Statistics
| Branch: | Revision:

ffmpeg / libavcodec / flicvideo.c @ 2912e87a

History | View | Annotate | Download (28.3 KB)

1
/*
2
 * FLI/FLC Animation Video Decoder
3
 * Copyright (C) 2003, 2004 the ffmpeg project
4
 *
5
 * This file is part of Libav.
6
 *
7
 * Libav 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
 * Libav 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 Libav; 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_INFO, "Problem: pixel_ptr >= pixel_limit (%d >= %d)\n", \
65
        pixel_ptr + n, pixel_limit); \
66
        return -1; \
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
                  break;
116
        default :
117
                  av_log(avctx, AV_LOG_ERROR, "Unknown FLC/FLX depth of %d Bpp is unsupported.\n",depth);
118
                  return -1;
119
    }
120

    
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 stream_ptr_after_color_chunk;
135
    int pixel_ptr;
136
    int palette_ptr;
137
    unsigned char palette_idx1;
138
    unsigned char palette_idx2;
139

    
140
    unsigned int frame_size;
141
    int num_chunks;
142

    
143
    unsigned int chunk_size;
144
    int chunk_type;
145

    
146
    int i, j;
147

    
148
    int color_packets;
149
    int color_changes;
150
    int color_shift;
151
    unsigned char r, g, b;
152

    
153
    int lines;
154
    int compressed_lines;
155
    int starting_line;
156
    signed short line_packets;
157
    int y_ptr;
158
    int byte_run;
159
    int pixel_skip;
160
    int pixel_countdown;
161
    unsigned char *pixels;
162
    unsigned int pixel_limit;
163

    
164
    s->frame.reference = 1;
165
    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
166
    if (avctx->reget_buffer(avctx, &s->frame) < 0) {
167
        av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
168
        return -1;
169
    }
170

    
171
    pixels = s->frame.data[0];
172
    pixel_limit = s->avctx->height * s->frame.linesize[0];
173

    
174
    frame_size = AV_RL32(&buf[stream_ptr]);
175
    stream_ptr += 6;  /* skip the magic number */
176
    num_chunks = AV_RL16(&buf[stream_ptr]);
177
    stream_ptr += 10;  /* skip padding */
178

    
179
    frame_size -= 16;
180

    
181
    /* iterate through the chunks */
