Mercurial > libavcodec.hg
comparison tscc.c @ 7885:f874e1d5cf07 libavcodec
Factorize out code used for MS RLE format decoding in different decoders.
author | kostya |
---|---|
date | Thu, 18 Sep 2008 05:20:54 +0000 |
parents | 4525dcd81357 |
children | bbac1857dd86 |
comparison
equal
deleted
inserted
replaced
7884:4077df298ba2 | 7885:f874e1d5cf07 |
---|---|
37 | 37 |
38 #include <stdio.h> | 38 #include <stdio.h> |
39 #include <stdlib.h> | 39 #include <stdlib.h> |
40 | 40 |
41 #include "avcodec.h" | 41 #include "avcodec.h" |
42 #include "msrledec.h" | |
42 | 43 |
43 #ifdef CONFIG_ZLIB | 44 #ifdef CONFIG_ZLIB |
44 #include <zlib.h> | 45 #include <zlib.h> |
45 #endif | 46 #endif |
46 | 47 |
62 int height; | 63 int height; |
63 #ifdef CONFIG_ZLIB | 64 #ifdef CONFIG_ZLIB |
64 z_stream zstream; | 65 z_stream zstream; |
65 #endif | 66 #endif |
66 } CamtasiaContext; | 67 } CamtasiaContext; |
67 | |
68 /* | |
69 * | |
70 * Decode RLE - almost identical to Windows BMP RLE8 | |
71 * and enhanced to bigger color depths | |
72 * | |
73 */ | |
74 | |
75 static int decode_rle(CamtasiaContext *c, unsigned int srcsize) | |
76 { | |
77 unsigned char *src = c->decomp_buf; | |
78 unsigned char *output, *output_end; | |
79 int p1, p2, line=c->height, pos=0, i; | |
80 uint16_t pix16; | |
81 uint32_t pix32; | |
82 | |
83 output = c->pic.data[0] + (c->height - 1) * c->pic.linesize[0]; | |
84 output_end = c->pic.data[0] + (c->height) * c->pic.linesize[0]; | |
85 while(src < c->decomp_buf + srcsize) { | |
86 p1 = *src++; | |
87 if(p1 == 0) { //Escape code | |
88 p2 = *src++; | |
89 if(p2 == 0) { //End-of-line | |
90 output = c->pic.data[0] + (--line) * c->pic.linesize[0]; | |
91 if (line < 0) | |
92 return -1; | |
93 pos = 0; | |
94 continue; | |
95 } else if(p2 == 1) { //End-of-picture | |
96 return 0; | |
97 } else if(p2 == 2) { //Skip | |
98 p1 = *src++; | |
99 p2 = *src++; | |
100 line -= p2; | |
101 if (line < 0) | |
102 return -1; | |
103 pos += p1; | |
104 output = c->pic.data[0] + line * c->pic.linesize[0] + pos * (c->bpp / 8); | |
105 continue; | |
106 } | |
107 // Copy data | |
108 if (output + p2 * (c->bpp / 8) > output_end) { | |
109 src += p2 * (c->bpp / 8); | |
110 continue; | |
111 } | |
112 if ((c->bpp == 8) || (c->bpp == 24)) { | |
113 for(i = 0; i < p2 * (c->bpp / 8); i++) { | |
114 *output++ = *src++; | |
115 } | |
116 // RLE8 copy is actually padded - and runs are not! | |
117 if(c->bpp == 8 && (p2 & 1)) { | |
118 src++; | |
119 } | |
120 } else if (c->bpp == 16) { | |
121 for(i = 0; i < p2; i++) { | |
122 pix16 = AV_RL16(src); | |
123 src += 2; | |
124 *(uint16_t*)output = pix16; | |
125 output += 2; | |
126 } | |
127 } else if (c->bpp == 32) { | |
128 for(i = 0; i < p2; i++) { | |
129 pix32 = AV_RL32(src); | |
130 src += 4; | |
131 *(uint32_t*)output = pix32; | |
132 output += 4; | |
133 } | |
134 } | |
135 pos += p2; | |
136 } else { //Run of pixels | |
137 int pix[4]; //original pixel | |
138 switch(c->bpp){ | |
139 case 8: pix[0] = *src++; | |
140 break; | |
141 case 16: pix16 = AV_RL16(src); | |
142 src += 2; | |
143 *(uint16_t*)pix = pix16; | |
144 break; | |
145 case 24: pix[0] = *src++; | |
146 pix[1] = *src++; | |
147 pix[2] = *src++; | |
148 break; | |
149 case 32: pix32 = AV_RL32(src); | |
150 src += 4; | |
151 *(uint32_t*)pix = pix32; | |
152 break; | |
153 } | |
154 if (output + p1 * (c->bpp / 8) > output_end) | |
155 continue; | |
156 for(i = 0; i < p1; i++) { | |
157 switch(c->bpp){ | |
158 case 8: *output++ = pix[0]; | |
159 break; | |
160 case 16: *(uint16_t*)output = pix16; | |
161 output += 2; | |
162 break; | |
163 case 24: *output++ = pix[0]; | |
164 *output++ = pix[1]; | |
165 *output++ = pix[2]; | |
166 break; | |
167 case 32: *(uint32_t*)output = pix32; | |
168 output += 4; | |
169 break; | |
170 } | |
171 } | |
172 pos += p1; | |
173 } | |
174 } | |
175 | |
176 av_log(c->avctx, AV_LOG_ERROR, "Camtasia warning: no End-of-picture code\n"); | |
177 return 1; | |
178 } | |
179 | 68 |
180 /* | 69 /* |
181 * | 70 * |
182 * Decode a frame | 71 * Decode a frame |
183 * | 72 * |
221 return -1; | 110 return -1; |
222 } | 111 } |
223 | 112 |
224 | 113 |
225 if(zret != Z_DATA_ERROR) | 114 if(zret != Z_DATA_ERROR) |
226 decode_rle(c, c->zstream.avail_out); | 115 ff_msrle_decode(avctx, &c->pic, c->bpp, c->decomp_buf, c->zstream.avail_out); |
227 | 116 |
228 /* make the palette available on the way out */ | 117 /* make the palette available on the way out */ |
229 if (c->avctx->pix_fmt == PIX_FMT_PAL8) { | 118 if (c->avctx->pix_fmt == PIX_FMT_PAL8) { |
230 memcpy(c->pic.data[1], c->avctx->palctrl->palette, AVPALETTE_SIZE); | 119 memcpy(c->pic.data[1], c->avctx->palctrl->palette, AVPALETTE_SIZE); |
231 if (c->avctx->palctrl->palette_changed) { | 120 if (c->avctx->palctrl->palette_changed) { |