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