182
    while ((frame_size > 0) && (num_chunks > 0)) {
183
        chunk_size = AV_RL32(&buf[stream_ptr]);
184
        stream_ptr += 4;
185
        chunk_type = AV_RL16(&buf[stream_ptr]);
186
        stream_ptr += 2;
187

    
188
        switch (chunk_type) {
189
        case FLI_256_COLOR:
190
        case FLI_COLOR:
191
            stream_ptr_after_color_chunk = stream_ptr + chunk_size - 6;
192

    
193
            /* check special case: If this file is from the Magic Carpet
194
             * game and uses 6-bit colors even though it reports 256-color
195
             * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during
196
             * initialization) */
197
            if ((chunk_type == FLI_256_COLOR) && (s->fli_type != FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE))
198
                color_shift = 0;
199
            else
200
                color_shift = 2;
201
            /* set up the palette */
202
            color_packets = AV_RL16(&buf[stream_ptr]);
203
            stream_ptr += 2;
204
            palette_ptr = 0;
205
            for (i = 0; i < color_packets; i++) {
206
                /* first byte is how many colors to skip */
207
                palette_ptr += buf[stream_ptr++];
208

    
209
                /* next byte indicates how many entries to change */
210
                color_changes = buf[stream_ptr++];
211

    
212
                /* if there are 0 color changes, there are actually 256 */
213
                if (color_changes == 0)
214
                    color_changes = 256;
215

    
216
                for (j = 0; j < color_changes; j++) {
217
                    unsigned int entry;
218

    
219
                    /* wrap around, for good measure */
220
                    if ((unsigned)palette_ptr >= 256)
221
                        palette_ptr = 0;
222

    
223
                    r = buf[stream_ptr++] << color_shift;
224
                    g = buf[stream_ptr++] << color_shift;
225
                    b = buf[stream_ptr++] << color_shift;
226
                    entry = (r << 16) | (g << 8) | b;
227
                    if (s->palette[palette_ptr] != entry)
228
                        s->new_palette = 1;
229
                    s->palette[palette_ptr++] = entry;
230
                }
231
            }
232

    
233
            /* color chunks sometimes have weird 16-bit alignment issues;
234
             * therefore, take the hardline approach and set the stream_ptr
235
             * to the value calculated w.r.t. the size specified by the color
236
             * chunk header */
237
            stream_ptr = stream_ptr_after_color_chunk;
238

    
239
            break;
240

    
241
        case FLI_DELTA:
242
            y_ptr = 0;
243
            compressed_lines = AV_RL16(&buf[stream_ptr]);
244
            stream_ptr += 2;
245
            while (compressed_lines > 0) {
246
                line_packets = AV_RL16(&buf[stream_ptr]);
247
                stream_ptr += 2;
248
                if ((line_packets & 0xC000) == 0xC000) {
249
                    // line skip opcode
250
                    line_packets = -line_packets;
251
                    y_ptr += line_packets * s->frame.linesize[0];
252
                } else if ((line_packets & 0xC000) == 0x4000) {
253
                    av_log(avctx, AV_LOG_ERROR, "Undefined opcode (%x) in DELTA_FLI\n", line_packets);
254
                } else if ((line_packets & 0xC000) == 0x8000) {
255
                    // "last byte" opcode
256
                    pixel_ptr= y_ptr + s->frame.linesize[0] - 1;
257
                    CHECK_PIXEL_PTR(0);
258
                    pixels[pixel_ptr] = line_packets & 0xff;
259
                } else {
260
                    compressed_lines--;
261
                    pixel_ptr = y_ptr;
262
                    CHECK_PIXEL_PTR(0);
263
                    pixel_countdown = s->avctx->width;
264
                    for (i = 0; i < line_packets; i++) {
265
                        /* account for the skip bytes */
266
                        pixel_skip = buf[stream_ptr++];
267
                        pixel_ptr += pixel_skip;
268
                        pixel_countdown -= pixel_skip;
269
                        byte_run = (signed char)(buf[stream_ptr++]);
270
                        if (byte_run < 0) {
271
                            byte_run = -byte_run;
272
                            palette_idx1 = buf[stream_ptr++];
273
                            palette_idx2 = buf[stream_ptr++];
274
                            CHECK_PIXEL_PTR(byte_run * 2);
275
                            for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
276
                                pixels[pixel_ptr++] = palette_idx1;
277
                                pixels[pixel_ptr++] = palette_idx2;
278
                            }
279
                        } else {
280
                            CHECK_PIXEL_PTR(byte_run * 2);
281
                            for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
282
                                palette_idx1 = buf[stream_ptr++];
283
                                pixels[pixel_ptr++] = palette_idx1;
284
                            }
285
                        }
286
                    }
287

    
288
                    y_ptr += s->frame.linesize[0];
289
                }
290
            }
291
            break;
292

    
293
        case FLI_LC:
294
            /* line compressed */
295
            starting_line = AV_RL16(&buf[stream_ptr]);
296
            stream_ptr += 2;
297
            y_ptr = 0;
298
            y_ptr += starting_line * s->frame.linesize[0];
299

    
300
            compressed_lines = AV_RL16(&buf[stream_ptr]);
301
            stream_ptr += 2;
302
            while (compressed_lines > 0) {
303
                pixel_ptr = y_ptr;
304
                CHECK_PIXEL_PTR(0);
305
                pixel_countdown = s->avctx->width;
306
                line_packets = buf[stream_ptr++];
307
                if (line_packets > 0) {
308
                    for (i = 0; i < line_packets; i++) {
309
                        /* account for the skip bytes */
310
                        pixel_skip = buf[stream_ptr++];
311
                        pixel_ptr += pixel_skip;
312
                        pixel_countdown -= pixel_skip;
313
                        byte_run = (signed char)(buf[stream_ptr++]);
314
                        if (byte_run > 0) {
315
                            CHECK_PIXEL_PTR(byte_run);
316
                            for (j = 0; j < byte_run; j++, pixel_countdown--) {
317
                                palette_idx1 = buf[stream_ptr++];
318
                                pixels[pixel_ptr++] = palette_idx1;
319
                            }
320
                        } else if (byte_run < 0) {
321
                            byte_run = -byte_run;
322
                            palette_idx1 = buf[stream_ptr++];
323
                            CHECK_PIXEL_PTR(byte_run);
324
                            for (j = 0; j < byte_run; j++, pixel_countdown--) {
325
                                pixels[pixel_ptr++] = palette_idx1;
326
                            }
327
                        }
328
                    }
329
                }
330

    
331
                y_ptr += s->frame.linesize[0];
332
                compressed_lines--;
333
            }
