comparison xan.c @ 1459:201d4e25c207 libavcodec

xan_wc3 decoder now works correctly; added a bunch of output colorspaces
author tmmm
date Thu, 11 Sep 2003 05:46:25 +0000
parents 47f4c8a5a7fc
children 4d2098e8c875
comparison
equal deleted inserted replaced
1458:40b69d238beb 1459:201d4e25c207
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 & IV computer games
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 * For more information about the Xan format, visit: 26 *
27 * http://www.pcisys.net/~melanson/codecs/ 27 * The xan_wc3 decoder outputs the following colorspaces natively:
28 * PAL8 (default), RGB555, RGB565, RGB24, BGR24, RGBA32, YUV444P
28 */ 29 */
29 30
30 #include <stdio.h> 31 #include <stdio.h>
31 #include <stdlib.h> 32 #include <stdlib.h>
32 #include <string.h> 33 #include <string.h>
118 printf (" WC3 Xan video: expected extradata_size of %d\n", 119 printf (" WC3 Xan video: expected extradata_size of %d\n",
119 PALETTE_CONTROL_SIZE); 120 PALETTE_CONTROL_SIZE);
120 return -1; 121 return -1;
121 } 122 }
122 123
123 avctx->pix_fmt = PIX_FMT_YUV444P; 124 avctx->pix_fmt = PIX_FMT_PAL8;
124 avctx->has_b_frames = 0; 125 avctx->has_b_frames = 0;
125 dsputil_init(&s->dsp, avctx); 126 dsputil_init(&s->dsp, avctx);
126 127
127 /* initialize the RGB -> YUV tables */ 128 /* initialize the RGB -> YUV tables */
128 for (i = 0; i < 256; i++) { 129 for (i = 0; i < 256; i++) {
137 v_r_table[i] = V_R * i; 138 v_r_table[i] = V_R * i;
138 v_g_table[i] = V_G * i; 139 v_g_table[i] = V_G * i;
139 v_b_table[i] = V_B * i; 140 v_b_table[i] = V_B * i;
140 } 141 }
141 142
142 s->buffer1 = av_malloc(avctx->width * avctx->height * 4); 143 s->buffer1 = av_malloc(avctx->width * avctx->height);
143 s->buffer2 = av_malloc(avctx->width * avctx->height * 4); 144 s->buffer2 = av_malloc(avctx->width * avctx->height);
144 if (!s->buffer1 || !s->buffer2) 145 if (!s->buffer1 || !s->buffer2)
145 return -1; 146 return -1;
146 147
147 return 0; 148 return 0;
148 } 149 }
158 159
159 for (i = 0; i < count; i++) 160 for (i = 0; i < count; i++)
160 dest[i] = src[i]; 161 dest[i] = src[i];
161 } 162 }
162 163
163 static int xan_decode_method_1(unsigned char *dest, unsigned char *src) 164 static int xan_huffman_decode(unsigned char *dest, unsigned char *src)
164 { 165 {
165 unsigned char byte = *src++; 166 unsigned char byte = *src++;
166 unsigned char ival = byte + 0x16; 167 unsigned char ival = byte + 0x16;
167 unsigned char * ptr = src + byte*2; 168 unsigned char * ptr = src + byte*2;
168 unsigned char val = ival; 169 unsigned char val = ival;
188 } 189 }
189 190
190 return 0; 191 return 0;
191 } 192 }
192 193
193 static int xan_decode_method_2(unsigned char *dest, unsigned char *src) 194 static void xan_unpack(unsigned char *dest, unsigned char *src)
194 { 195 {
195 unsigned char opcode; 196 unsigned char opcode;
196 int size; 197 int size;
197 int offset; 198 int offset;
198 int byte1, byte2, byte3; 199 int byte1, byte2, byte3;
247 } 248 }
248 } 249 }
249 250
250 size = opcode & 3; 251 size = opcode & 3;
251 bytecopy(dest, src, size); dest += size; src += size; 252 bytecopy(dest, src, size); dest += size; src += size;
252
253 return 0;
254 } 253 }
255 254
256 static void inline xan_wc3_build_palette(XanContext *s, 255 static void inline xan_wc3_build_palette(XanContext *s,
257 unsigned char *palette_data) 256 unsigned char *palette_data)
258 { 257 {
259 int i; 258 int i;
260 unsigned char r, g, b; 259 unsigned char r, g, b;
260 unsigned short *palette16;
261 unsigned int *palette32;
261 262
262 /* transform the palette passed through the palette control structure 263 /* transform the palette passed through the palette control structure
263 * into the necessary internal format depending on colorspace */ 264 * into the necessary internal format depending on colorspace */
264 265
265 switch (s->avctx->pix_fmt) { 266 switch (s->avctx->pix_fmt) {
267
268 case PIX_FMT_PAL8:
269 for (i = 0; i < PALETTE_COUNT; i++) {
270 r = *palette_data++;
271 g = *palette_data++;
272 b = *palette_data++;
273 s->palette[i * 4 + 0] = b;
274 s->palette[i * 4 + 1] = g;
275 s->palette[i * 4 + 2] = r;
276 }
277 break;
278
279 case PIX_FMT_RGB555:
280 palette16 = (unsigned short *)s->palette;
281 for (i = 0; i < PALETTE_COUNT; i++) {
282 r = *palette_data++;
283 g = *palette_data++;
284 b = *palette_data++;
285 palette16[i] =
286 ((r >> 3) << 10) |
287 ((g >> 3) << 5) |
288 ((g >> 3) << 0);
289 }
290 break;
291
292 case PIX_FMT_RGB565:
293 palette16 = (unsigned short *)s->palette;
294 for (i = 0; i < PALETTE_COUNT; i++) {
295 r = *palette_data++;
296 g = *palette_data++;
297 b = *palette_data++;
298 palette16[i] =
299 ((r >> 3) << 11) |
300 ((g >> 2) << 5) |
301 ((g >> 3) << 0);
302 }
303 break;
304
305 case PIX_FMT_RGB24:
306 for (i = 0; i < PALETTE_COUNT; i++) {
307 s->palette[i * 4 + 0] = *palette_data++;
308 s->palette[i * 4 + 1] = *palette_data++;
309 s->palette[i * 4 + 2] = *palette_data++;
310 }
311 break;
312
313 case PIX_FMT_BGR24:
314 for (i = 0; i < PALETTE_COUNT; i++) {
315 r = *palette_data++;
316 g = *palette_data++;
317 b = *palette_data++;
318 s->palette[i * 4 + 0] = b;
319 s->palette[i * 4 + 1] = g;
320 s->palette[i * 4 + 2] = r;
321 }
322 break;
323
324 case PIX_FMT_RGBA32:
325 palette32 = (unsigned int *)s->palette;
326 for (i = 0; i < PALETTE_COUNT; i++) {
327 r = *palette_data++;
328 g = *palette_data++;
329 b = *palette_data++;
330 palette32[i] = (r << 16) | (g << 8) | (b);
331 }
332 break;
266 333
267 case PIX_FMT_YUV444P: 334 case PIX_FMT_YUV444P:
268 for (i = 0; i < PALETTE_COUNT; i++) { 335 for (i = 0; i < PALETTE_COUNT; i++) {
269 r = *palette_data++; 336 r = *palette_data++;
270 g = *palette_data++; 337 g = *palette_data++;
288 int line_inc; 355 int line_inc;
289 int index; 356 int index;
290 int current_x; 357 int current_x;
291 int width = s->avctx->width; 358 int width = s->avctx->width;
292 unsigned char pixel; 359 unsigned char pixel;
360 unsigned char *palette_plane;
293 unsigned char *y_plane; 361 unsigned char *y_plane;
294 unsigned char *u_plane; 362 unsigned char *u_plane;
295 unsigned char *v_plane; 363 unsigned char *v_plane;
364 unsigned char *rgb_plane;
365 unsigned short *rgb16_plane;
366 unsigned short *palette16;
367 unsigned int *rgb32_plane;
368 unsigned int *palette32;
296 369
297 switch (s->avctx->pix_fmt) { 370 switch (s->avctx->pix_fmt) {
371
372 case PIX_FMT_PAL8:
373 palette_plane = s->current_frame.data[0];
374 stride = s->current_frame.linesize[0];
375 line_inc = stride - width;
376 index = y * stride + x;
377 current_x = x;
378 while(pixel_count--) {
379
380 /* don't do a memcpy() here; keyframes generally copy an entire
381 * frame of data and the stride needs to be accounted for */
382 palette_plane[index++] = *pixel_buffer++;
383
384 current_x++;
385 if (current_x >= width) {
386 /* reset accounting variables */
387 index += line_inc;
388 current_x = 0;
389 }
390 }
391 break;
392
393 case PIX_FMT_RGB555:
394 case PIX_FMT_RGB565:
395 rgb16_plane = (unsigned short *)s->current_frame.data[0];
396 palette16 = (unsigned short *)s->palette;
397 stride = s->current_frame.linesize[0] / 2;
398 line_inc = stride - width;
399 index = y * stride + x;
400 current_x = x;
401 while(pixel_count--) {
402
403 rgb16_plane[index++] = palette16[*pixel_buffer++];
404
405 current_x++;
406 if (current_x >= width) {
407 /* reset accounting variables */
408 index += line_inc;
409 current_x = 0;
410 }
411 }
412 break;
413
414 case PIX_FMT_RGB24:
415 case PIX_FMT_BGR24:
416 rgb_plane = s->current_frame.data[0];
417 stride = s->current_frame.linesize[0];
418 line_inc = stride - width * 3;
419 index = y * stride + x * 3;
420 current_x = x;
421 while(pixel_count--) {
422 pixel = *pixel_buffer++;
423
424 rgb_plane[index++] = s->palette[pixel * 4 + 0];
425 rgb_plane[index++] = s->palette[pixel * 4 + 1];
426 rgb_plane[index++] = s->palette[pixel * 4 + 2];
427
428 current_x++;
429 if (current_x >= width) {
430 /* reset accounting variables */
431 index += line_inc;
432 current_x = 0;
433 }
434 }
435 break;
436
437 case PIX_FMT_RGBA32:
438 rgb32_plane = (unsigned int *)s->current_frame.data[0];
439 palette32 = (unsigned int *)s->palette;
440 stride = s->current_frame.linesize[0] / 4;
441 line_inc = stride - width;
442 index = y * stride + x;
443 current_x = x;
444 while(pixel_count--) {
445
446 rgb32_plane[index++] = palette32[*pixel_buffer++];
447
448 current_x++;
449 if (current_x >= width) {
450 /* reset accounting variables */
451 index += line_inc;
452 current_x = 0;
453 }
454 }
455 break;
298 456
299 case PIX_FMT_YUV444P: 457 case PIX_FMT_YUV444P:
300 y_plane = s->current_frame.data[0]; 458 y_plane = s->current_frame.data[0];
301 u_plane = s->current_frame.data[1]; 459 u_plane = s->current_frame.data[1];
302 v_plane = s->current_frame.data[2]; 460 v_plane = s->current_frame.data[2];
333 int stride; 491 int stride;
334 int line_inc; 492 int line_inc;
335 int curframe_index, prevframe_index; 493 int curframe_index, prevframe_index;
336 int curframe_x, prevframe_x; 494 int curframe_x, prevframe_x;
337 int width = s->avctx->width; 495 int width = s->avctx->width;
496 unsigned char *palette_plane, *prev_palette_plane;
338 unsigned char *y_plane, *u_plane, *v_plane; 497 unsigned char *y_plane, *u_plane, *v_plane;
339 unsigned char *prev_y_plane, *prev_u_plane, *prev_v_plane; 498 unsigned char *prev_y_plane, *prev_u_plane, *prev_v_plane;
499 unsigned char *rgb_plane, *prev_rgb_plane;
500 unsigned short *rgb16_plane, *prev_rgb16_plane;
501 unsigned int *rgb32_plane, *prev_rgb32_plane;
340 502
341 switch (s->avctx->pix_fmt) { 503 switch (s->avctx->pix_fmt) {
504
505 case PIX_FMT_PAL8:
506 palette_plane = s->current_frame.data[0];
507 prev_palette_plane = s->last_frame.data[0];
508 stride = s->current_frame.linesize[0];
509 line_inc = stride - width;
510 curframe_index = y * stride + x;
511 curframe_x = x;
512 prevframe_index = (y + motion_y) * stride + x + motion_x;
513 prevframe_x = x + motion_x;
514 while(pixel_count--) {
515
516 palette_plane[curframe_index++] =
517 prev_palette_plane[prevframe_index++];
518
519 curframe_x++;
520 if (curframe_x >= width) {
521 /* reset accounting variables */
522 curframe_index += line_inc;
523 curframe_x = 0;
524 }
525
526 prevframe_x++;
527 if (prevframe_x >= width) {
528 /* reset accounting variables */
529 prevframe_index += line_inc;
530 prevframe_x = 0;
531 }
532 }
533 break;
534
535 case PIX_FMT_RGB555:
536 case PIX_FMT_RGB565:
537 rgb16_plane = (unsigned short *)s->current_frame.data[0];
538 prev_rgb16_plane = (unsigned short *)s->last_frame.data[0];
539 stride = s->current_frame.linesize[0] / 2;
540 line_inc = stride - width;
541 curframe_index = y * stride + x;
542 curframe_x = x;
543 prevframe_index = (y + motion_y) * stride + x + motion_x;
544 prevframe_x = x + motion_x;
545 while(pixel_count--) {
546
547 rgb16_plane[curframe_index++] =
548 prev_rgb16_plane[prevframe_index++];
549
550 curframe_x++;
551 if (curframe_x >= width) {
552 /* reset accounting variables */
553 curframe_index += line_inc;
554 curframe_x = 0;
555 }
556
557 prevframe_x++;
558 if (prevframe_x >= width) {
559 /* reset accounting variables */
560 prevframe_index += line_inc;
561 prevframe_x = 0;
562 }
563 }
564 break;
565
566 case PIX_FMT_RGB24:
567 case PIX_FMT_BGR24:
568 rgb_plane = s->current_frame.data[0];
569 prev_rgb_plane = s->last_frame.data[0];
570 stride = s->current_frame.linesize[0];
571 line_inc = stride - width * 3;
572 curframe_index = y * stride + x * 3;
573 curframe_x = x;
574 prevframe_index = (y + motion_y) * stride +
575 (3 * (x + motion_x));
576 prevframe_x = x + motion_x;
577 while(pixel_count--) {
578
579 rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++];
580 rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++];
581 rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++];
582
583 curframe_x++;
584 if (curframe_x >= width) {
585 /* reset accounting variables */
586 curframe_index += line_inc;
587 curframe_x = 0;
588 }
589
590 prevframe_x++;
591 if (prevframe_x >= width) {
592 /* reset accounting variables */
593 prevframe_index += line_inc;
594 prevframe_x = 0;
595 }
596 }
597 break;
598
599 case PIX_FMT_RGBA32:
600 rgb32_plane = (unsigned int *)s->current_frame.data[0];
601 prev_rgb32_plane = (unsigned int *)s->last_frame.data[0];
602 stride = s->current_frame.linesize[0] / 4;
603 line_inc = stride - width;
604 curframe_index = y * stride + x;
605 curframe_x = x;
606 prevframe_index = (y + motion_y) * stride + x + motion_x;
607 prevframe_x = x + motion_x;
608 while(pixel_count--) {
609
610 rgb32_plane[curframe_index++] =
611 prev_rgb32_plane[prevframe_index++];
612
613 curframe_x++;
614 if (curframe_x >= width) {
615 /* reset accounting variables */
616 curframe_index += line_inc;
617 curframe_x = 0;
618 }
619
620 prevframe_x++;
621 if (prevframe_x >= width) {
622 /* reset accounting variables */
623 prevframe_index += line_inc;
624 prevframe_x = 0;
625 }
626 }
627 break;
342 628
343 case PIX_FMT_YUV444P: 629 case PIX_FMT_YUV444P:
344 y_plane = s->current_frame.data[0]; 630 y_plane = s->current_frame.data[0];
345 u_plane = s->current_frame.data[1]; 631 u_plane = s->current_frame.data[1];
346 v_plane = s->current_frame.data[2]; 632 v_plane = s->current_frame.data[2];
349 prev_v_plane = s->last_frame.data[2]; 635 prev_v_plane = s->last_frame.data[2];
350 stride = s->current_frame.linesize[0]; 636 stride = s->current_frame.linesize[0];
351 line_inc = stride - width; 637 line_inc = stride - width;
352 curframe_index = y * stride + x; 638 curframe_index = y * stride + x;
353 curframe_x = x; 639 curframe_x = x;
354 prevframe_index = (y + motion_x) * stride + x + motion_x; 640 prevframe_index = (y + motion_y) * stride + x + motion_x;
355 prevframe_x = x + motion_x; 641 prevframe_x = x + motion_x;
356 while(pixel_count--) { 642 while(pixel_count--) {
357 643
358 y_plane[curframe_index] = prev_y_plane[prevframe_index]; 644 y_plane[curframe_index] = prev_y_plane[prevframe_index];
359 u_plane[curframe_index] = prev_u_plane[prevframe_index]; 645 u_plane[curframe_index] = prev_u_plane[prevframe_index];
392 unsigned char flag = 0; 678 unsigned char flag = 0;
393 int size = 0; 679 int size = 0;
394 int motion_x, motion_y; 680 int motion_x, motion_y;
395 int x, y; 681 int x, y;
396 682
397 unsigned char *method1_buffer = s->buffer1; 683 unsigned char *opcode_buffer = s->buffer1;
398 unsigned char *method2_buffer = s->buffer2; 684 unsigned char *imagedata_buffer = s->buffer2;
399 685
400 /* pointers to segments inside the compressed chunk */ 686 /* pointers to segments inside the compressed chunk */
401 unsigned char *method1_segment; 687 unsigned char *huffman_segment;
402 unsigned char *size_segment; 688 unsigned char *size_segment;
403 unsigned char *vector_segment; 689 unsigned char *vector_segment;
404 unsigned char *method2_segment; 690 unsigned char *imagedata_segment;
405 691
406 method1_segment = s->buf + LE_16(&s->buf[0]); 692 huffman_segment = s->buf + LE_16(&s->buf[0]);
407 size_segment = s->buf + LE_16(&s->buf[2]); 693 size_segment = s->buf + LE_16(&s->buf[2]);
408 vector_segment = s->buf + LE_16(&s->buf[4]); 694 vector_segment = s->buf + LE_16(&s->buf[4]);
409 method2_segment = s->buf + LE_16(&s->buf[6]); 695 imagedata_segment = s->buf + LE_16(&s->buf[6]);
410 696
411 xan_decode_method_1(method1_buffer, method1_segment); 697 xan_huffman_decode(opcode_buffer, huffman_segment);
412 if (method2_segment[0] == 2) 698
413 xan_decode_method_2(method2_buffer, method2_segment + 1); 699 if (imagedata_segment[0] == 2)
700 xan_unpack(imagedata_buffer, &imagedata_segment[1]);
414 else 701 else
415 method2_buffer = method2_segment + 1; 702 imagedata_buffer = &imagedata_segment[1];
416 703
417 /* use the decoded data segments to build the frame */ 704 /* use the decoded data segments to build the frame */
418 x = y = 0; 705 x = y = 0;
419 while (total_pixels) { 706 while (total_pixels) {
420 707
421 opcode = *method1_buffer++; 708 opcode = *opcode_buffer++;
422 size = 0; 709 size = 0;
423 710
424 switch (opcode) { 711 switch (opcode) {
425 712
426 case 0: 713 case 0:
471 flag ^= 1; 758 flag ^= 1;
472 if (flag) { 759 if (flag) {
473 /* run of (size) pixels is unchanged from last frame */ 760 /* run of (size) pixels is unchanged from last frame */
474 xan_wc3_copy_pixel_run(s, x, y, size, 0, 0); 761 xan_wc3_copy_pixel_run(s, x, y, size, 0, 0);
475 } else { 762 } else {
476 /* output a run of pixels from method2_buffer */ 763 /* output a run of pixels from imagedata_buffer */
477 xan_wc3_output_pixel_run(s, method2_buffer, x, y, size); 764 xan_wc3_output_pixel_run(s, imagedata_buffer, x, y, size);
478 method2_buffer += size; 765 imagedata_buffer += size;
479 } 766 }
480 } else { 767 } else {
481 /* run-based motion compensation from last frame */ 768 /* run-based motion compensation from last frame */
482 motion_x = (*vector_segment >> 4) & 0xF; 769 motion_x = (*vector_segment >> 4) & 0xF;
483 motion_y = *vector_segment & 0xF; 770 motion_y = *vector_segment & 0xF;
506 x += size; 793 x += size;
507 size = 0; 794 size = 0;
508 } 795 }
509 } 796 }
510 } 797 }
798
799 /* for PAL8, make the palette available on the way out */
800 if (s->avctx->pix_fmt == PIX_FMT_PAL8)
801 memcpy(s->current_frame.data[1], s->palette, PALETTE_COUNT * 4);
511 } 802 }
512 803
513 static void xan_wc4_decode_frame(XanContext *s) { 804 static void xan_wc4_decode_frame(XanContext *s) {
514 } 805 }
515 806
530 821
531 if (avctx->get_buffer(avctx, &s->current_frame)) { 822 if (avctx->get_buffer(avctx, &s->current_frame)) {
532 printf (" Interplay Video: get_buffer() failed\n"); 823 printf (" Interplay Video: get_buffer() failed\n");
533 return -1; 824 return -1;
534 } 825 }
826 s->current_frame.reference = 3;
535 827
536 s->buf = buf; 828 s->buf = buf;
537 s->size = buf_size; 829 s->size = buf_size;
538 830
539 if (avctx->codec->id == CODEC_ID_XAN_WC3) { 831 if (avctx->codec->id == CODEC_ID_XAN_WC3)
540 // if (keyframe) 832 xan_wc3_decode_frame(s);
541 if (1) 833 else if (avctx->codec->id == CODEC_ID_XAN_WC4)
542 xan_wc3_decode_frame(s);
543 else {
544 memcpy(s->current_frame.data[0], s->last_frame.data[0],
545 s->current_frame.linesize[0] * avctx->height);
546 memcpy(s->current_frame.data[1], s->last_frame.data[1],
547 s->current_frame.linesize[1] * avctx->height);
548 memcpy(s->current_frame.data[2], s->last_frame.data[2],
549 s->current_frame.linesize[2] * avctx->height);
550 }
551 } else if (avctx->codec->id == CODEC_ID_XAN_WC4)
552 xan_wc4_decode_frame(s); 834 xan_wc4_decode_frame(s);
553 835
554 /* release the last frame if it is allocated */ 836 /* release the last frame if it is allocated */
555 if (s->last_frame.data[0]) 837 if (s->last_frame.data[0])
556 avctx->release_buffer(avctx, &s->last_frame); 838 avctx->release_buffer(avctx, &s->last_frame);
557 839
558 /* shuffle frames */ 840 /* shuffle frames */