Fix bugs in previous commit that caused FTBFS in synfig and ETL FTBFS with older...
[synfig.git] / synfig-core / tags / synfig_0_61_05 / synfig-core / src / modules / mod_libavcodec / libavcodec / xan.c
1 /*
2  * Wing Commander/Xan Video Decoder
3  * Copyright (C) 2003 the ffmpeg project
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  */
20
21 /**
22  * @file xan.c
23  * Xan video decoder for Wing Commander III & IV computer games
24  * by Mario Brito (mbrito@student.dei.uc.pt)
25  * and Mike Melanson (melanson@pcisys.net)
26  *
27  * The xan_wc3 decoder outputs the following colorspaces natively:
28  *   PAL8 (default), RGB555, RGB565, RGB24, BGR24, RGBA32, YUV444P
29  */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <unistd.h>
35
36 #include "common.h"
37 #include "avcodec.h"
38 #include "dsputil.h"
39
40 #define PALETTE_COUNT 256
41 #define PALETTE_CONTROL_SIZE ((256 * 3) + 1)
42
43 typedef struct XanContext {
44
45     AVCodecContext *avctx;
46     DSPContext dsp;
47     AVFrame last_frame;
48     AVFrame current_frame;
49
50     unsigned char *buf;
51     int size;
52
53     unsigned char palette[PALETTE_COUNT * 4];
54
55     /* scratch space */
56     unsigned char *buffer1;
57     unsigned char *buffer2;
58
59 } XanContext;
60
61 #define BE_16(x)  ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1])
62 #define LE_16(x)  ((((uint8_t*)(x))[1] << 8) | ((uint8_t*)(x))[0])
63 #define LE_32(x)  ((((uint8_t*)(x))[3] << 24) | \
64                    (((uint8_t*)(x))[2] << 16) | \
65                    (((uint8_t*)(x))[1] << 8) | \
66                     ((uint8_t*)(x))[0])
67
68 /* RGB -> YUV conversion stuff */
69 #define SCALEFACTOR 65536
70 #define CENTERSAMPLE 128
71
72 #define COMPUTE_Y(r, g, b) \
73   (unsigned char) \
74   ((y_r_table[r] + y_g_table[g] + y_b_table[b]) / SCALEFACTOR)
75 #define COMPUTE_U(r, g, b) \
76   (unsigned char) \
77   ((u_r_table[r] + u_g_table[g] + u_b_table[b]) / SCALEFACTOR + CENTERSAMPLE)
78 #define COMPUTE_V(r, g, b) \
79   (unsigned char) \
80   ((v_r_table[r] + v_g_table[g] + v_b_table[b]) / SCALEFACTOR + CENTERSAMPLE)
81
82 #define Y_R (SCALEFACTOR *  0.29900)
83 #define Y_G (SCALEFACTOR *  0.58700)
84 #define Y_B (SCALEFACTOR *  0.11400)
85
86 #define U_R (SCALEFACTOR * -0.16874)
87 #define U_G (SCALEFACTOR * -0.33126)
88 #define U_B (SCALEFACTOR *  0.50000)
89
90 #define V_R (SCALEFACTOR *  0.50000)
91 #define V_G (SCALEFACTOR * -0.41869)
92 #define V_B (SCALEFACTOR * -0.08131)
93
94 /*
95  * Precalculate all of the YUV tables since it requires fewer than
96  * 10 kilobytes to store them.
97  */
98 static int y_r_table[256];
99 static int y_g_table[256];
100 static int y_b_table[256];
101
102 static int u_r_table[256];
103 static int u_g_table[256];
104 static int u_b_table[256];
105
106 static int v_r_table[256];
107 static int v_g_table[256];
108 static int v_b_table[256];
109
110 static int xan_decode_init(AVCodecContext *avctx)
111 {
112     XanContext *s = avctx->priv_data;
113     int i;
114
115     s->avctx = avctx;
116
117     if ((avctx->codec->id == CODEC_ID_XAN_WC3) && 
118         (s->avctx->extradata_size != sizeof(AVPaletteControl))) {
119         printf (" WC3 Xan video: expected extradata_size of %d\n",
120             sizeof(AVPaletteControl));
121         return -1;
122     }
123
124     avctx->pix_fmt = PIX_FMT_PAL8;
125     avctx->has_b_frames = 0;
126     dsputil_init(&s->dsp, avctx);
127
128     /* initialize the RGB -> YUV tables */
129     for (i = 0; i < 256; i++) {
130         y_r_table[i] = Y_R * i;
131         y_g_table[i] = Y_G * i;
132         y_b_table[i] = Y_B * i;
133
134         u_r_table[i] = U_R * i;
135         u_g_table[i] = U_G * i;
136         u_b_table[i] = U_B * i;
137
138         v_r_table[i] = V_R * i;
139         v_g_table[i] = V_G * i;
140         v_b_table[i] = V_B * i;
141     }
142
143     s->buffer1 = av_malloc(avctx->width * avctx->height);
144     s->buffer2 = av_malloc(avctx->width * avctx->height);
145     if (!s->buffer1 || !s->buffer2)
146         return -1;
147
148     return 0;
149 }
150
151 /* This function is used in lieu of memcpy(). This decoder can not use 
152  * memcpy because the memory locations often overlap and
153  * memcpy doesn't like that; it's not uncommon, for example, for
154  * dest = src+1, to turn byte A into  pattern AAAAAAAA.
155  * This was originally repz movsb in Intel x86 ASM. */
156 static inline void bytecopy(unsigned char *dest, unsigned char *src, int count)
157 {
158     int i;
159
160     for (i = 0; i < count; i++)
161         dest[i] = src[i];
162 }
163
164 static int xan_huffman_decode(unsigned char *dest, unsigned char *src)
165 {
166     unsigned char byte = *src++;
167     unsigned char ival = byte + 0x16;
168     unsigned char * ptr = src + byte*2;
169     unsigned char val = ival;
170     int counter = 0;
171
172     unsigned char bits = *ptr++;
173
174     while ( val != 0x16 ) {
175         if ( (1 << counter) & bits )
176             val = src[byte + val - 0x17];
177         else
178             val = src[val - 0x17];
179
180         if ( val < 0x16 ) {
181             *dest++ = val;
182             val = ival;
183         }
184
185         if (counter++ == 7) {
186             counter = 0;
187             bits = *ptr++;
188         }
189     }
190
191     return 0;
192 }
193
194 static void xan_unpack(unsigned char *dest, unsigned char *src)
195 {
196     unsigned char opcode;
197     int size;
198     int offset;
199     int byte1, byte2, byte3;
200
201     for (;;) {
202         opcode = *src++;
203
204         if ( (opcode & 0x80) == 0 ) {
205
206             offset = *src++;
207
208             size = opcode & 3;
209             bytecopy(dest, src, size);  dest += size;  src += size;
210
211             size = ((opcode & 0x1c) >> 2) + 3;
212             bytecopy (dest, dest - (((opcode & 0x60) << 3) + offset + 1), size);
213             dest += size;
214
215         } else if ( (opcode & 0x40) == 0 ) {
216
217             byte1 = *src++;
218             byte2 = *src++;
219
220             size = byte1 >> 6;
221             bytecopy (dest, src, size);  dest += size;  src += size;
222
223             size = (opcode & 0x3f) + 4;
224             bytecopy (dest, dest - (((byte1 & 0x3f) << 8) + byte2 + 1), size);
225             dest += size;
226
227         } else if ( (opcode & 0x20) == 0 ) {
228
229             byte1 = *src++;
230             byte2 = *src++;
231             byte3 = *src++;
232
233             size = opcode & 3;
234             bytecopy (dest, src, size);  dest += size;  src += size;
235
236             size = byte3 + 5 + ((opcode & 0xc) << 6);
237             bytecopy (dest,
238                 dest - ((((opcode & 0x10) >> 4) << 0x10) + 1 + (byte1 << 8) + byte2),
239                 size);
240             dest += size;
241         } else {
242             size = ((opcode & 0x1f) << 2) + 4;
243
244             if (size > 0x70)
245                 break;
246
247             bytecopy (dest, src, size);  dest += size;  src += size;
248         }
249     }
250
251     size = opcode & 3;
252     bytecopy(dest, src, size);  dest += size;  src += size;
253 }
254
255 static void inline xan_wc3_build_palette(XanContext *s, 
256     unsigned char *palette_data)
257 {
258     int i;
259     unsigned char r, g, b;
260     unsigned short *palette16;
261     unsigned int *palette32;
262
263     /* transform the palette passed through the palette control structure
264      * into the necessary internal format depending on colorspace */
265
266     switch (s->avctx->pix_fmt) {
267
268     case PIX_FMT_RGB555:
269         palette16 = (unsigned short *)s->palette;
270         for (i = 0; i < PALETTE_COUNT; i++) {
271             r = *palette_data++;
272             g = *palette_data++;
273             b = *palette_data++;
274             palette16[i] = 
275                 ((r >> 3) << 10) |
276                 ((g >> 3) <<  5) |
277                 ((b >> 3) <<  0);
278         }
279         break;
280
281     case PIX_FMT_RGB565:
282         palette16 = (unsigned short *)s->palette;
283         for (i = 0; i < PALETTE_COUNT; i++) {
284             r = *palette_data++;
285             g = *palette_data++;
286             b = *palette_data++;
287             palette16[i] = 
288                 ((r >> 3) << 11) |
289                 ((g >> 2) <<  5) |
290                 ((b >> 3) <<  0);
291         }
292         break;
293
294     case PIX_FMT_RGB24:
295         for (i = 0; i < PALETTE_COUNT; i++) {
296             s->palette[i * 4 + 0] = *palette_data++;
297             s->palette[i * 4 + 1] = *palette_data++;
298             s->palette[i * 4 + 2] = *palette_data++;
299         }
300         break;
301
302     case PIX_FMT_BGR24:
303         for (i = 0; i < PALETTE_COUNT; i++) {
304             r = *palette_data++;
305             g = *palette_data++;
306             b = *palette_data++;
307             s->palette[i * 4 + 0] = b;
308             s->palette[i * 4 + 1] = g;
309             s->palette[i * 4 + 2] = r;
310         }
311         break;
312
313     case PIX_FMT_PAL8:
314     case PIX_FMT_RGBA32:
315         palette32 = (unsigned int *)s->palette;
316         for (i = 0; i < PALETTE_COUNT; i++) {
317             r = *palette_data++;
318             g = *palette_data++;
319             b = *palette_data++;
320             palette32[i] = (r << 16) | (g << 8) | (b);
321         }
322         break;
323
324     case PIX_FMT_YUV444P:
325         for (i = 0; i < PALETTE_COUNT; i++) {
326             r = *palette_data++;
327             g = *palette_data++;
328             b = *palette_data++;
329             s->palette[i * 4 + 0] = COMPUTE_Y(r, g, b);
330             s->palette[i * 4 + 1] = COMPUTE_U(r, g, b);
331             s->palette[i * 4 + 2] = COMPUTE_V(r, g, b);
332         }
333         break;
334
335     default:
336         printf (" Xan WC3: Unhandled colorspace\n");
337         break;
338     }
339 }
340
341 /* advance current_x variable; reset accounting variables if current_x
342  * moves beyond width */
343 #define ADVANCE_CURRENT_X() \
344     current_x++; \
345     if (current_x >= width) { \
346         index += line_inc; \
347         current_x = 0; \
348     }
349
350 static void inline xan_wc3_output_pixel_run(XanContext *s, 
351     unsigned char *pixel_buffer, int x, int y, int pixel_count)
352 {
353     int stride;
354     int line_inc;
355     int index;
356     int current_x;
357     int width = s->avctx->width;
358     unsigned char pix;
359     unsigned char *palette_plane;
360     unsigned char *y_plane;
361     unsigned char *u_plane;
362     unsigned char *v_plane;
363     unsigned char *rgb_plane;
364     unsigned short *rgb16_plane;
365     unsigned short *palette16;
366     unsigned int *rgb32_plane;
367     unsigned int *palette32;
368
369     switch (s->avctx->pix_fmt) {
370
371     case PIX_FMT_PAL8:
372         palette_plane = s->current_frame.data[0];
373         stride = s->current_frame.linesize[0];
374         line_inc = stride - width;
375         index = y * stride + x;
376         current_x = x;
377         while(pixel_count--) {
378
379             /* don't do a memcpy() here; keyframes generally copy an entire
380              * frame of data and the stride needs to be accounted for */
381             palette_plane[index++] = *pixel_buffer++;
382
383             ADVANCE_CURRENT_X();
384         }
385         break;
386
387     case PIX_FMT_RGB555:
388     case PIX_FMT_RGB565:
389         rgb16_plane = (unsigned short *)s->current_frame.data[0];
390         palette16 = (unsigned short *)s->palette;
391         stride = s->current_frame.linesize[0] / 2;
392         line_inc = stride - width;
393         index = y * stride + x;
394         current_x = x;
395         while(pixel_count--) {
396
397             rgb16_plane[index++] = palette16[*pixel_buffer++];
398
399             ADVANCE_CURRENT_X();
400         }
401         break;
402
403     case PIX_FMT_RGB24:
404     case PIX_FMT_BGR24:
405         rgb_plane = s->current_frame.data[0];
406         stride = s->current_frame.linesize[0];
407         line_inc = stride - width * 3;
408         index = y * stride + x * 3;
409         current_x = x;
410         while(pixel_count--) {
411             pix = *pixel_buffer++;
412
413             rgb_plane[index++] = s->palette[pix * 4 + 0];
414             rgb_plane[index++] = s->palette[pix * 4 + 1];
415             rgb_plane[index++] = s->palette[pix * 4 + 2];
416
417             ADVANCE_CURRENT_X();
418         }
419         break;
420
421     case PIX_FMT_RGBA32:
422         rgb32_plane = (unsigned int *)s->current_frame.data[0];
423         palette32 = (unsigned int *)s->palette;
424         stride = s->current_frame.linesize[0] / 4;
425         line_inc = stride - width;
426         index = y * stride + x;
427         current_x = x;
428         while(pixel_count--) {
429
430             rgb32_plane[index++] = palette32[*pixel_buffer++];
431
432             ADVANCE_CURRENT_X();
433         }
434         break;
435
436     case PIX_FMT_YUV444P:
437         y_plane = s->current_frame.data[0];
438         u_plane = s->current_frame.data[1];
439         v_plane = s->current_frame.data[2];
440         stride = s->current_frame.linesize[0];
441         line_inc = stride - width;
442         index = y * stride + x;
443         current_x = x;
444         while(pixel_count--) {
445             pix = *pixel_buffer++;
446
447             y_plane[index] = s->palette[pix * 4 + 0];
448             u_plane[index] = s->palette[pix * 4 + 1];
449             v_plane[index] = s->palette[pix * 4 + 2];
450
451             index++;
452             ADVANCE_CURRENT_X();
453         }
454         break;
455
456     default:
457         printf (" Xan WC3: Unhandled colorspace\n");
458         break;
459     }
460 }
461
462 #define ADVANCE_CURFRAME_X() \
463     curframe_x++; \
464     if (curframe_x >= width) { \
465         curframe_index += line_inc; \
466         curframe_x = 0; \
467     }
468
469 #define ADVANCE_PREVFRAME_X() \
470     prevframe_x++; \
471     if (prevframe_x >= width) { \
472         prevframe_index += line_inc; \
473         prevframe_x = 0; \
474     }
475
476 static void inline xan_wc3_copy_pixel_run(XanContext *s, 
477     int x, int y, int pixel_count, int motion_x, int motion_y)
478 {
479     int stride;
480     int line_inc;
481     int curframe_index, prevframe_index;
482     int curframe_x, prevframe_x;
483     int width = s->avctx->width;
484     unsigned char *palette_plane, *prev_palette_plane;
485     unsigned char *y_plane, *u_plane, *v_plane;
486     unsigned char *prev_y_plane, *prev_u_plane, *prev_v_plane;
487     unsigned char *rgb_plane, *prev_rgb_plane;
488     unsigned short *rgb16_plane, *prev_rgb16_plane;
489     unsigned int *rgb32_plane, *prev_rgb32_plane;
490
491     switch (s->avctx->pix_fmt) {
492
493     case PIX_FMT_PAL8:
494         palette_plane = s->current_frame.data[0];
495         prev_palette_plane = s->last_frame.data[0];
496         stride = s->current_frame.linesize[0];
497         line_inc = stride - width;
498         curframe_index = y * stride + x;
499         curframe_x = x;
500         prevframe_index = (y + motion_y) * stride + x + motion_x;
501         prevframe_x = x + motion_x;
502         while(pixel_count--) {
503
504             palette_plane[curframe_index++] = 
505                 prev_palette_plane[prevframe_index++];
506
507             ADVANCE_CURFRAME_X();
508             ADVANCE_PREVFRAME_X();
509         }
510         break;
511
512     case PIX_FMT_RGB555:
513     case PIX_FMT_RGB565:
514         rgb16_plane = (unsigned short *)s->current_frame.data[0];
515         prev_rgb16_plane = (unsigned short *)s->last_frame.data[0];
516         stride = s->current_frame.linesize[0] / 2;
517         line_inc = stride - width;
518         curframe_index = y * stride + x;
519         curframe_x = x;
520         prevframe_index = (y + motion_y) * stride + x + motion_x;
521         prevframe_x = x + motion_x;
522         while(pixel_count--) {
523
524             rgb16_plane[curframe_index++] = 
525                 prev_rgb16_plane[prevframe_index++];
526
527             ADVANCE_CURFRAME_X();
528             ADVANCE_PREVFRAME_X();
529         }
530         break;
531
532     case PIX_FMT_RGB24:
533     case PIX_FMT_BGR24:
534         rgb_plane = s->current_frame.data[0];
535         prev_rgb_plane = s->last_frame.data[0];
536         stride = s->current_frame.linesize[0];
537         line_inc = stride - width * 3;
538         curframe_index = y * stride + x * 3;
539         curframe_x = x;
540         prevframe_index = (y + motion_y) * stride + 
541             (3 * (x + motion_x));
542         prevframe_x = x + motion_x;
543         while(pixel_count--) {
544
545             rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++];
546             rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++];
547             rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++];
548
549             ADVANCE_CURFRAME_X();
550             ADVANCE_PREVFRAME_X();
551         }
552         break;
553
554     case PIX_FMT_RGBA32:
555         rgb32_plane = (unsigned int *)s->current_frame.data[0];
556         prev_rgb32_plane = (unsigned int *)s->last_frame.data[0];
557         stride = s->current_frame.linesize[0] / 4;
558         line_inc = stride - width;
559         curframe_index = y * stride + x;
560         curframe_x = x;
561         prevframe_index = (y + motion_y) * stride + x + motion_x;
562         prevframe_x = x + motion_x;
563         while(pixel_count--) {
564
565             rgb32_plane[curframe_index++] = 
566                 prev_rgb32_plane[prevframe_index++];
567
568             ADVANCE_CURFRAME_X();
569             ADVANCE_PREVFRAME_X();
570         }
571         break;
572
573     case PIX_FMT_YUV444P:
574         y_plane = s->current_frame.data[0];
575         u_plane = s->current_frame.data[1];
576         v_plane = s->current_frame.data[2];
577         prev_y_plane = s->last_frame.data[0];
578         prev_u_plane = s->last_frame.data[1];
579         prev_v_plane = s->last_frame.data[2];
580         stride = s->current_frame.linesize[0];
581         line_inc = stride - width;
582         curframe_index = y * stride + x;
583         curframe_x = x;
584         prevframe_index = (y + motion_y) * stride + x + motion_x;
585         prevframe_x = x + motion_x;
586         while(pixel_count--) {
587
588             y_plane[curframe_index] = prev_y_plane[prevframe_index];
589             u_plane[curframe_index] = prev_u_plane[prevframe_index];
590             v_plane[curframe_index] = prev_v_plane[prevframe_index];
591
592             curframe_index++;
593             ADVANCE_CURFRAME_X();
594             prevframe_index++;
595             ADVANCE_PREVFRAME_X();
596         }
597         break;
598
599     default:
600         printf (" Xan WC3: Unhandled colorspace\n");
601         break;
602     }
603 }
604
605 static void xan_wc3_decode_frame(XanContext *s) {
606
607     int width = s->avctx->width;
608     int height = s->avctx->height;
609     int total_pixels = width * height;
610     unsigned char opcode;
611     unsigned char flag = 0;
612     int size = 0;
613     int motion_x, motion_y;
614     int x, y;
615
616     unsigned char *opcode_buffer = s->buffer1;
617     unsigned char *imagedata_buffer = s->buffer2;
618
619     /* pointers to segments inside the compressed chunk */
620     unsigned char *huffman_segment;
621     unsigned char *size_segment;
622     unsigned char *vector_segment;
623     unsigned char *imagedata_segment;
624
625     huffman_segment =   s->buf + LE_16(&s->buf[0]);
626     size_segment =      s->buf + LE_16(&s->buf[2]);
627     vector_segment =    s->buf + LE_16(&s->buf[4]);
628     imagedata_segment = s->buf + LE_16(&s->buf[6]);
629
630     xan_huffman_decode(opcode_buffer, huffman_segment);
631
632     if (imagedata_segment[0] == 2)
633         xan_unpack(imagedata_buffer, &imagedata_segment[1]);
634     else
635         imagedata_buffer = &imagedata_segment[1];
636
637     /* use the decoded data segments to build the frame */
638     x = y = 0;
639     while (total_pixels) {
640
641         opcode = *opcode_buffer++;
642         size = 0;
643
644         switch (opcode) {
645
646         case 0:
647             flag ^= 1;
648             continue;
649
650         case 1:
651         case 2:
652         case 3:
653         case 4:
654         case 5:
655         case 6:
656         case 7:
657         case 8:
658             size = opcode;
659             break;
660
661         case 12:
662         case 13:
663         case 14:
664         case 15:
665         case 16:
666         case 17:
667         case 18:
668             size += (opcode - 10);
669             break;
670
671         case 9:
672         case 19:
673             size = *size_segment++;
674             break;
675
676         case 10:
677         case 20:
678             size = BE_16(&size_segment[0]);
679             size_segment += 2;
680             break;
681
682         case 11:
683         case 21:
684             size = (size_segment[0] << 16) | (size_segment[1] << 8) |
685                 size_segment[2];
686             size_segment += 3;
687             break;
688         }
689
690         if (opcode < 12) {
691             flag ^= 1;
692             if (flag) {
693                 /* run of (size) pixels is unchanged from last frame */
694                 xan_wc3_copy_pixel_run(s, x, y, size, 0, 0);
695             } else {
696                 /* output a run of pixels from imagedata_buffer */
697                 xan_wc3_output_pixel_run(s, imagedata_buffer, x, y, size);
698                 imagedata_buffer += size;
699             }
700         } else {
701             /* run-based motion compensation from last frame */
702             motion_x = (*vector_segment >> 4) & 0xF;
703             motion_y = *vector_segment & 0xF;
704             vector_segment++;
705
706             /* sign extension */
707             if (motion_x & 0x8)
708                 motion_x |= 0xFFFFFFF0;
709             if (motion_y & 0x8)
710                 motion_y |= 0xFFFFFFF0;
711
712             /* copy a run of pixels from the previous frame */
713             xan_wc3_copy_pixel_run(s, x, y, size, motion_x, motion_y);
714
715             flag = 0;
716         }
717
718         /* coordinate accounting */
719         total_pixels -= size;
720         while (size) {
721             if (x + size >= width) {
722                 y++;
723                 size -= (width - x);
724                 x = 0;
725             } else {
726                 x += size;
727                 size = 0;
728             }
729         }
730     }
731
732     /* for PAL8, make the palette available on the way out */
733     if (s->avctx->pix_fmt == PIX_FMT_PAL8)
734         memcpy(s->current_frame.data[1], s->palette, PALETTE_COUNT * 4);
735 }
736
737 static void xan_wc4_decode_frame(XanContext *s) {
738 }
739
740 static int xan_decode_frame(AVCodecContext *avctx,
741                             void *data, int *data_size,
742                             uint8_t *buf, int buf_size)
743 {
744     XanContext *s = avctx->priv_data;
745     AVPaletteControl *palette_control = (AVPaletteControl *)avctx->extradata;
746     int keyframe = 0;
747
748     if (palette_control->palette_changed) {
749         /* load the new palette and reset the palette control */
750         xan_wc3_build_palette(s, palette_control->palette);
751         palette_control->palette_changed = 0;
752         keyframe = 1;
753     }
754
755     if (avctx->get_buffer(avctx, &s->current_frame)) {
756         printf ("  Xan Video: get_buffer() failed\n");
757         return -1;
758     }
759     s->current_frame.reference = 3;
760
761     s->buf = buf;
762     s->size = buf_size;
763
764     if (avctx->codec->id == CODEC_ID_XAN_WC3)
765         xan_wc3_decode_frame(s);
766     else if (avctx->codec->id == CODEC_ID_XAN_WC4)
767         xan_wc4_decode_frame(s);
768
769     /* release the last frame if it is allocated */
770     if (s->last_frame.data[0])
771         avctx->release_buffer(avctx, &s->last_frame);
772
773     /* shuffle frames */
774     s->last_frame = s->current_frame;
775
776     *data_size = sizeof(AVFrame);
777     *(AVFrame*)data = s->current_frame;
778
779     /* always report that the buffer was completely consumed */
780     return buf_size;
781 }
782
783 static int xan_decode_end(AVCodecContext *avctx)
784 {
785     XanContext *s = avctx->priv_data;
786
787     /* release the last frame */
788     avctx->release_buffer(avctx, &s->last_frame);
789
790     av_free(s->buffer1);
791     av_free(s->buffer2);
792
793     return 0;
794 }
795
796 AVCodec xan_wc3_decoder = {
797     "xan_wc3",
798     CODEC_TYPE_VIDEO,
799     CODEC_ID_XAN_WC3,
800     sizeof(XanContext),
801     xan_decode_init,
802     NULL,
803     xan_decode_end,
804     xan_decode_frame,
805     CODEC_CAP_DR1,
806 };
807
808 /*
809 AVCodec xan_wc4_decoder = {
810     "xan_wc4",
811     CODEC_TYPE_VIDEO,
812     CODEC_ID_XAN_WC4,
813     sizeof(XanContext),
814     xan_decode_init,
815     NULL,
816     xan_decode_end,
817     xan_decode_frame,
818     CODEC_CAP_DR1,
819 };
820 */