334
            break;
335

    
336
        case FLI_BLACK:
337
            /* set the whole frame to color 0 (which is usually black) */
338
            memset(pixels, 0,
339
                s->frame.linesize[0] * s->avctx->height);
340
            break;
341

    
342
        case FLI_BRUN:
343
            /* Byte run compression: This chunk type only occurs in the first
344
             * FLI frame and it will update the entire frame. */
345
            y_ptr = 0;
346
            for (lines = 0; lines < s->avctx->height; lines++) {
347
                pixel_ptr = y_ptr;
348
                /* disregard the line packets; instead, iterate through all
349
                 * pixels on a row */
350
                stream_ptr++;
351
                pixel_countdown = s->avctx->width;
352
                while (pixel_countdown > 0) {
353
                    byte_run = (signed char)(buf[stream_ptr++]);
354
                    if (byte_run > 0) {
355
                        palette_idx1 = buf[stream_ptr++];
356
                        CHECK_PIXEL_PTR(byte_run);
357
                        for (j = 0; j < byte_run; j++) {
358
                            pixels[pixel_ptr++] = palette_idx1;
359
                            pixel_countdown--;
360
                            if (pixel_countdown < 0)
361
                                av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
362
                                       pixel_countdown, lines);
363
                        }
364
                    } else {  /* copy bytes if byte_run < 0 */
365
                        byte_run = -byte_run;
366
                        CHECK_PIXEL_PTR(byte_run);
367
                        for (j = 0; j < byte_run; j++) {
368
                            palette_idx1 = buf[stream_ptr++];
369
                            pixels[pixel_ptr++] = palette_idx1;
370
                            pixel_countdown--;
371
                            if (pixel_countdown < 0)
372
                                av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
373
                                       pixel_countdown, lines);
374
                        }
375
                    }
376
                }
377

    
378
                y_ptr += s->frame.linesize[0];
379
            }
380
            break;
381

    
382
        case FLI_COPY:
383
            /* copy the chunk (uncompressed frame) */
384
            if (chunk_size - 6 > s->avctx->width * s->avctx->height) {
385
                av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
386
                       "bigger than image, skipping chunk\n", chunk_size - 6);
387
                stream_ptr += chunk_size - 6;
388
            } else {
389
                for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
390
                     y_ptr += s->frame.linesize[0]) {
391
                    memcpy(&pixels[y_ptr], &buf[stream_ptr],
392
                        s->avctx->width);
393
                    stream_ptr += s->avctx->width;
394
                }
395
            }
396
            break;
397

    
398
        case FLI_MINI:
399
            /* some sort of a thumbnail? disregard this chunk... */
400
            stream_ptr += chunk_size - 6;
401
            break;
402

    
403
        default:
404
            av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
405
            break;
406
        }
407

    
408
        frame_size -= chunk_size;
409
        num_chunks--;
410
    }
411

    
412
    /* by the end of the chunk, the stream ptr should equal the frame
413
     * size (minus 1, possibly); if it doesn't, issue a warning */
414
    if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1))
415
        av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
416
               "and final chunk ptr = %d\n", buf_size, stream_ptr);
417

    
418
    /* make the palette available on the way out */
419
    memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
420
    if (s->new_palette) {
421
        s->frame.palette_has_changed = 1;
422
        s->new_palette = 0;
423
    }
424

    
425
    *data_size=sizeof(AVFrame);
426
    *(AVFrame*)data = s->frame;
427

    
428
    return buf_size;
429
}
430

    
431
static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
432
                                      void *data, int *data_size,
433
                                      const uint8_t *buf, int buf_size)
