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