Mercurial > libavcodec.hg
comparison xan.c @ 2831:ad9d121cc6e9 libavcodec
tinfoil patch: no array is written to in bulk before counts are
validated; do not free frames that are not allocated; removed all of the
output modes that no one uses and only PAL8 remains
author | melanson |
---|---|
date | Sat, 13 Aug 2005 20:48:47 +0000 |
parents | 18b8b2dcc037 |
children | ef2149182f1c |
comparison
equal
deleted
inserted
replaced
2830:4e31ad3623cf | 2831:ad9d121cc6e9 |
---|---|
18 * | 18 * |
19 */ | 19 */ |
20 | 20 |
21 /** | 21 /** |
22 * @file xan.c | 22 * @file xan.c |
23 * Xan video decoder for Wing Commander III & IV computer games | 23 * Xan video decoder for Wing Commander III computer game |
24 * by Mario Brito (mbrito@student.dei.uc.pt) | 24 * by Mario Brito (mbrito@student.dei.uc.pt) |
25 * and Mike Melanson (melanson@pcisys.net) | 25 * and Mike Melanson (melanson@pcisys.net) |
26 * | 26 * |
27 * The xan_wc3 decoder outputs the following colorspaces natively: | 27 * The xan_wc3 decoder outputs PAL8 data. |
28 * PAL8 (default), RGB555, RGB565, RGB24, BGR24, RGBA32, YUV444P | |
29 */ | 28 */ |
30 | 29 |
31 #include <stdio.h> | 30 #include <stdio.h> |
32 #include <stdlib.h> | 31 #include <stdlib.h> |
33 #include <string.h> | 32 #include <string.h> |
34 #include <unistd.h> | 33 #include <unistd.h> |
35 | 34 |
36 #include "common.h" | 35 #include "common.h" |
37 #include "avcodec.h" | 36 #include "avcodec.h" |
38 #include "dsputil.h" | |
39 | |
40 #define PALETTE_COUNT 256 | |
41 #define PALETTE_CONTROL_SIZE ((256 * 3) + 1) | |
42 | 37 |
43 typedef struct XanContext { | 38 typedef struct XanContext { |
44 | 39 |
45 AVCodecContext *avctx; | 40 AVCodecContext *avctx; |
46 DSPContext dsp; | |
47 AVFrame last_frame; | 41 AVFrame last_frame; |
48 AVFrame current_frame; | 42 AVFrame current_frame; |
49 | 43 |
50 unsigned char *buf; | 44 unsigned char *buf; |
51 int size; | 45 int size; |
52 | 46 |
53 unsigned char palette[PALETTE_COUNT * 4]; | |
54 | |
55 /* scratch space */ | 47 /* scratch space */ |
56 unsigned char *buffer1; | 48 unsigned char *buffer1; |
49 int buffer1_size; | |
57 unsigned char *buffer2; | 50 unsigned char *buffer2; |
51 int buffer2_size; | |
52 | |
53 int frame_size; | |
58 | 54 |
59 } XanContext; | 55 } XanContext; |
60 | 56 |
61 /* RGB -> YUV conversion stuff */ | |
62 #define SCALEFACTOR 65536 | |
63 #define CENTERSAMPLE 128 | |
64 | |
65 #define COMPUTE_Y(r, g, b) \ | |
66 (unsigned char) \ | |
67 ((y_r_table[r] + y_g_table[g] + y_b_table[b]) / SCALEFACTOR) | |
68 #define COMPUTE_U(r, g, b) \ | |
69 (unsigned char) \ | |
70 ((u_r_table[r] + u_g_table[g] + u_b_table[b]) / SCALEFACTOR + CENTERSAMPLE) | |
71 #define COMPUTE_V(r, g, b) \ | |
72 (unsigned char) \ | |
73 ((v_r_table[r] + v_g_table[g] + v_b_table[b]) / SCALEFACTOR + CENTERSAMPLE) | |
74 | |
75 #define Y_R (SCALEFACTOR * 0.29900) | |
76 #define Y_G (SCALEFACTOR * 0.58700) | |
77 #define Y_B (SCALEFACTOR * 0.11400) | |
78 | |
79 #define U_R (SCALEFACTOR * -0.16874) | |
80 #define U_G (SCALEFACTOR * -0.33126) | |
81 #define U_B (SCALEFACTOR * 0.50000) | |
82 | |
83 #define V_R (SCALEFACTOR * 0.50000) | |
84 #define V_G (SCALEFACTOR * -0.41869) | |
85 #define V_B (SCALEFACTOR * -0.08131) | |
86 | |
87 /* | |
88 * Precalculate all of the YUV tables since it requires fewer than | |
89 * 10 kilobytes to store them. | |
90 */ | |
91 static int y_r_table[256]; | |
92 static int y_g_table[256]; | |
93 static int y_b_table[256]; | |
94 | |
95 static int u_r_table[256]; | |
96 static int u_g_table[256]; | |
97 static int u_b_table[256]; | |
98 | |
99 static int v_r_table[256]; | |
100 static int v_g_table[256]; | |
101 static int v_b_table[256]; | |
102 | |
103 static int xan_decode_init(AVCodecContext *avctx) | 57 static int xan_decode_init(AVCodecContext *avctx) |
104 { | 58 { |
105 XanContext *s = avctx->priv_data; | 59 XanContext *s = avctx->priv_data; |
106 int i; | |
107 | 60 |
108 s->avctx = avctx; | 61 s->avctx = avctx; |
62 s->frame_size = 0; | |
109 | 63 |
110 if ((avctx->codec->id == CODEC_ID_XAN_WC3) && | 64 if ((avctx->codec->id == CODEC_ID_XAN_WC3) && |
111 (s->avctx->palctrl == NULL)) { | 65 (s->avctx->palctrl == NULL)) { |
112 av_log(avctx, AV_LOG_ERROR, " WC3 Xan video: palette expected.\n"); | 66 av_log(avctx, AV_LOG_ERROR, " WC3 Xan video: palette expected.\n"); |
113 return -1; | 67 return -1; |
114 } | 68 } |
115 | 69 |
116 avctx->pix_fmt = PIX_FMT_PAL8; | 70 avctx->pix_fmt = PIX_FMT_PAL8; |
117 avctx->has_b_frames = 0; | 71 avctx->has_b_frames = 0; |
118 dsputil_init(&s->dsp, avctx); | |
119 | |
120 /* initialize the RGB -> YUV tables */ | |
121 for (i = 0; i < 256; i++) { | |
122 y_r_table[i] = Y_R * i; | |
123 y_g_table[i] = Y_G * i; | |
124 y_b_table[i] = Y_B * i; | |
125 | |
126 u_r_table[i] = U_R * i; | |
127 u_g_table[i] = U_G * i; | |
128 u_b_table[i] = U_B * i; | |
129 | |
130 v_r_table[i] = V_R * i; | |
131 v_g_table[i] = V_G * i; | |
132 v_b_table[i] = V_B * i; | |
133 } | |
134 | 72 |
135 if(avcodec_check_dimensions(avctx, avctx->width, avctx->height)) | 73 if(avcodec_check_dimensions(avctx, avctx->width, avctx->height)) |
136 return -1; | 74 return -1; |
137 | 75 |
138 s->buffer1 = av_malloc(avctx->width * avctx->height); | 76 s->buffer1_size = avctx->width * avctx->height; |
139 s->buffer2 = av_malloc(avctx->width * avctx->height); | 77 s->buffer1 = av_malloc(s->buffer1_size); |
78 s->buffer2_size = avctx->width * avctx->height; | |
79 s->buffer2 = av_malloc(s->buffer2_size); | |
140 if (!s->buffer1 || !s->buffer2) | 80 if (!s->buffer1 || !s->buffer2) |
141 return -1; | 81 return -1; |
142 | 82 |
143 return 0; | 83 return 0; |
144 } | 84 } |
154 | 94 |
155 for (i = 0; i < count; i++) | 95 for (i = 0; i < count; i++) |
156 dest[i] = src[i]; | 96 dest[i] = src[i]; |
157 } | 97 } |
158 | 98 |
159 static int xan_huffman_decode(unsigned char *dest, unsigned char *src) | 99 static int xan_huffman_decode(unsigned char *dest, unsigned char *src, |
100 int dest_len) | |
160 { | 101 { |
161 unsigned char byte = *src++; | 102 unsigned char byte = *src++; |
162 unsigned char ival = byte + 0x16; | 103 unsigned char ival = byte + 0x16; |
163 unsigned char * ptr = src + byte*2; | 104 unsigned char * ptr = src + byte*2; |
164 unsigned char val = ival; | 105 unsigned char val = ival; |
165 int counter = 0; | 106 int counter = 0; |
107 unsigned char *dest_end = dest + dest_len; | |
166 | 108 |
167 unsigned char bits = *ptr++; | 109 unsigned char bits = *ptr++; |
168 | 110 |
169 while ( val != 0x16 ) { | 111 while ( val != 0x16 ) { |
170 if ( (1 << counter) & bits ) | 112 if ( (1 << counter) & bits ) |
171 val = src[byte + val - 0x17]; | 113 val = src[byte + val - 0x17]; |
172 else | 114 else |
173 val = src[val - 0x17]; | 115 val = src[val - 0x17]; |
174 | 116 |
175 if ( val < 0x16 ) { | 117 if ( val < 0x16 ) { |
118 if (dest + 1 > dest_end) | |
119 return 0; | |
176 *dest++ = val; | 120 *dest++ = val; |
177 val = ival; | 121 val = ival; |
178 } | 122 } |
179 | 123 |
180 if (counter++ == 7) { | 124 if (counter++ == 7) { |
184 } | 128 } |
185 | 129 |
186 return 0; | 130 return 0; |
187 } | 131 } |
188 | 132 |
189 static void xan_unpack(unsigned char *dest, unsigned char *src) | 133 static void xan_unpack(unsigned char *dest, unsigned char *src, int dest_len) |
190 { | 134 { |
191 unsigned char opcode; | 135 unsigned char opcode; |
192 int size; | 136 int size; |
193 int offset; | 137 int offset; |
194 int byte1, byte2, byte3; | 138 int byte1, byte2, byte3; |
139 unsigned char *dest_end = dest + dest_len; | |
195 | 140 |
196 for (;;) { | 141 for (;;) { |
197 opcode = *src++; | 142 opcode = *src++; |
198 | 143 |
199 if ( (opcode & 0x80) == 0 ) { | 144 if ( (opcode & 0x80) == 0 ) { |
200 | 145 |
201 offset = *src++; | 146 offset = *src++; |
202 | 147 |
203 size = opcode & 3; | 148 size = opcode & 3; |
149 if (dest + size > dest_end) | |
150 return; | |
204 bytecopy(dest, src, size); dest += size; src += size; | 151 bytecopy(dest, src, size); dest += size; src += size; |
205 | 152 |
206 size = ((opcode & 0x1c) >> 2) + 3; | 153 size = ((opcode & 0x1c) >> 2) + 3; |
154 if (dest + size > dest_end) | |
155 return; | |
207 bytecopy (dest, dest - (((opcode & 0x60) << 3) + offset + 1), size); | 156 bytecopy (dest, dest - (((opcode & 0x60) << 3) + offset + 1), size); |
208 dest += size; | 157 dest += size; |
209 | 158 |
210 } else if ( (opcode & 0x40) == 0 ) { | 159 } else if ( (opcode & 0x40) == 0 ) { |
211 | 160 |
212 byte1 = *src++; | 161 byte1 = *src++; |
213 byte2 = *src++; | 162 byte2 = *src++; |
214 | 163 |
215 size = byte1 >> 6; | 164 size = byte1 >> 6; |
165 if (dest + size > dest_end) | |
166 return; | |
216 bytecopy (dest, src, size); dest += size; src += size; | 167 bytecopy (dest, src, size); dest += size; src += size; |
217 | 168 |
218 size = (opcode & 0x3f) + 4; | 169 size = (opcode & 0x3f) + 4; |
170 if (dest + size > dest_end) | |
171 return; | |
219 bytecopy (dest, dest - (((byte1 & 0x3f) << 8) + byte2 + 1), size); | 172 bytecopy (dest, dest - (((byte1 & 0x3f) << 8) + byte2 + 1), size); |
220 dest += size; | 173 dest += size; |
221 | 174 |
222 } else if ( (opcode & 0x20) == 0 ) { | 175 } else if ( (opcode & 0x20) == 0 ) { |
223 | 176 |
224 byte1 = *src++; | 177 byte1 = *src++; |
225 byte2 = *src++; | 178 byte2 = *src++; |
226 byte3 = *src++; | 179 byte3 = *src++; |
227 | 180 |
228 size = opcode & 3; | 181 size = opcode & 3; |
182 if (dest + size > dest_end) | |
183 return; | |
229 bytecopy (dest, src, size); dest += size; src += size; | 184 bytecopy (dest, src, size); dest += size; src += size; |
230 | 185 |
231 size = byte3 + 5 + ((opcode & 0xc) << 6); | 186 size = byte3 + 5 + ((opcode & 0xc) << 6); |
187 if (dest + size > dest_end) | |
188 return; | |
232 bytecopy (dest, | 189 bytecopy (dest, |
233 dest - ((((opcode & 0x10) >> 4) << 0x10) + 1 + (byte1 << 8) + byte2), | 190 dest - ((((opcode & 0x10) >> 4) << 0x10) + 1 + (byte1 << 8) + byte2), |
234 size); | 191 size); |
235 dest += size; | 192 dest += size; |
236 } else { | 193 } else { |
237 size = ((opcode & 0x1f) << 2) + 4; | 194 size = ((opcode & 0x1f) << 2) + 4; |
238 | 195 |
239 if (size > 0x70) | 196 if (size > 0x70) |
240 break; | 197 break; |
241 | 198 |
199 if (dest + size > dest_end) | |
200 return; | |
242 bytecopy (dest, src, size); dest += size; src += size; | 201 bytecopy (dest, src, size); dest += size; src += size; |
243 } | 202 } |
244 } | 203 } |
245 | 204 |
246 size = opcode & 3; | 205 size = opcode & 3; |
247 bytecopy(dest, src, size); dest += size; src += size; | 206 bytecopy(dest, src, size); dest += size; src += size; |
248 } | 207 } |
249 | |
250 static void inline xan_wc3_build_palette(XanContext *s, | |
251 unsigned int *palette_data) | |
252 { | |
253 int i; | |
254 unsigned char r, g, b; | |
255 unsigned short *palette16; | |
256 unsigned int *palette32; | |
257 unsigned int pal_elem; | |
258 | |
259 /* transform the palette passed through the palette control structure | |
260 * into the necessary internal format depending on colorspace */ | |
261 | |
262 switch (s->avctx->pix_fmt) { | |
263 | |
264 case PIX_FMT_RGB555: | |
265 palette16 = (unsigned short *)s->palette; | |
266 for (i = 0; i < PALETTE_COUNT; i++) { | |
267 pal_elem = palette_data[i]; | |
268 r = (pal_elem >> 16) & 0xff; | |
269 g = (pal_elem >> 8) & 0xff; | |
270 b = pal_elem & 0xff; | |
271 palette16[i] = | |
272 ((r >> 3) << 10) | | |
273 ((g >> 3) << 5) | | |
274 ((b >> 3) << 0); | |
275 } | |
276 break; | |
277 | |
278 case PIX_FMT_RGB565: | |
279 palette16 = (unsigned short *)s->palette; | |
280 for (i = 0; i < PALETTE_COUNT; i++) { | |
281 pal_elem = palette_data[i]; | |
282 r = (pal_elem >> 16) & 0xff; | |
283 g = (pal_elem >> 8) & 0xff; | |
284 b = pal_elem & 0xff; | |
285 palette16[i] = | |
286 ((r >> 3) << 11) | | |
287 ((g >> 2) << 5) | | |
288 ((b >> 3) << 0); | |
289 } | |
290 break; | |
291 | |
292 case PIX_FMT_RGB24: | |
293 for (i = 0; i < PALETTE_COUNT; i++) { | |
294 pal_elem = palette_data[i]; | |
295 r = (pal_elem >> 16) & 0xff; | |
296 g = (pal_elem >> 8) & 0xff; | |
297 b = pal_elem & 0xff; | |
298 s->palette[i * 4 + 0] = r; | |
299 s->palette[i * 4 + 1] = g; | |
300 s->palette[i * 4 + 2] = b; | |
301 } | |
302 break; | |
303 | |
304 case PIX_FMT_BGR24: | |
305 for (i = 0; i < PALETTE_COUNT; i++) { | |
306 pal_elem = palette_data[i]; | |
307 r = (pal_elem >> 16) & 0xff; | |
308 g = (pal_elem >> 8) & 0xff; | |
309 b = pal_elem & 0xff; | |
310 s->palette[i * 4 + 0] = b; | |
311 s->palette[i * 4 + 1] = g; | |
312 s->palette[i * 4 + 2] = r; | |
313 } | |
314 break; | |
315 | |
316 case PIX_FMT_PAL8: | |
317 case PIX_FMT_RGBA32: | |
318 palette32 = (unsigned int *)s->palette; | |
319 memcpy (palette32, palette_data, PALETTE_COUNT * sizeof(unsigned int)); | |
320 break; | |
321 | |
322 case PIX_FMT_YUV444P: | |
323 for (i = 0; i < PALETTE_COUNT; i++) { | |
324 pal_elem = palette_data[i]; | |
325 r = (pal_elem >> 16) & 0xff; | |
326 g = (pal_elem >> 8) & 0xff; | |
327 b = pal_elem & 0xff; | |
328 s->palette[i * 4 + 0] = COMPUTE_Y(r, g, b); | |
329 s->palette[i * 4 + 1] = COMPUTE_U(r, g, b); | |
330 s->palette[i * 4 + 2] = COMPUTE_V(r, g, b); | |
331 } | |
332 break; | |
333 | |
334 default: | |
335 av_log(s->avctx, AV_LOG_ERROR, " Xan WC3: Unhandled colorspace\n"); | |
336 break; | |
337 } | |
338 } | |
339 | |
340 /* advance current_x variable; reset accounting variables if current_x | |
341 * moves beyond width */ | |
342 #define ADVANCE_CURRENT_X() \ | |
343 current_x++; \ | |
344 if (current_x >= width) { \ | |
345 index += line_inc; \ | |
346 current_x = 0; \ | |
347 } | |
348 | 208 |
349 static void inline xan_wc3_output_pixel_run(XanContext *s, | 209 static void inline xan_wc3_output_pixel_run(XanContext *s, |
350 unsigned char *pixel_buffer, int x, int y, int pixel_count) | 210 unsigned char *pixel_buffer, int x, int y, int pixel_count) |
351 { | 211 { |
352 int stride; | 212 int stride; |
353 int line_inc; | 213 int line_inc; |
354 int index; | 214 int index; |
355 int current_x; | 215 int current_x; |
356 int width = s->avctx->width; | 216 int width = s->avctx->width; |
357 unsigned char pix; | |
358 unsigned char *palette_plane; | 217 unsigned char *palette_plane; |
359 unsigned char *y_plane; | 218 |
360 unsigned char *u_plane; | 219 palette_plane = s->current_frame.data[0]; |
361 unsigned char *v_plane; | 220 stride = s->current_frame.linesize[0]; |
362 unsigned char *rgb_plane; | 221 line_inc = stride - width; |
363 unsigned short *rgb16_plane; | 222 index = y * stride + x; |
364 unsigned short *palette16; | 223 current_x = x; |
365 unsigned int *rgb32_plane; | 224 while((pixel_count--) && (index < s->frame_size)) { |
366 unsigned int *palette32; | 225 |
367 | 226 /* don't do a memcpy() here; keyframes generally copy an entire |
368 switch (s->avctx->pix_fmt) { | 227 * frame of data and the stride needs to be accounted for */ |
369 | 228 palette_plane[index++] = *pixel_buffer++; |
370 case PIX_FMT_PAL8: | 229 |
371 palette_plane = s->current_frame.data[0]; | 230 current_x++; |
372 stride = s->current_frame.linesize[0]; | 231 if (current_x >= width) { |
373 line_inc = stride - width; | 232 index += line_inc; |
374 index = y * stride + x; | 233 current_x = 0; |
375 current_x = x; | 234 } |
376 while(pixel_count--) { | 235 } |
377 | 236 } |
378 /* don't do a memcpy() here; keyframes generally copy an entire | |
379 * frame of data and the stride needs to be accounted for */ | |
380 palette_plane[index++] = *pixel_buffer++; | |
381 | |
382 ADVANCE_CURRENT_X(); | |
383 } | |
384 break; | |
385 | |
386 case PIX_FMT_RGB555: | |
387 case PIX_FMT_RGB565: | |
388 rgb16_plane = (unsigned short *)s->current_frame.data[0]; | |
389 palette16 = (unsigned short *)s->palette; | |
390 stride = s->current_frame.linesize[0] / 2; | |
391 line_inc = stride - width; | |
392 index = y * stride + x; | |
393 current_x = x; | |
394 while(pixel_count--) { | |
395 | |
396 rgb16_plane[index++] = palette16[*pixel_buffer++]; | |
397 | |
398 ADVANCE_CURRENT_X(); | |
399 } | |
400 break; | |
401 | |
402 case PIX_FMT_RGB24: | |
403 case PIX_FMT_BGR24: | |
404 rgb_plane = s->current_frame.data[0]; | |
405 stride = s->current_frame.linesize[0]; | |
406 line_inc = stride - width * 3; | |
407 index = y * stride + x * 3; | |
408 current_x = x; | |
409 while(pixel_count--) { | |
410 pix = *pixel_buffer++; | |
411 | |
412 rgb_plane[index++] = s->palette[pix * 4 + 0]; | |
413 rgb_plane[index++] = s->palette[pix * 4 + 1]; | |
414 rgb_plane[index++] = s->palette[pix * 4 + 2]; | |
415 | |
416 ADVANCE_CURRENT_X(); | |
417 } | |
418 break; | |
419 | |
420 case PIX_FMT_RGBA32: | |
421 rgb32_plane = (unsigned int *)s->current_frame.data[0]; | |
422 palette32 = (unsigned int *)s->palette; | |
423 stride = s->current_frame.linesize[0] / 4; | |
424 line_inc = stride - width; | |
425 index = y * stride + x; | |
426 current_x = x; | |
427 while(pixel_count--) { | |
428 | |
429 rgb32_plane[index++] = palette32[*pixel_buffer++]; | |
430 | |
431 ADVANCE_CURRENT_X(); | |
432 } | |
433 break; | |
434 | |
435 case PIX_FMT_YUV444P: | |
436 y_plane = s->current_frame.data[0]; | |
437 u_plane = s->current_frame.data[1]; | |
438 v_plane = s->current_frame.data[2]; | |
439 stride = s->current_frame.linesize[0]; | |
440 line_inc = stride - width; | |
441 index = y * stride + x; | |
442 current_x = x; | |
443 while(pixel_count--) { | |
444 pix = *pixel_buffer++; | |
445 | |
446 y_plane[index] = s->palette[pix * 4 + 0]; | |
447 u_plane[index] = s->palette[pix * 4 + 1]; | |
448 v_plane[index] = s->palette[pix * 4 + 2]; | |
449 | |
450 index++; | |
451 ADVANCE_CURRENT_X(); | |
452 } | |
453 break; | |
454 | |
455 default: | |
456 av_log(s->avctx, AV_LOG_ERROR, " Xan WC3: Unhandled colorspace\n"); | |
457 break; | |
458 } | |
459 } | |
460 | |
461 #define ADVANCE_CURFRAME_X() \ | |
462 curframe_x++; \ | |
463 if (curframe_x >= width) { \ | |
464 curframe_index += line_inc; \ | |
465 curframe_x = 0; \ | |
466 } | |
467 | |
468 #define ADVANCE_PREVFRAME_X() \ | |
469 prevframe_x++; \ | |
470 if (prevframe_x >= width) { \ | |
471 prevframe_index += line_inc; \ | |
472 prevframe_x = 0; \ | |
473 } | |
474 | 237 |
475 static void inline xan_wc3_copy_pixel_run(XanContext *s, | 238 static void inline xan_wc3_copy_pixel_run(XanContext *s, |
476 int x, int y, int pixel_count, int motion_x, int motion_y) | 239 int x, int y, int pixel_count, int motion_x, int motion_y) |
477 { | 240 { |
478 int stride; | 241 int stride; |
479 int line_inc; | 242 int line_inc; |
480 int curframe_index, prevframe_index; | 243 int curframe_index, prevframe_index; |
481 int curframe_x, prevframe_x; | 244 int curframe_x, prevframe_x; |
482 int width = s->avctx->width; | 245 int width = s->avctx->width; |
483 unsigned char *palette_plane, *prev_palette_plane; | 246 unsigned char *palette_plane, *prev_palette_plane; |
484 unsigned char *y_plane, *u_plane, *v_plane; | 247 |
485 unsigned char *prev_y_plane, *prev_u_plane, *prev_v_plane; | 248 palette_plane = s->current_frame.data[0]; |
486 unsigned char *rgb_plane, *prev_rgb_plane; | 249 prev_palette_plane = s->last_frame.data[0]; |
487 unsigned short *rgb16_plane, *prev_rgb16_plane; | 250 stride = s->current_frame.linesize[0]; |
488 unsigned int *rgb32_plane, *prev_rgb32_plane; | 251 line_inc = stride - width; |
489 | 252 curframe_index = y * stride + x; |
490 switch (s->avctx->pix_fmt) { | 253 curframe_x = x; |
491 | 254 prevframe_index = (y + motion_y) * stride + x + motion_x; |
492 case PIX_FMT_PAL8: | 255 prevframe_x = x + motion_x; |
493 palette_plane = s->current_frame.data[0]; | 256 while((pixel_count--) && (curframe_index < s->frame_size)) { |
494 prev_palette_plane = s->last_frame.data[0]; | 257 |
495 stride = s->current_frame.linesize[0]; | 258 palette_plane[curframe_index++] = |
496 line_inc = stride - width; | 259 prev_palette_plane[prevframe_index++]; |
497 curframe_index = y * stride + x; | 260 |
498 curframe_x = x; | 261 curframe_x++; |
499 prevframe_index = (y + motion_y) * stride + x + motion_x; | 262 if (curframe_x >= width) { |
500 prevframe_x = x + motion_x; | 263 curframe_index += line_inc; |
501 while(pixel_count--) { | 264 curframe_x = 0; |
502 | 265 } |
503 palette_plane[curframe_index++] = | 266 |
504 prev_palette_plane[prevframe_index++]; | 267 prevframe_x++; |
505 | 268 if (prevframe_x >= width) { |
506 ADVANCE_CURFRAME_X(); | 269 prevframe_index += line_inc; |
507 ADVANCE_PREVFRAME_X(); | 270 prevframe_x = 0; |
508 } | 271 } |
509 break; | |
510 | |
511 case PIX_FMT_RGB555: | |
512 case PIX_FMT_RGB565: | |
513 rgb16_plane = (unsigned short *)s->current_frame.data[0]; | |
514 prev_rgb16_plane = (unsigned short *)s->last_frame.data[0]; | |
515 stride = s->current_frame.linesize[0] / 2; | |
516 line_inc = stride - width; | |
517 curframe_index = y * stride + x; | |
518 curframe_x = x; | |
519 prevframe_index = (y + motion_y) * stride + x + motion_x; | |
520 prevframe_x = x + motion_x; | |
521 while(pixel_count--) { | |
522 | |
523 rgb16_plane[curframe_index++] = | |
524 prev_rgb16_plane[prevframe_index++]; | |
525 | |
526 ADVANCE_CURFRAME_X(); | |
527 ADVANCE_PREVFRAME_X(); | |
528 } | |
529 break; | |
530 | |
531 case PIX_FMT_RGB24: | |
532 case PIX_FMT_BGR24: | |
533 rgb_plane = s->current_frame.data[0]; | |
534 prev_rgb_plane = s->last_frame.data[0]; | |
535 stride = s->current_frame.linesize[0]; | |
536 line_inc = stride - width * 3; | |
537 curframe_index = y * stride + x * 3; | |
538 curframe_x = x; | |
539 prevframe_index = (y + motion_y) * stride + | |
540 (3 * (x + motion_x)); | |
541 prevframe_x = x + motion_x; | |
542 while(pixel_count--) { | |
543 | |
544 rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++]; | |
545 rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++]; | |
546 rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++]; | |
547 | |
548 ADVANCE_CURFRAME_X(); | |
549 ADVANCE_PREVFRAME_X(); | |
550 } | |
551 break; | |
552 | |
553 case PIX_FMT_RGBA32: | |
554 rgb32_plane = (unsigned int *)s->current_frame.data[0]; | |
555 prev_rgb32_plane = (unsigned int *)s->last_frame.data[0]; | |
556 stride = s->current_frame.linesize[0] / 4; | |
557 line_inc = stride - width; | |
558 curframe_index = y * stride + x; | |
559 curframe_x = x; | |
560 prevframe_index = (y + motion_y) * stride + x + motion_x; | |
561 prevframe_x = x + motion_x; | |
562 while(pixel_count--) { | |
563 | |
564 rgb32_plane[curframe_index++] = | |
565 prev_rgb32_plane[prevframe_index++]; | |
566 | |
567 ADVANCE_CURFRAME_X(); | |
568 ADVANCE_PREVFRAME_X(); | |
569 } | |
570 break; | |
571 | |
572 case PIX_FMT_YUV444P: | |
573 y_plane = s->current_frame.data[0]; | |
574 u_plane = s->current_frame.data[1]; | |
575 v_plane = s->current_frame.data[2]; | |
576 prev_y_plane = s->last_frame.data[0]; | |
577 prev_u_plane = s->last_frame.data[1]; | |
578 prev_v_plane = s->last_frame.data[2]; | |
579 stride = s->current_frame.linesize[0]; | |
580 line_inc = stride - width; | |
581 curframe_index = y * stride + x; | |
582 curframe_x = x; | |
583 prevframe_index = (y + motion_y) * stride + x + motion_x; | |
584 prevframe_x = x + motion_x; | |
585 while(pixel_count--) { | |
586 | |
587 y_plane[curframe_index] = prev_y_plane[prevframe_index]; | |
588 u_plane[curframe_index] = prev_u_plane[prevframe_index]; | |
589 v_plane[curframe_index] = prev_v_plane[prevframe_index]; | |
590 | |
591 curframe_index++; | |
592 ADVANCE_CURFRAME_X(); | |
593 prevframe_index++; | |
594 ADVANCE_PREVFRAME_X(); | |
595 } | |
596 break; | |
597 | |
598 default: | |
599 av_log(s->avctx, AV_LOG_ERROR, " Xan WC3: Unhandled colorspace\n"); | |
600 break; | |
601 } | 272 } |
602 } | 273 } |
603 | 274 |
604 static void xan_wc3_decode_frame(XanContext *s) { | 275 static void xan_wc3_decode_frame(XanContext *s) { |
605 | 276 |
611 int size = 0; | 282 int size = 0; |
612 int motion_x, motion_y; | 283 int motion_x, motion_y; |
613 int x, y; | 284 int x, y; |
614 | 285 |
615 unsigned char *opcode_buffer = s->buffer1; | 286 unsigned char *opcode_buffer = s->buffer1; |
287 int opcode_buffer_size = s->buffer1_size; | |
616 unsigned char *imagedata_buffer = s->buffer2; | 288 unsigned char *imagedata_buffer = s->buffer2; |
289 int imagedata_buffer_size = s->buffer2_size; | |
617 | 290 |
618 /* pointers to segments inside the compressed chunk */ | 291 /* pointers to segments inside the compressed chunk */ |
619 unsigned char *huffman_segment; | 292 unsigned char *huffman_segment; |
620 unsigned char *size_segment; | 293 unsigned char *size_segment; |
621 unsigned char *vector_segment; | 294 unsigned char *vector_segment; |
624 huffman_segment = s->buf + LE_16(&s->buf[0]); | 297 huffman_segment = s->buf + LE_16(&s->buf[0]); |
625 size_segment = s->buf + LE_16(&s->buf[2]); | 298 size_segment = s->buf + LE_16(&s->buf[2]); |
626 vector_segment = s->buf + LE_16(&s->buf[4]); | 299 vector_segment = s->buf + LE_16(&s->buf[4]); |
627 imagedata_segment = s->buf + LE_16(&s->buf[6]); | 300 imagedata_segment = s->buf + LE_16(&s->buf[6]); |
628 | 301 |
629 xan_huffman_decode(opcode_buffer, huffman_segment); | 302 xan_huffman_decode(opcode_buffer, huffman_segment, opcode_buffer_size); |
630 | 303 |
631 if (imagedata_segment[0] == 2) | 304 if (imagedata_segment[0] == 2) |
632 xan_unpack(imagedata_buffer, &imagedata_segment[1]); | 305 xan_unpack(imagedata_buffer, &imagedata_segment[1], |
306 imagedata_buffer_size); | |
633 else | 307 else |
634 imagedata_buffer = &imagedata_segment[1]; | 308 imagedata_buffer = &imagedata_segment[1]; |
635 | 309 |
636 /* use the decoded data segments to build the frame */ | 310 /* use the decoded data segments to build the frame */ |
637 x = y = 0; | 311 x = y = 0; |
725 x += size; | 399 x += size; |
726 size = 0; | 400 size = 0; |
727 } | 401 } |
728 } | 402 } |
729 } | 403 } |
730 | |
731 /* for PAL8, make the palette available on the way out */ | |
732 if (s->avctx->pix_fmt == PIX_FMT_PAL8) { | |
733 memcpy(s->current_frame.data[1], s->palette, PALETTE_COUNT * 4); | |
734 s->current_frame.palette_has_changed = 1; | |
735 s->avctx->palctrl->palette_changed = 0; | |
736 } | |
737 } | 404 } |
738 | 405 |
739 static void xan_wc4_decode_frame(XanContext *s) { | 406 static void xan_wc4_decode_frame(XanContext *s) { |
740 } | 407 } |
741 | 408 |
743 void *data, int *data_size, | 410 void *data, int *data_size, |
744 uint8_t *buf, int buf_size) | 411 uint8_t *buf, int buf_size) |
745 { | 412 { |
746 XanContext *s = avctx->priv_data; | 413 XanContext *s = avctx->priv_data; |
747 AVPaletteControl *palette_control = avctx->palctrl; | 414 AVPaletteControl *palette_control = avctx->palctrl; |
748 int keyframe = 0; | |
749 | |
750 if (palette_control->palette_changed) { | |
751 /* load the new palette and reset the palette control */ | |
752 xan_wc3_build_palette(s, palette_control->palette); | |
753 /* If pal8 we clear flag when we copy palette */ | |
754 if (s->avctx->pix_fmt != PIX_FMT_PAL8) | |
755 palette_control->palette_changed = 0; | |
756 keyframe = 1; | |
757 } | |
758 | 415 |
759 if (avctx->get_buffer(avctx, &s->current_frame)) { | 416 if (avctx->get_buffer(avctx, &s->current_frame)) { |
760 av_log(s->avctx, AV_LOG_ERROR, " Xan Video: get_buffer() failed\n"); | 417 av_log(s->avctx, AV_LOG_ERROR, " Xan Video: get_buffer() failed\n"); |
761 return -1; | 418 return -1; |
762 } | 419 } |
763 s->current_frame.reference = 3; | 420 s->current_frame.reference = 3; |
421 | |
422 if (!s->frame_size) | |
423 s->frame_size = s->current_frame.linesize[0] * s->avctx->height; | |
424 | |
425 palette_control->palette_changed = 0; | |
426 memcpy(s->current_frame.data[1], palette_control->palette, | |
427 AVPALETTE_SIZE); | |
428 s->current_frame.palette_has_changed = 1; | |
764 | 429 |
765 s->buf = buf; | 430 s->buf = buf; |
766 s->size = buf_size; | 431 s->size = buf_size; |
767 | 432 |
768 if (avctx->codec->id == CODEC_ID_XAN_WC3) | 433 if (avctx->codec->id == CODEC_ID_XAN_WC3) |
787 static int xan_decode_end(AVCodecContext *avctx) | 452 static int xan_decode_end(AVCodecContext *avctx) |
788 { | 453 { |
789 XanContext *s = avctx->priv_data; | 454 XanContext *s = avctx->priv_data; |
790 | 455 |
791 /* release the last frame */ | 456 /* release the last frame */ |
792 avctx->release_buffer(avctx, &s->last_frame); | 457 if (s->last_frame.data[0]) |
458 avctx->release_buffer(avctx, &s->last_frame); | |
793 | 459 |
794 av_free(s->buffer1); | 460 av_free(s->buffer1); |
795 av_free(s->buffer2); | 461 av_free(s->buffer2); |
796 | 462 |
797 return 0; | 463 return 0; |