434
{
435
    /* Note, the only difference between the 15Bpp and 16Bpp */
436
    /* Format is the pixel format, the packets are processed the same. */
437
    FlicDecodeContext *s = avctx->priv_data;
438

    
439
    int stream_ptr = 0;
440
    int pixel_ptr;
441
    unsigned char palette_idx1;
442

    
443
    unsigned int frame_size;
444
    int num_chunks;
445

    
446
    unsigned int chunk_size;
447
    int chunk_type;
448

    
449
    int i, j;
450

    
451
    int lines;
452
    int compressed_lines;
453
    signed short line_packets;
454
    int y_ptr;
455
    int byte_run;
456
    int pixel_skip;
457
    int pixel_countdown;
458
    unsigned char *pixels;
459
    int pixel;
460
    unsigned int pixel_limit;
461

    
462
    s->frame.reference = 1;
463
    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
464
    if (avctx->reget_buffer(avctx, &s->frame) < 0) {
465
        av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
466
        return -1;
467
    }
468

    
469
    pixels = s->frame.data[0];
470
    pixel_limit = s->avctx->height * s->frame.linesize[0];
471

    
472
    frame_size = AV_RL32(&buf[stream_ptr]);
473
    stream_ptr += 6;  /* skip the magic number */
474
    num_chunks = AV_RL16(&buf[stream_ptr]);
475
    stream_ptr += 10;  /* skip padding */
476

    
477
    frame_size -= 16;
478

    
479
    /* iterate through the chunks */
480
    while ((frame_size > 0) && (num_chunks > 0)) {
481
        chunk_size = AV_RL32(&buf[stream_ptr]);
482
        stream_ptr += 4;
483
        chunk_type = AV_RL16(&buf[stream_ptr]);
484
        stream_ptr += 2;
485

    
486
        switch (chunk_type) {
487
        case FLI_256_COLOR:
488
        case FLI_COLOR:
489
            /* For some reason, it seems that non-palettized flics do
490
             * include one of these chunks in their first frame.
491
             * Why I do not know, it seems rather extraneous. */
492
/*            av_log(avctx, AV_LOG_ERROR, "Unexpected Palette chunk %d in non-paletised FLC\n",chunk_type);*/
493
            stream_ptr = stream_ptr + chunk_size - 6;
494
            break;
495

    
496
        case FLI_DELTA:
497
        case FLI_DTA_LC:
498
            y_ptr = 0;
499
            compressed_lines = AV_RL16(&buf[stream_ptr]);
500
            stream_ptr += 2;
501
            while (compressed_lines > 0) {
502
                line_packets = AV_RL16(&buf[stream_ptr]);
503
                stream_ptr += 2;
504
                if (line_packets < 0) {
505
                    line_packets = -line_packets;
506
                    y_ptr += line_packets * s->frame.linesize[0];
507
                } else {
508
                    compressed_lines--;
509
                    pixel_ptr = y_ptr;
510
                    CHECK_PIXEL_PTR(0);
511
                    pixel_countdown = s->avctx->width;
512
                    for (i = 0; i < line_packets; i++) {
513
                        /* account for the skip bytes */
514
                        pixel_skip = buf[stream_ptr++];
515
                        pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */
516
                        pixel_countdown -= pixel_skip;
517
                        byte_run = (signed char)(buf[stream_ptr++]);
518
                        if (byte_run < 0) {
519
                            byte_run = -byte_run;
520
                            pixel    = AV_RL16(&buf[stream_ptr]);
521
                            stream_ptr += 2;
522
                            CHECK_PIXEL_PTR(2 * byte_run);
523
                            for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
524
                                *((signed short*)(&pixels[pixel_ptr])) = pixel;
525
                                pixel_ptr += 2;
526
                            }
527
                        } else {
528
                            CHECK_PIXEL_PTR(2 * byte_run);
529
                            for (j = 0; j < byte_run; j++, pixel_countdown--) {
530
                                *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[stream_ptr]);
531
                                stream_ptr += 2;
532
                                pixel_ptr += 2;
533
                            }
534
                        }
535
                    }
536

    
537
                    y_ptr += s->frame.linesize[0];
538
                }
539
            }
540
            break;
541

    
542
        case FLI_LC:
543
            av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-paletised FLC\n");
544
            stream_ptr = stream_ptr + chunk_size - 6;
545
            break;
546

    
547
        case FLI_BLACK:
548
            /* set the whole frame to 0x0000 which is black in both 15Bpp and 16Bpp modes. */
549
            memset(pixels, 0x0000,
550
                   s->frame.linesize[0] * s->avctx->height);
551
            break;
552

    
553
        case FLI_BRUN:
554
            y_ptr = 0;
555
            for (lines = 0; lines < s->avctx->height; lines++) {
556
                pixel_ptr = y_ptr;
557
                /* disregard the line packets; instead, iterate through all
558
                 * pixels on a row */
559
                stream_ptr++;
560
                pixel_countdown = (s->avctx->width * 2);
561

    
562
                while (pixel_countdown > 0) {
563
                    byte_run = (signed char)(buf[stream_ptr++]);
564
                    if (byte_run > 0) {
565
                        palette_idx1 = buf[stream_ptr++];
566
                        CHECK_PIXEL_PTR(byte_run);
567
                        for (j = 0; j < byte_run; j++) {
568
                            pixels[pixel_ptr++] = palette_idx1;
569
                            pixel_countdown--;
570
                            if (pixel_countdown < 0)
571
                                av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) (linea%d)\n",
572
                                       pixel_countdown, lines);
573
                        }
574
                    } else {  /* copy bytes if byte_run < 0 */
575
                        byte_run = -byte_run;
576
                        CHECK_PIXEL_PTR(byte_run);
577
                        for (j = 0; j < byte_run; j++) {
578
                            palette_idx1 = buf[stream_ptr++];
579
                            pixels[pixel_ptr++] = palette_idx1;
580
                            pixel_countdown--;
581
                            if (pixel_countdown < 0)
582
                                av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
583
                                       pixel_countdown, lines);
584
                        }
585
                    }
