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;