]> git.sesse.net Git - ffmpeg/blob - libavcodec/flicvideo.c
Use proper PRI?64 macros for %ll? format to fix printf format warnings:
[ffmpeg] / libavcodec / flicvideo.c
1 /*
2  * FLI/FLC Animation Video Decoder
3  * Copyright (C) 2003, 2004 the ffmpeg project
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  *
21  */
22
23 /**
24  * @file flic.c
25  * Autodesk Animator FLI/FLC Video Decoder
26  * by Mike Melanson (melanson@pcisys.net)
27  * for more information on the .fli/.flc file format and all of its many
28  * variations, visit:
29  *   http://www.compuphase.com/flic.htm
30  *
31  * This decoder outputs PAL8/RGB555/RGB565 and maybe one day RGB24
32  * colorspace data, depending on the FLC. To use this decoder, be
33  * sure that your demuxer sends the FLI file header to the decoder via
34  * the extradata chunk in AVCodecContext. The chunk should be 128 bytes
35  * large. The only exception is for FLI files from the game "Magic Carpet",
36  * in which the header is only 12 bytes.
37  */
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <unistd.h>
43
44 #include "common.h"
45 #include "avcodec.h"
46 #include "bswap.h"
47
48 #define FLI_256_COLOR 4
49 #define FLI_DELTA     7
50 #define FLI_COLOR     11
51 #define FLI_LC        12
52 #define FLI_BLACK     13
53 #define FLI_BRUN      15
54 #define FLI_COPY      16
55 #define FLI_MINI      18
56 #define FLI_DTA_BRUN  25
57 #define FLI_DTA_COPY  26
58 #define FLI_DTA_LC    27
59
60 #define FLI_TYPE_CODE     (0xAF11)
61 #define FLC_FLX_TYPE_CODE (0xAF12)
62 #define FLC_DTA_TYPE_CODE (0xAF44) /* Marks an "Extended FLC" comes from Dave's Targa Animator (DTA) */
63 #define FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE (0xAF13)
64
65 #define CHECK_PIXEL_PTR(n) \
66     if (pixel_ptr + n > pixel_limit) { \
67         av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr >= pixel_limit (%d >= %d)\n", \
68         pixel_ptr + n, pixel_limit); \
69         return -1; \
70     } \
71
72 typedef struct FlicDecodeContext {
73     AVCodecContext *avctx;
74     AVFrame frame;
75
76     unsigned int palette[256];
77     int new_palette;
78     int fli_type;  /* either 0xAF11 or 0xAF12, affects palette resolution */
79 } FlicDecodeContext;
80
81 static int flic_decode_init(AVCodecContext *avctx)
82 {
83     FlicDecodeContext *s = (FlicDecodeContext *)avctx->priv_data;
84     unsigned char *fli_header = (unsigned char *)avctx->extradata;
85     int depth;
86
87     s->avctx = avctx;
88     avctx->has_b_frames = 0;
89
90     s->fli_type = LE_16(&fli_header[4]); /* Might be overridden if a Magic Carpet FLC */
91     depth       = LE_16(&fli_header[12]);
92
93     if (depth == 0) {
94       depth = 8; /* Some FLC generators set depth to zero, when they mean 8Bpp. Fix up here */
95     }
96
97     if (s->avctx->extradata_size == 12) {
98         /* special case for magic carpet FLIs */
99         s->fli_type = FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE;
100     } else if (s->avctx->extradata_size != 128) {
101         av_log(avctx, AV_LOG_ERROR, "Expected extradata of 12 or 128 bytes\n");
102         return -1;
103     }
104
105     if ((s->fli_type == FLC_FLX_TYPE_CODE) && (depth == 16)) {
106         depth = 15; /* Original Autodesk FLX's say the depth is 16Bpp when it is really 15Bpp */
107     }
108
109     switch (depth) {
110         case 8  : avctx->pix_fmt = PIX_FMT_PAL8; break;
111         case 15 : avctx->pix_fmt = PIX_FMT_RGB555; break;
112         case 16 : avctx->pix_fmt = PIX_FMT_RGB565; break;
113         case 24 : avctx->pix_fmt = PIX_FMT_BGR24; /* Supposedly BGR, but havent any files to test with */
114                   av_log(avctx, AV_LOG_ERROR, "24Bpp FLC/FLX is unsupported due to no test files.\n");
115                   return -1;
116                   break;
117         default :
118                   av_log(avctx, AV_LOG_ERROR, "Unkown FLC/FLX depth of %d Bpp is unsupported.\n",depth);
119                   return -1;
120     }
121
122     s->frame.data[0] = NULL;
123     s->new_palette = 0;
124
125     return 0;
126 }
127
128 static int flic_decode_frame_8BPP(AVCodecContext *avctx,
129                                   void *data, int *data_size,
130                                   uint8_t *buf, int buf_size)
131 {
132     FlicDecodeContext *s = (FlicDecodeContext *)avctx->priv_data;
133
134     int stream_ptr = 0;
135     int stream_ptr_after_color_chunk;
136     int pixel_ptr;
137     int palette_ptr;
138     unsigned char palette_idx1;
139     unsigned char palette_idx2;
140
141     unsigned int frame_size;
142     int num_chunks;
143
144     unsigned int chunk_size;
145     int chunk_type;
146
147     int i, j;
148
149     int color_packets;
150     int color_changes;
151     int color_shift;
152     unsigned char r, g, b;
153
154     int lines;
155     int compressed_lines;
156     int starting_line;
157     signed short line_packets;
158     int y_ptr;
159     signed char byte_run;
160     int pixel_skip;
161     int pixel_countdown;
162     unsigned char *pixels;
163     int pixel_limit;
164
165     s->frame.reference = 1;
166     s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
167     if (avctx->reget_buffer(avctx, &s->frame) < 0) {
168         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
169         return -1;
170     }
171
172     pixels = s->frame.data[0];
173     pixel_limit = s->avctx->height * s->frame.linesize[0];
174
175     frame_size = LE_32(&buf[stream_ptr]);
176     stream_ptr += 6;  /* skip the magic number */
177     num_chunks = LE_16(&buf[stream_ptr]);
178     stream_ptr += 10;  /* skip padding */
179
180     frame_size -= 16;
181
182     /* iterate through the chunks */
183     while ((frame_size > 0) && (num_chunks > 0)) {
184         chunk_size = LE_32(&buf[stream_ptr]);
185         stream_ptr += 4;
186         chunk_type = LE_16(&buf[stream_ptr]);
187         stream_ptr += 2;
188
189         switch (chunk_type) {
190         case FLI_256_COLOR:
191         case FLI_COLOR:
192             stream_ptr_after_color_chunk = stream_ptr + chunk_size - 6;
193             s->new_palette = 1;
194
195             /* check special case: If this file is from the Magic Carpet
196              * game and uses 6-bit colors even though it reports 256-color
197              * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during
198              * initialization) */
199             if ((chunk_type == FLI_256_COLOR) && (s->fli_type != FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE))
200                 color_shift = 0;
201             else
202                 color_shift = 2;
203             /* set up the palette */
204             color_packets = LE_16(&buf[stream_ptr]);
205             stream_ptr += 2;
206             palette_ptr = 0;
207             for (i = 0; i < color_packets; i++) {
208                 /* first byte is how many colors to skip */
209                 palette_ptr += buf[stream_ptr++];
210
211                 /* next byte indicates how many entries to change */
212                 color_changes = buf[stream_ptr++];
213
214                 /* if there are 0 color changes, there are actually 256 */
215                 if (color_changes == 0)
216                     color_changes = 256;
217
218                 for (j = 0; j < color_changes; j++) {
219
220                     /* wrap around, for good measure */
221                     if ((unsigned)palette_ptr >= 256)
222                         palette_ptr = 0;
223
224                     r = buf[stream_ptr++] << color_shift;
225                     g = buf[stream_ptr++] << color_shift;
226                     b = buf[stream_ptr++] << color_shift;
227                     s->palette[palette_ptr++] = (r << 16) | (g << 8) | b;
228                 }
229             }
230
231             /* color chunks sometimes have weird 16-bit alignment issues;
232              * therefore, take the hardline approach and set the stream_ptr
233              * to the value calculated w.r.t. the size specified by the color
234              * chunk header */
235             stream_ptr = stream_ptr_after_color_chunk;
236
237             break;
238
239         case FLI_DELTA:
240             y_ptr = 0;
241             compressed_lines = LE_16(&buf[stream_ptr]);
242             stream_ptr += 2;
243             while (compressed_lines > 0) {
244                 line_packets = LE_16(&buf[stream_ptr]);
245                 stream_ptr += 2;
246                 if (line_packets < 0) {
247                     line_packets = -line_packets;
248                     y_ptr += line_packets * s->frame.linesize[0];
249                 } else {
250                     compressed_lines--;
251                     pixel_ptr = y_ptr;
252                     pixel_countdown = s->avctx->width;
253                     for (i = 0; i < line_packets; i++) {
254                         /* account for the skip bytes */
255                         pixel_skip = buf[stream_ptr++];
256                         pixel_ptr += pixel_skip;
257                         pixel_countdown -= pixel_skip;
258                         byte_run = buf[stream_ptr++];
259                         if (byte_run < 0) {
260                             byte_run = -byte_run;
261                             palette_idx1 = buf[stream_ptr++];
262                             palette_idx2 = buf[stream_ptr++];
263                             CHECK_PIXEL_PTR(byte_run);
264                             for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
265                                 pixels[pixel_ptr++] = palette_idx1;
266                                 pixels[pixel_ptr++] = palette_idx2;
267                             }
268                         } else {
269                             CHECK_PIXEL_PTR(byte_run * 2);
270                             for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
271                                 palette_idx1 = buf[stream_ptr++];
272                                 pixels[pixel_ptr++] = palette_idx1;
273                             }
274                         }
275                     }
276
277                     y_ptr += s->frame.linesize[0];
278                 }
279             }
280             break;
281
282         case FLI_LC:
283             /* line compressed */
284             starting_line = LE_16(&buf[stream_ptr]);
285             stream_ptr += 2;
286             y_ptr = 0;
287             y_ptr += starting_line * s->frame.linesize[0];
288
289             compressed_lines = LE_16(&buf[stream_ptr]);
290             stream_ptr += 2;
291             while (compressed_lines > 0) {
292                 pixel_ptr = y_ptr;
293                 pixel_countdown = s->avctx->width;
294                 line_packets = buf[stream_ptr++];
295                 if (line_packets > 0) {
296                     for (i = 0; i < line_packets; i++) {
297                         /* account for the skip bytes */
298                         pixel_skip = buf[stream_ptr++];
299                         pixel_ptr += pixel_skip;
300                         pixel_countdown -= pixel_skip;
301                         byte_run = buf[stream_ptr++];
302                         if (byte_run > 0) {
303                             CHECK_PIXEL_PTR(byte_run);
304                             for (j = 0; j < byte_run; j++, pixel_countdown--) {
305                                 palette_idx1 = buf[stream_ptr++];
306                                 pixels[pixel_ptr++] = palette_idx1;
307                             }
308                         } else {
309                             byte_run = -byte_run;
310                             palette_idx1 = buf[stream_ptr++];
311                             CHECK_PIXEL_PTR(byte_run);
312                             for (j = 0; j < byte_run; j++, pixel_countdown--) {
313                                 pixels[pixel_ptr++] = palette_idx1;
314                             }
315                         }
316                     }
317                 }
318
319                 y_ptr += s->frame.linesize[0];
320                 compressed_lines--;
321             }
322             break;
323
324         case FLI_BLACK:
325             /* set the whole frame to color 0 (which is usually black) */
326             memset(pixels, 0,
327                 s->frame.linesize[0] * s->avctx->height);
328             break;
329
330         case FLI_BRUN:
331             /* Byte run compression: This chunk type only occurs in the first
332              * FLI frame and it will update the entire frame. */
333             y_ptr = 0;
334             for (lines = 0; lines < s->avctx->height; lines++) {
335                 pixel_ptr = y_ptr;
336                 /* disregard the line packets; instead, iterate through all
337                  * pixels on a row */
338                 stream_ptr++;
339                 pixel_countdown = s->avctx->width;
340                 while (pixel_countdown > 0) {
341                     byte_run = buf[stream_ptr++];
342                     if (byte_run > 0) {
343                         palette_idx1 = buf[stream_ptr++];
344                         CHECK_PIXEL_PTR(byte_run);
345                         for (j = 0; j < byte_run; j++) {
346                             pixels[pixel_ptr++] = palette_idx1;
347                             pixel_countdown--;
348                             if (pixel_countdown < 0)
349                                 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
350                                        pixel_countdown);
351                         }
352                     } else {  /* copy bytes if byte_run < 0 */
353                         byte_run = -byte_run;
354                         CHECK_PIXEL_PTR(byte_run);
355                         for (j = 0; j < byte_run; j++) {
356                             palette_idx1 = buf[stream_ptr++];
357                             pixels[pixel_ptr++] = palette_idx1;
358                             pixel_countdown--;
359                             if (pixel_countdown < 0)
360                                 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
361                                        pixel_countdown);
362                         }
363                     }
364                 }
365
366                 y_ptr += s->frame.linesize[0];
367             }
368             break;
369
370         case FLI_COPY:
371             /* copy the chunk (uncompressed frame) */
372             if (chunk_size - 6 > s->avctx->width * s->avctx->height) {
373                 av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
374                        "bigger than image, skipping chunk\n", chunk_size - 6);
375                 stream_ptr += chunk_size - 6;
376             } else {
377                 for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
378                      y_ptr += s->frame.linesize[0]) {
379                     memcpy(&pixels[y_ptr], &buf[stream_ptr],
380                         s->avctx->width);
381                     stream_ptr += s->avctx->width;
382                 }
383             }
384             break;
385
386         case FLI_MINI:
387             /* some sort of a thumbnail? disregard this chunk... */
388             stream_ptr += chunk_size - 6;
389             break;
390
391         default:
392             av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
393             break;
394         }
395
396         frame_size -= chunk_size;
397         num_chunks--;
398     }
399
400     /* by the end of the chunk, the stream ptr should equal the frame
401      * size (minus 1, possibly); if it doesn't, issue a warning */
402     if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1))
403         av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
404                "and final chunk ptr = %d\n", buf_size, stream_ptr);
405
406     /* make the palette available on the way out */
407 //    if (s->new_palette) {
408     if (1) {
409         memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
410         s->frame.palette_has_changed = 1;
411         s->new_palette = 0;
412     }
413
414     *data_size=sizeof(AVFrame);
415     *(AVFrame*)data = s->frame;
416
417     return buf_size;
418 }
419
420 static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
421                                       void *data, int *data_size,
422                                       uint8_t *buf, int buf_size)
423 {
424     /* Note, the only difference between the 15Bpp and 16Bpp */
425     /* Format is the pixel format, the packets are processed the same. */
426     FlicDecodeContext *s = (FlicDecodeContext *)avctx->priv_data;
427
428     int stream_ptr = 0;
429     int pixel_ptr;
430     unsigned char palette_idx1;
431
432     unsigned int frame_size;
433     int num_chunks;
434
435     unsigned int chunk_size;
436     int chunk_type;
437
438     int i, j;
439
440     int lines;
441     int compressed_lines;
442     signed short line_packets;
443     int y_ptr;
444     signed char byte_run;
445     int pixel_skip;
446     int pixel_countdown;
447     unsigned char *pixels;
448     int pixel;
449     int pixel_limit;
450
451     s->frame.reference = 1;
452     s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
453     if (avctx->reget_buffer(avctx, &s->frame) < 0) {
454         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
455         return -1;
456     }
457
458     pixels = s->frame.data[0];
459     pixel_limit = s->avctx->height * s->frame.linesize[0];
460
461     frame_size = LE_32(&buf[stream_ptr]);
462     stream_ptr += 6;  /* skip the magic number */
463     num_chunks = LE_16(&buf[stream_ptr]);
464     stream_ptr += 10;  /* skip padding */
465
466     frame_size -= 16;
467
468     /* iterate through the chunks */
469     while ((frame_size > 0) && (num_chunks > 0)) {
470         chunk_size = LE_32(&buf[stream_ptr]);
471         stream_ptr += 4;
472         chunk_type = LE_16(&buf[stream_ptr]);
473         stream_ptr += 2;
474
475         switch (chunk_type) {
476         case FLI_256_COLOR:
477         case FLI_COLOR:
478             /* For some reason, it seems that non-paletised flics do include one of these */
479             /* chunks in their first frame.  Why i do not know, it seems rather extraneous */
480 /*            av_log(avctx, AV_LOG_ERROR, "Unexpected Palette chunk %d in non-paletised FLC\n",chunk_type);*/
481             stream_ptr = stream_ptr + chunk_size - 6;
482             break;
483
484         case FLI_DELTA:
485         case FLI_DTA_LC:
486             y_ptr = 0;
487             compressed_lines = LE_16(&buf[stream_ptr]);
488             stream_ptr += 2;
489             while (compressed_lines > 0) {
490                 line_packets = LE_16(&buf[stream_ptr]);
491                 stream_ptr += 2;
492                 if (line_packets < 0) {
493                     line_packets = -line_packets;
494                     y_ptr += line_packets * s->frame.linesize[0];
495                 } else {
496                     compressed_lines--;
497                     pixel_ptr = y_ptr;
498                     pixel_countdown = s->avctx->width;
499                     for (i = 0; i < line_packets; i++) {
500                         /* account for the skip bytes */
501                         pixel_skip = buf[stream_ptr++];
502                         pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */
503                         pixel_countdown -= pixel_skip;
504                         byte_run = buf[stream_ptr++];
505                         if (byte_run < 0) {
506                             byte_run = -byte_run;
507                             pixel    = LE_16(&buf[stream_ptr]);
508                             stream_ptr += 2;
509                             CHECK_PIXEL_PTR(byte_run);
510                             for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
511                                 *((signed short*)(&pixels[pixel_ptr])) = pixel;
512                                 pixel_ptr += 2;
513                             }
514                         } else {
515                             CHECK_PIXEL_PTR(byte_run);
516                             for (j = 0; j < byte_run; j++, pixel_countdown--) {
517                                 *((signed short*)(&pixels[pixel_ptr])) = LE_16(&buf[stream_ptr]);
518                                 stream_ptr += 2;
519                                 pixel_ptr += 2;
520                             }
521                         }
522                     }
523
524                     y_ptr += s->frame.linesize[0];
525                 }
526             }
527             break;
528
529         case FLI_LC:
530             av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-paletised FLC\n");
531             stream_ptr = stream_ptr + chunk_size - 6;
532             break;
533
534         case FLI_BLACK:
535             /* set the whole frame to 0x0000 which is balck in both 15Bpp and 16Bpp modes. */
536             memset(pixels, 0x0000,
537                    s->frame.linesize[0] * s->avctx->height * 2);
538             break;
539
540         case FLI_BRUN:
541             y_ptr = 0;
542             for (lines = 0; lines < s->avctx->height; lines++) {
543                 pixel_ptr = y_ptr;
544                 /* disregard the line packets; instead, iterate through all
545                  * pixels on a row */
546                 stream_ptr++;
547                 pixel_countdown = (s->avctx->width * 2);
548
549                 while (pixel_countdown > 0) {
550                     byte_run = buf[stream_ptr++];
551                     if (byte_run > 0) {
552                         palette_idx1 = buf[stream_ptr++];
553                         CHECK_PIXEL_PTR(byte_run);
554                         for (j = 0; j < byte_run; j++) {
555                             pixels[pixel_ptr++] = palette_idx1;
556                             pixel_countdown--;
557                             if (pixel_countdown < 0)
558                                 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
559                                        pixel_countdown);
560                         }
561                     } else {  /* copy bytes if byte_run < 0 */
562                         byte_run = -byte_run;
563                         CHECK_PIXEL_PTR(byte_run);
564                         for (j = 0; j < byte_run; j++) {
565                             palette_idx1 = buf[stream_ptr++];
566                             pixels[pixel_ptr++] = palette_idx1;
567                             pixel_countdown--;
568                             if (pixel_countdown < 0)
569                                 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
570                                        pixel_countdown);
571                         }
572                     }
573                 }
574
575                 /* Now FLX is strange, in that it is "byte" as opposed to "pixel" run length compressed.
576                  * This doesnt give us any good oportunity to perform word endian conversion
577                  * during decompression. So if its requried (ie, this isnt a LE target, we do
578                  * a second pass over the line here, swapping the bytes.
579                  */
580                 pixel = 0xFF00;
581                 if (0xFF00 != LE_16(&pixel)) /* Check if its not an LE Target */
582                 {
583                   pixel_ptr = y_ptr;
584                   pixel_countdown = s->avctx->width;
585                   while (pixel_countdown > 0) {
586                     *((signed short*)(&pixels[pixel_ptr])) = LE_16(&buf[pixel_ptr]);
587                     pixel_ptr += 2;
588                   }
589                 }
590                 y_ptr += s->frame.linesize[0];
591             }
592             break;
593
594         case FLI_DTA_BRUN:
595             y_ptr = 0;
596             for (lines = 0; lines < s->avctx->height; lines++) {
597                 pixel_ptr = y_ptr;
598                 /* disregard the line packets; instead, iterate through all
599                  * pixels on a row */
600                 stream_ptr++;
601                 pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */
602
603                 while (pixel_countdown > 0) {
604                     byte_run = buf[stream_ptr++];
605                     if (byte_run > 0) {
606                         pixel    = LE_16(&buf[stream_ptr]);
607                         stream_ptr += 2;
608                         CHECK_PIXEL_PTR(byte_run);
609                         for (j = 0; j < byte_run; j++) {
610                             *((signed short*)(&pixels[pixel_ptr])) = pixel;
611                             pixel_ptr += 2;
612                             pixel_countdown--;
613                             if (pixel_countdown < 0)
614                                 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
615                                        pixel_countdown);
616                         }
617                     } else {  /* copy pixels if byte_run < 0 */
618                         byte_run = -byte_run;
619                         CHECK_PIXEL_PTR(byte_run);
620                         for (j = 0; j < byte_run; j++) {
621                             *((signed short*)(&pixels[pixel_ptr])) = LE_16(&buf[stream_ptr]);
622                             stream_ptr += 2;
623                             pixel_ptr  += 2;
624                             pixel_countdown--;
625                             if (pixel_countdown < 0)
626                                 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
627                                        pixel_countdown);
628                         }
629                     }
630                 }
631
632                 y_ptr += s->frame.linesize[0];
633             }
634             break;
635
636         case FLI_COPY:
637         case FLI_DTA_COPY:
638             /* copy the chunk (uncompressed frame) */
639             if (chunk_size - 6 > (unsigned int)(s->avctx->width * s->avctx->height)*2) {
640                 av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
641                        "bigger than image, skipping chunk\n", chunk_size - 6);
642                 stream_ptr += chunk_size - 6;
643             } else {
644
645                 for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
646                      y_ptr += s->frame.linesize[0]) {
647
648                     pixel_countdown = s->avctx->width;
649                     pixel_ptr = 0;
650                     while (pixel_countdown > 0) {
651                       *((signed short*)(&pixels[y_ptr + pixel_ptr])) = LE_16(&buf[stream_ptr+pixel_ptr]);
652                       pixel_ptr += 2;
653                       pixel_countdown--;
654                     }
655                     stream_ptr += s->avctx->width*2;
656                 }
657             }
658             break;
659
660         case FLI_MINI:
661             /* some sort of a thumbnail? disregard this chunk... */
662             stream_ptr += chunk_size - 6;
663             break;
664
665         default:
666             av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
667             break;
668         }
669
670         frame_size -= chunk_size;
671         num_chunks--;
672     }
673
674     /* by the end of the chunk, the stream ptr should equal the frame
675      * size (minus 1, possibly); if it doesn't, issue a warning */
676     if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1))
677         av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
678                "and final chunk ptr = %d\n", buf_size, stream_ptr);
679
680
681     *data_size=sizeof(AVFrame);
682     *(AVFrame*)data = s->frame;
683
684     return buf_size;
685 }
686
687 static int flic_decode_frame_24BPP(AVCodecContext *avctx,
688                                    void *data, int *data_size,
689                                    uint8_t *buf, int buf_size)
690 {
691   av_log(avctx, AV_LOG_ERROR, "24Bpp FLC Unsupported due to lack of test files.\n");
692   return -1;
693 }
694
695 static int flic_decode_frame(AVCodecContext *avctx,
696                              void *data, int *data_size,
697                              uint8_t *buf, int buf_size)
698 {
699     if (avctx->pix_fmt == PIX_FMT_PAL8) {
700       return flic_decode_frame_8BPP(avctx, data, data_size,
701                                     buf, buf_size);
702     }
703     else if ((avctx->pix_fmt == PIX_FMT_RGB555) ||
704              (avctx->pix_fmt == PIX_FMT_RGB565)) {
705       return flic_decode_frame_15_16BPP(avctx, data, data_size,
706                                         buf, buf_size);
707     }
708     else if (avctx->pix_fmt == PIX_FMT_BGR24) {
709       return flic_decode_frame_24BPP(avctx, data, data_size,
710                                      buf, buf_size);
711     }
712
713     /* Shouldnt get  here, ever as the pix_fmt is processed */
714     /* in flic_decode_init and the above if should deal with */
715     /* the finite set of possibilites allowable by here. */
716     /* but in case we do, just error out. */
717     av_log(avctx, AV_LOG_ERROR, "Unknown Format of FLC. My Science cant explain how this happened\n");
718     return -1;
719 }
720
721
722 static int flic_decode_end(AVCodecContext *avctx)
723 {
724     FlicDecodeContext *s = avctx->priv_data;
725
726     if (s->frame.data[0])
727         avctx->release_buffer(avctx, &s->frame);
728
729     return 0;
730 }
731
732 AVCodec flic_decoder = {
733     "flic",
734     CODEC_TYPE_VIDEO,
735     CODEC_ID_FLIC,
736     sizeof(FlicDecodeContext),
737     flic_decode_init,
738     NULL,
739     flic_decode_end,
740     flic_decode_frame,
741     CODEC_CAP_DR1,
742     NULL,
743     NULL,
744     NULL,
745     NULL
746 };