586
                }
587

    
588
                /* Now FLX is strange, in that it is "byte" as opposed to "pixel" run length compressed.
589
                 * This does not give us any good oportunity to perform word endian conversion
590
                 * during decompression. So if it is required (i.e., this is not a LE target, we do
591
                 * a second pass over the line here, swapping the bytes.
592
                 */
593
#if HAVE_BIGENDIAN
594
                pixel_ptr = y_ptr;
595
                pixel_countdown = s->avctx->width;
596
                while (pixel_countdown > 0) {
597
                    *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[pixel_ptr]);
598
                    pixel_ptr += 2;
599
                }
600
#endif
601
                y_ptr += s->frame.linesize[0];
602
            }
603
            break;
604

    
605
        case FLI_DTA_BRUN:
606
            y_ptr = 0;
607
            for (lines = 0; lines < s->avctx->height; lines++) {
608
                pixel_ptr = y_ptr;
609
                /* disregard the line packets; instead, iterate through all
610
                 * pixels on a row */
611
                stream_ptr++;
612
                pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */
613

    
614
                while (pixel_countdown > 0) {
615
                    byte_run = (signed char)(buf[stream_ptr++]);
616
                    if (byte_run > 0) {
617
                        pixel    = AV_RL16(&buf[stream_ptr]);
618
                        stream_ptr += 2;
619
                        CHECK_PIXEL_PTR(2 * byte_run);
620
                        for (j = 0; j < byte_run; j++) {
621
                            *((signed short*)(&pixels[pixel_ptr])) = pixel;
622
                            pixel_ptr += 2;
623
                            pixel_countdown--;
624
                            if (pixel_countdown < 0)
625
                                av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
626
                                       pixel_countdown);
627
                        }
628
                    } else {  /* copy pixels if byte_run < 0 */
629
                        byte_run = -byte_run;
630
                        CHECK_PIXEL_PTR(2 * byte_run);
631
                        for (j = 0; j < byte_run; j++) {
632
                            *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[stream_ptr]);
633
                            stream_ptr += 2;
634
                            pixel_ptr  += 2;
635
                            pixel_countdown--;
636
                            if (pixel_countdown < 0)
637
                                av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
638
                                       pixel_countdown);
639
                        }
640
                    }
641
                }
642

    
643
                y_ptr += s->frame.linesize[0];
644
            }
645
            break;
646

    
647
        case FLI_COPY:
648
        case FLI_DTA_COPY:
649
            /* copy the chunk (uncompressed frame) */
650
            if (chunk_size - 6 > (unsigned int)(s->avctx->width * s->avctx->height)*2) {
651
                av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
652
                       "bigger than image, skipping chunk\n", chunk_size - 6);
653
                stream_ptr += chunk_size - 6;
654
            } else {
655

    
656
                for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
657
                     y_ptr += s->frame.linesize[0]) {
658

    
659
                    pixel_countdown = s->avctx->width;
660
                    pixel_ptr = 0;
661
                    while (pixel_countdown > 0) {
662
                      *((signed short*)(&pixels[y_ptr + pixel_ptr])) = AV_RL16(&buf[stream_ptr+pixel_ptr]);
663
                      pixel_ptr += 2;
664
                      pixel_countdown--;
665
                    }
666
                    stream_ptr += s->avctx->width*2;
667
                }
668
            }
669
            break;
670

    
671
        case FLI_MINI:
672
            /* some sort of a thumbnail? disregard this chunk... */
673
            stream_ptr += chunk_size - 6;
674
            break;
675

    
676
        default:
677
            av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
678
            break;
679
        }
680

    
681
        frame_size -= chunk_size;
682
        num_chunks--;
683
    }
684

    
685
    /* by the end of the chunk, the stream ptr should equal the frame
686
     * size (minus 1, possibly); if it doesn't, issue a warning */
687
    if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1))
688
        av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
689
               "and final chunk ptr = %d\n", buf_size, stream_ptr);
690

    
691

    
692
    *data_size=sizeof(AVFrame);
693
    *(AVFrame*)data = s->frame;
694

    
695
    return buf_size;
696
}
697

    
698
static int flic_decode_frame_24BPP(AVCodecContext *avctx,
699
                                   void *data, int *data_size,
700
                                   const uint8_t *buf, int buf_size)
701
{
702
  av_log(avctx, AV_LOG_ERROR, "24Bpp FLC Unsupported due to lack of test files.\n");
703
  return -1;
704
}
705

    
706
static int flic_decode_frame(AVCodecContext *avctx,
707
                             void *data, int *data_size,
708
                             AVPacket *avpkt)
709
{
710
    const uint8_t *buf = avpkt->data;
711
    int buf_size = avpkt->size;
712
    if (avctx->pix_fmt == PIX_FMT_PAL8) {
713
      return flic_decode_frame_8BPP(avctx, data, data_size,
714
                                    buf, buf_size);
715
    }
716
    else if ((avctx->pix_fmt == PIX_FMT_RGB555) ||
717
             (avctx->pix_fmt == PIX_FMT_RGB565)) {
718
      return flic_decode_frame_15_16BPP(avctx, data, data_size,
719
                                        buf, buf_size);
720
    }
721
    else if (avctx->pix_fmt == PIX_FMT_BGR24) {
722
      return flic_decode_frame_24BPP(avctx, data, data_size,
723
                                     buf, buf_size);
724
    }
725

    
726
    /* Should not get  here, ever as the pix_fmt is processed */
727
    /* in flic_decode_init and the above if should deal with */
728
    /* the finite set of possibilites allowable by here. */
729
    /* But in case we do, just error out. */
730
    av_log(avctx, AV_LOG_ERROR, "Unknown FLC format, my science cannot explain how this happened.\n");
731
    return -1;
732
}
733

    
734

    
735
static av_cold int flic_decode_end(AVCodecContext *avctx)
736
{
737
    FlicDecodeContext *s = avctx->priv_data;
738

    
739
    if (s->frame.data[0])
740
        avctx->release_buffer(avctx, &s->frame);
741

    
742
    return 0;
743
}
744

    
745
AVCodec ff_flic_decoder = {
746
    "flic",
747
    AVMEDIA_TYPE_VIDEO,
748
    CODEC_ID_FLIC,
749
    sizeof(FlicDecodeContext),
750
    flic_decode_init,
751
    NULL,
752
    flic_decode_end,
753
    flic_decode_frame,
754
    CODEC_CAP_DR1,
755
    NULL,
756
    NULL,
757
    NULL,
758
    NULL,
759
    .long_name = NULL_IF_CONFIG_SMALL("Autodesk Animator Flic video"),
760
};