Coverage Report

Created: 2024-09-06 07:53

/src/ffmpeg/libavcodec/flicvideo.c
Line
Count
Source (jump to first uncovered line)
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/BGR24. To use this decoder, be
31
 * sure that your demuxer sends the FLI file header to the decoder via
32
 * the extradata chunk in AVCodecContext. The chunk should be 128 bytes
33
 * large. The only exception is for FLI files from the game "Magic Carpet",
34
 * in which the header is only 12 bytes.
35
 */
36
37
#include <string.h>
38
39
#include "libavutil/intreadwrite.h"
40
#include "avcodec.h"
41
#include "bytestream.h"
42
#include "codec_internal.h"
43
#include "decode.h"
44
#include "mathops.h"
45
46
4.29k
#define FLI_256_COLOR 4
47
7.45k
#define FLI_DELTA     7
48
3.42k
#define FLI_COLOR     11
49
7.57k
#define FLI_LC        12
50
826
#define FLI_BLACK     13
51
4.36k
#define FLI_BRUN      15
52
2.90k
#define FLI_COPY      16
53
1.35k
#define FLI_MINI      18
54
1.84k
#define FLI_DTA_BRUN  25
55
2.08k
#define FLI_DTA_COPY  26
56
4.91k
#define FLI_DTA_LC    27
57
58
1.06k
#define FLI_TYPE_CODE     (0xAF11)
59
2.64k
#define FLC_FLX_TYPE_CODE (0xAF12)
60
#define FLC_DTA_TYPE_CODE (0xAF44) /* Marks an "Extended FLC" comes from Dave's Targa Animator (DTA) */
61
1.33k
#define FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE (0xAF13)
62
63
static inline int check_pixel_ptr(ptrdiff_t ptr, int n,
64
                                  ptrdiff_t limit, int direction)
65
8.96M
{
66
8.96M
    if (( direction && ptr + n > limit) ||
67
8.96M
        (!direction && ptr + n < limit))
68
8.31k
        return AVERROR_INVALIDDATA;
69
8.95M
    return 0;
70
8.96M
}
71
72
7.30M
#define CHECK_PIXEL_PTR(n) \
73
7.30M
{ \
74
7.30M
    ret = check_pixel_ptr(pixel_ptr, (n), pixel_limit, direction); \
75
7.30M
    if (ret < 0) \
76
7.30M
        return ret; \
77
7.30M
}
78
79
30.7k
#define CHECK_Y_PTR() \
80
30.7k
{ \
81
30.7k
    ret = check_pixel_ptr(y_ptr, 0, pixel_limit, direction); \
82
30.7k
    if (ret < 0) \
83
30.7k
        return ret; \
84
30.7k
}
85
86
typedef struct FlicDecodeContext {
87
    AVCodecContext *avctx;
88
    AVFrame *frame;
89
90
    unsigned int palette[256];
91
    int new_palette;
92
    int fli_type;  /* either 0xAF11 or 0xAF12, affects palette resolution */
93
} FlicDecodeContext;
94
95
static av_cold int flic_decode_init(AVCodecContext *avctx)
96
2.70k
{
97
2.70k
    FlicDecodeContext *s = avctx->priv_data;
98
2.70k
    uint8_t *fli_header = avctx->extradata;
99
2.70k
    int depth;
100
101
2.70k
    if (avctx->extradata_size != 0 &&
102
2.70k
        avctx->extradata_size != 12 &&
103
2.70k
        avctx->extradata_size != 128 &&
104
2.70k
        avctx->extradata_size != 256 &&
105
2.70k
        avctx->extradata_size != 904 &&
106
2.70k
        avctx->extradata_size != 1024) {
107
55
        av_log(avctx, AV_LOG_ERROR, "Unexpected extradata size %d\n", avctx->extradata_size);
108
55
        return AVERROR_INVALIDDATA;
109
55
    }
110
111
2.64k
    s->avctx = avctx;
112
113
2.64k
    if (s->avctx->extradata_size == 12) {
114
        /* special case for magic carpet FLIs */
115
8
        s->fli_type = FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE;
116
8
        depth = 8;
117
2.64k
    } else if (avctx->extradata_size == 1024) {
118
2
        uint8_t *ptr = avctx->extradata;
119
2
        int i;
120
121
514
        for (i = 0; i < 256; i++) {
122
512
            s->palette[i] = AV_RL32(ptr);
123
512
            ptr += 4;
124
512
        }
125
2
        depth = 8;
126
        /* FLI in MOV, see e.g. FFmpeg trac issue #626 */
127
2.63k
    } else if (avctx->extradata_size == 0 ||
128
2.63k
               avctx->extradata_size == 256 ||
129
        /* see FFmpeg ticket #1234 */
130
2.63k
               avctx->extradata_size == 904) {
131
1.06k
        s->fli_type = FLI_TYPE_CODE;
132
1.06k
        depth = 8;
133
1.57k
    } else {
134
1.57k
        s->fli_type = AV_RL16(&fli_header[4]);
135
1.57k
        depth = AV_RL16(&fli_header[12]);
136
1.57k
    }
137
138
2.64k
    if (depth == 0) {
139
109
        depth = 8; /* Some FLC generators set depth to zero, when they mean 8Bpp. Fix up here */
140
109
    }
141
142
2.64k
    if ((s->fli_type == FLC_FLX_TYPE_CODE) && (depth == 16)) {
143
1
        depth = 15; /* Original Autodesk FLX's say the depth is 16Bpp when it is really 15Bpp */
144
1
    }
145
146
2.64k
    switch (depth) {
147
354
        case 1  : avctx->pix_fmt = AV_PIX_FMT_MONOBLACK; break;
148
1.18k
        case 8  : avctx->pix_fmt = AV_PIX_FMT_PAL8; break;
149
139
        case 15 : avctx->pix_fmt = AV_PIX_FMT_RGB555; break;
150
419
        case 16 : avctx->pix_fmt = AV_PIX_FMT_RGB565; break;
151
543
        case 24 : avctx->pix_fmt = AV_PIX_FMT_BGR24; break;
152
9
        default :
153
9
                  av_log(avctx, AV_LOG_ERROR, "Unknown FLC/FLX depth of %d Bpp is unsupported.\n",depth);
154
9
                  return AVERROR_INVALIDDATA;
155
2.64k
    }
156
157
2.63k
    s->frame = av_frame_alloc();
158
2.63k
    if (!s->frame)
159
0
        return AVERROR(ENOMEM);
160
161
2.63k
    s->new_palette = 0;
162
163
2.63k
    return 0;
164
2.63k
}
165
166
static int flic_decode_frame_1BPP(AVCodecContext *avctx,
167
                                  AVFrame *rframe, int *got_frame,
168
                                  const uint8_t *buf, int buf_size)
169
9.03k
{
170
9.03k
    FlicDecodeContext *s = avctx->priv_data;
171
172
9.03k
    GetByteContext g2;
173
9.03k
    ptrdiff_t pixel_ptr;
174
175
9.03k
    unsigned int frame_size;
176
9.03k
    int num_chunks;
177
178
9.03k
    unsigned int chunk_size;
179
9.03k
    int chunk_type;
180
181
9.03k
    int i, j, ret, direction;
182
183
9.03k
    int lines;
184
9.03k
    int compressed_lines;
185
9.03k
    int starting_line;
186
9.03k
    int line_packets;
187
9.03k
    ptrdiff_t y_ptr;
188
9.03k
    int byte_run;
189
9.03k
    int pixel_skip;
190
9.03k
    int pixel_countdown;
191
9.03k
    unsigned char *pixels;
192
9.03k
    ptrdiff_t pixel_limit;
193
194
9.03k
    bytestream2_init(&g2, buf, buf_size);
195
196
9.03k
    if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
197
217
        return ret;
198
199
8.81k
    direction = s->frame->linesize[0] > 0;
200
8.81k
    pixels = s->frame->data[0];
201
8.81k
    pixel_limit = s->avctx->height * s->frame->linesize[0];
202
8.81k
    if (buf_size < 16 || buf_size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
203
714
        return AVERROR_INVALIDDATA;
204
8.10k
    frame_size = bytestream2_get_le32(&g2);
205
8.10k
    if (frame_size > buf_size)
206
7.83k
        frame_size = buf_size;
207
8.10k
    bytestream2_skip(&g2, 2); /* skip the magic number */
208
8.10k
    num_chunks = bytestream2_get_le16(&g2);
209
8.10k
    bytestream2_skip(&g2, 8);  /* skip padding */
210
211
8.10k
    if (frame_size < 16)
212
255
        return AVERROR_INVALIDDATA;
213
214
7.84k
    frame_size -= 16;
215
216
    /* iterate through the chunks */
217
11.3k
    while ((frame_size >= 6) && (num_chunks > 0) &&
218
11.3k
            bytestream2_get_bytes_left(&g2) >= 4) {
219
5.64k
        int stream_ptr_after_chunk;
220
5.64k
        chunk_size = bytestream2_get_le32(&g2);
221
5.64k
        if (chunk_size > frame_size) {
222
4.81k
            av_log(avctx, AV_LOG_WARNING,
223
4.81k
                   "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
224
4.81k
            chunk_size = frame_size;
225
4.81k
        }
226
5.64k
        stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
227
228
5.64k
        chunk_type = bytestream2_get_le16(&g2);
229
230
5.64k
        switch (chunk_type) {
231
1.29k
        case FLI_BRUN:
232
            /* Byte run compression: This chunk type only occurs in the first
233
             * FLI frame and it will update the entire frame. */
234
1.29k
            y_ptr = 0;
235
2.46M
            for (lines = 0; lines < s->avctx->height; lines++) {
236
2.46M
                pixel_ptr = y_ptr;
237
                /* disregard the line packets; instead, iterate through all
238
                 * pixels on a row */
239
2.46M
                bytestream2_skip(&g2, 1);
240
2.46M
                pixel_countdown = (s->avctx->width + 7) >> 3;
241
2.53M
                while (pixel_countdown > 0) {
242
2.48M
                    if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
243
2.40M
                        break;
244
73.2k
                    byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
245
73.2k
                    if (!byte_run) {
246
355
                        av_log(avctx, AV_LOG_ERROR, "Invalid byte run value.\n");
247
355
                        return AVERROR_INVALIDDATA;
248
355
                    }
249
250
72.8k
                    if (byte_run > 0) {
251
69.1k
                        int value = bytestream2_get_byte(&g2);
252
69.1k
                        CHECK_PIXEL_PTR(byte_run);
253
3.89M
                        for (j = 0; j < byte_run; j++) {
254
3.82M
                            pixels[pixel_ptr++] = value;
255
3.82M
                            pixel_countdown--;
256
3.82M
                            if (pixel_countdown < 0)
257
2.14M
                                av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
258
2.14M
                                       pixel_countdown, lines);
259
3.82M
                        }
260
68.9k
                    } else {  /* copy bytes if byte_run < 0 */
261
3.73k
                        byte_run = -byte_run;
262
3.73k
                        CHECK_PIXEL_PTR(byte_run);
263
3.51k
                        if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
264
1.13k
                            break;
265
42.1k
                        for (j = 0; j < byte_run; j++) {
266
39.7k
                            pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
267
39.7k
                            pixel_countdown--;
268
39.7k
                            if (pixel_countdown < 0)
269
18.6k
                                av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
270
18.6k
                                       pixel_countdown, lines);
271
39.7k
                        }
272
2.37k
                    }
273
72.8k
                }
274
275
2.45M
                y_ptr += s->frame->linesize[0];
276
2.45M
            }
277
509
            break;
278
279
2.25k
        case FLI_LC:
280
            /* line compressed */
281
2.25k
            starting_line = bytestream2_get_le16(&g2);
282
2.25k
            if (starting_line >= s->avctx->height)
283
252
                return AVERROR_INVALIDDATA;
284
2.00k
            y_ptr = 0;
285
2.00k
            y_ptr += starting_line * s->frame->linesize[0];
286
287
2.00k
            compressed_lines = bytestream2_get_le16(&g2);
288
180k
            while (compressed_lines > 0) {
289
179k
                pixel_ptr = y_ptr;
290
179k
                CHECK_PIXEL_PTR(0);
291
179k
                pixel_countdown = (s->avctx->width + 7) >> 3;
292
179k
                if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
293
724
                    break;
294
178k
                line_packets = bytestream2_get_byte(&g2);
295
178k
                if (line_packets > 0) {
296
1.19M
                    for (i = 0; i < line_packets; i++) {
297
                        /* account for the skip bytes */
298
1.17M
                        if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
299
761
                            break;
300
1.17M
                        pixel_skip = bytestream2_get_byte(&g2);
301
1.17M
                        pixel_ptr += pixel_skip;
302
1.17M
                        pixel_countdown -= pixel_skip;
303
1.17M
                        byte_run = sign_extend(bytestream2_get_byte(&g2),8);
304
1.17M
                        if (byte_run > 0) {
305
247k
                            CHECK_PIXEL_PTR(byte_run);
306
247k
                            if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
307
1.71k
                                break;
308
5.36M
                            for (j = 0; j < byte_run; j++, pixel_countdown--) {
309
5.11M
                                pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
310
5.11M
                            }
311
924k
                        } else if (byte_run < 0) {
312
328k
                            int value = bytestream2_get_byte(&g2);
313
328k
                            byte_run = -byte_run;
314
328k
                            CHECK_PIXEL_PTR(byte_run);
315
16.6M
                            for (j = 0; j < byte_run; j++, pixel_countdown--) {
316
16.3M
                                pixels[pixel_ptr++] = value;
317
16.3M
                            }
318
327k
                        }
319
1.17M
                    }
320
26.3k
                }
321
322
178k
                y_ptr += s->frame->linesize[0];
323
178k
                compressed_lines--;
324
178k
            }
325
1.15k
            break;
326
327
2.09k
        default:
328
2.09k
            av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
329
2.09k
            break;
330
5.64k
        }
331
332
3.76k
        if (stream_ptr_after_chunk - bytestream2_tell(&g2) >= 0) {
333
3.47k
            bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
334
3.47k
        } else {
335
289
            av_log(avctx, AV_LOG_ERROR, "Chunk overread\n");
336
289
            break;
337
289
        }
338
339
3.47k
        frame_size -= chunk_size;
340
3.47k
        num_chunks--;
341
3.47k
    }
342
343
    /* by the end of the chunk, the stream ptr should equal the frame
344
     * size (minus 1 or 2, possibly); if it doesn't, issue a warning */
345
5.96k
    if (bytestream2_get_bytes_left(&g2) > 2)
346
2.01k
        av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
347
2.01k
               "and final chunk ptr = %d\n", buf_size,
348
2.01k
               buf_size - bytestream2_get_bytes_left(&g2));
349
350
5.96k
    if ((ret = av_frame_ref(rframe, s->frame)) < 0)
351
0
        return ret;
352
353
5.96k
    *got_frame = 1;
354
355
5.96k
    return buf_size;
356
5.96k
}
357
358
static int flic_decode_frame_8BPP(AVCodecContext *avctx,
359
                                  AVFrame *rframe, int *got_frame,
360
                                  const uint8_t *buf, int buf_size)
361
113k
{
362
113k
    FlicDecodeContext *s = avctx->priv_data;
363
364
113k
    GetByteContext g2;
365
113k
    ptrdiff_t pixel_ptr;
366
113k
    int palette_ptr;
367
113k
    unsigned char palette_idx1;
368
113k
    unsigned char palette_idx2;
369
370
113k
    unsigned int frame_size;
371
113k
    int num_chunks;
372
373
113k
    unsigned int chunk_size;
374
113k
    int chunk_type;
375
376
113k
    int i, j, ret, direction;
377
378
113k
    int color_packets;
379
113k
    int color_changes;
380
113k
    int color_shift;
381
113k
    unsigned char r, g, b;
382
383
113k
    int lines;
384
113k
    int compressed_lines;
385
113k
    int starting_line;
386
113k
    int line_packets;
387
113k
    ptrdiff_t y_ptr;
388
113k
    int byte_run;
389
113k
    int pixel_skip;
390
113k
    int pixel_countdown;
391
113k
    unsigned char *pixels;
392
113k
    ptrdiff_t pixel_limit;
393
394
113k
    bytestream2_init(&g2, buf, buf_size);
395
396
113k
    if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
397
4.72k
        return ret;
398
399
109k
    direction = s->frame->linesize[0] > 0;
400
109k
    pixels = s->frame->data[0];
401
109k
    pixel_limit = s->avctx->height * s->frame->linesize[0];
402
109k
    if (buf_size < 16 || buf_size > INT_MAX - (3 * 256 + AV_INPUT_BUFFER_PADDING_SIZE))
403
4.00k
        return AVERROR_INVALIDDATA;
404
105k
    frame_size = bytestream2_get_le32(&g2);
405
105k
    if (frame_size > buf_size)
406
104k
        frame_size = buf_size;
407
105k
    bytestream2_skip(&g2, 2); /* skip the magic number */
408
105k
    num_chunks = bytestream2_get_le16(&g2);
409
105k
    bytestream2_skip(&g2, 8);  /* skip padding */
410
411
105k
    if (frame_size < 16)
412
269
        return AVERROR_INVALIDDATA;
413
414
104k
    frame_size -= 16;
415
416
    /* iterate through the chunks */
417
117k
    while ((frame_size >= 6) && (num_chunks > 0) &&
418
117k
            bytestream2_get_bytes_left(&g2) >= 4) {
419
17.0k
        int stream_ptr_after_chunk;
420
17.0k
        chunk_size = bytestream2_get_le32(&g2);
421
17.0k
        if (chunk_size > frame_size) {
422
15.0k
            av_log(avctx, AV_LOG_WARNING,
423
15.0k
                   "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
424
15.0k
            chunk_size = frame_size;
425
15.0k
        }
426
17.0k
        stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
427
428
17.0k
        chunk_type = bytestream2_get_le16(&g2);
429
430
17.0k
        switch (chunk_type) {
431
1.33k
        case FLI_256_COLOR:
432
1.98k
        case FLI_COLOR:
433
            /* check special case: If this file is from the Magic Carpet
434
             * game and uses 6-bit colors even though it reports 256-color
435
             * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during
436
             * initialization) */
437
1.98k
            if ((chunk_type == FLI_256_COLOR) && (s->fli_type != FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE))
438
1.13k
                color_shift = 0;
439
855
            else
440
855
                color_shift = 2;
441
            /* set up the palette */
442
1.98k
            color_packets = bytestream2_get_le16(&g2);
443
1.98k
            palette_ptr = 0;
444
67.9k
            for (i = 0; i < color_packets; i++) {
445
                /* first byte is how many colors to skip */
446
67.0k
                palette_ptr += bytestream2_get_byte(&g2);
447
448
                /* next byte indicates how many entries to change */
449
67.0k
                color_changes = bytestream2_get_byte(&g2);
450
451
                /* if there are 0 color changes, there are actually 256 */
452
67.0k
                if (color_changes == 0)
453
5.68k
                    color_changes = 256;
454
455
67.0k
                if (bytestream2_tell(&g2) + color_changes * 3 > stream_ptr_after_chunk)
456
1.05k
                    break;
457
458
2.14M
                for (j = 0; j < color_changes; j++) {
459
2.07M
                    unsigned int entry;
460
461
                    /* wrap around, for good measure */
462
2.07M
                    if ((unsigned)palette_ptr >= 256)
463
9.99k
                        palette_ptr = 0;
464
465
2.07M
                    r = bytestream2_get_byte(&g2) << color_shift;
466
2.07M
                    g = bytestream2_get_byte(&g2) << color_shift;
467
2.07M
                    b = bytestream2_get_byte(&g2) << color_shift;
468
2.07M
                    entry = 0xFFU << 24 | r << 16 | g << 8 | b;
469
2.07M
                    if (color_shift == 2)
470
1.99k
                        entry |= entry >> 6 & 0x30303;
471
2.07M
                    if (s->palette[palette_ptr] != entry)
472
1.85M
                        s->new_palette = 1;
473
2.07M
                    s->palette[palette_ptr++] = entry;
474
2.07M
                }
475
65.9k
            }
476
1.98k
            break;
477
478
3.24k
        case FLI_DELTA:
479
3.24k
            y_ptr = 0;
480
3.24k
            compressed_lines = bytestream2_get_le16(&g2);
481
20.3k
            while (compressed_lines > 0) {
482
19.7k
                if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
483
1.22k
                    break;
484
18.5k
                CHECK_Y_PTR()
485
18.1k
                line_packets = sign_extend(bytestream2_get_le16(&g2), 16);
486
18.1k
                if ((line_packets & 0xC000) == 0xC000) {
487
                    // line skip opcode
488
3.96k
                    line_packets = -line_packets;
489
3.96k
                    if (line_packets > s->avctx->height)
490
364
                        return AVERROR_INVALIDDATA;
491
3.60k
                    y_ptr += line_packets * s->frame->linesize[0];
492
14.1k
                } else if ((line_packets & 0xC000) == 0x4000) {
493
1.68k
                    av_log(avctx, AV_LOG_ERROR, "Undefined opcode (%x) in DELTA_FLI\n", line_packets);
494
12.4k
                } else if ((line_packets & 0xC000) == 0x8000) {
495
                    // "last byte" opcode
496
1.26k
                    pixel_ptr= y_ptr + s->frame->linesize[0] - 1;
497
1.26k
                    CHECK_PIXEL_PTR(0);
498
1.04k
                    pixels[pixel_ptr] = line_packets & 0xff;
499
11.2k
                } else {
500
11.2k
                    compressed_lines--;
501
11.2k
                    pixel_ptr = y_ptr;
502
11.2k
                    CHECK_PIXEL_PTR(0);
503
11.2k
                    pixel_countdown = s->avctx->width;
504
850k
                    for (i = 0; i < line_packets; i++) {
505
842k
                        if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
506
948
                            break;
507
                        /* account for the skip bytes */
508
841k
                        pixel_skip = bytestream2_get_byte(&g2);
509
841k
                        pixel_ptr += pixel_skip;
510
841k
                        pixel_countdown -= pixel_skip;
511
841k
                        byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
512
841k
                        if (byte_run < 0) {
513
230k
                            byte_run = -byte_run;
514
230k
                            palette_idx1 = bytestream2_get_byte(&g2);
515
230k
                            palette_idx2 = bytestream2_get_byte(&g2);
516
230k
                            CHECK_PIXEL_PTR(byte_run * 2);
517
5.87M
                            for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
518
5.64M
                                pixels[pixel_ptr++] = palette_idx1;
519
5.64M
                                pixels[pixel_ptr++] = palette_idx2;
520
5.64M
                            }
521
611k
                        } else {
522
611k
                            CHECK_PIXEL_PTR(byte_run * 2);
523
610k
                            if (bytestream2_tell(&g2) + byte_run * 2 > stream_ptr_after_chunk)
524
1.39k
                                break;
525
5.12M
                            for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
526
4.51M
                                pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
527
4.51M
                            }
528
609k
                        }
529
841k
                    }
530
531
10.7k
                    y_ptr += s->frame->linesize[0];
532
10.7k
                }
533
18.1k
            }
534
1.80k
            break;
535
536
4.09k
        case FLI_LC:
537
            /* line compressed */
538
4.09k
            starting_line = bytestream2_get_le16(&g2);
539
4.09k
            if (starting_line >= s->avctx->height)
540
256
                return AVERROR_INVALIDDATA;
541
3.84k
            y_ptr = 0;
542
3.84k
            y_ptr += starting_line * s->frame->linesize[0];
543
544
3.84k
            compressed_lines = bytestream2_get_le16(&g2);
545
389k
            while (compressed_lines > 0) {
546
388k
                pixel_ptr = y_ptr;
547
388k
                CHECK_PIXEL_PTR(0);
548
388k
                pixel_countdown = s->avctx->width;
549
388k
                if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
550
2.10k
                    break;
551
386k
                line_packets = bytestream2_get_byte(&g2);
552
386k
                if (line_packets > 0) {
553
1.07M
                    for (i = 0; i < line_packets; i++) {
554
                        /* account for the skip bytes */
555
1.03M
                        if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
556
2.06k
                            break;
557
1.02M
                        pixel_skip = bytestream2_get_byte(&g2);
558
1.02M
                        pixel_ptr += pixel_skip;
559
1.02M
                        pixel_countdown -= pixel_skip;
560
1.02M
                        byte_run = sign_extend(bytestream2_get_byte(&g2),8);
561
1.02M
                        if (byte_run > 0) {
562
245k
                            CHECK_PIXEL_PTR(byte_run);
563
244k
                            if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
564
4.29k
                                break;
565
4.08M
                            for (j = 0; j < byte_run; j++, pixel_countdown--) {
566
3.84M
                                pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
567
3.84M
                            }
568
783k
                        } else if (byte_run < 0) {
569
251k
                            byte_run = -byte_run;
570
251k
                            palette_idx1 = bytestream2_get_byte(&g2);
571
251k
                            CHECK_PIXEL_PTR(byte_run);
572
12.3M
                            for (j = 0; j < byte_run; j++, pixel_countdown--) {
573
12.0M
                                pixels[pixel_ptr++] = palette_idx1;
574
12.0M
                            }
575
250k
                        }
576
1.02M
                    }
577
49.6k
                }
578
579
385k
                y_ptr += s->frame->linesize[0];
580
385k
                compressed_lines--;
581
385k
            }
582
2.60k
            break;
583
584
2.60k
        case FLI_BLACK:
585
            /* set the whole frame to color 0 (which is usually black) */
586
1.78M
            for (int y = 0; y < s->avctx->height; y++)
587
1.78M
                memset(pixels + y * s->frame->linesize[0], 0, s->avctx->width);
588
322
            break;
589
590
1.36k
        case FLI_BRUN:
591
            /* Byte run compression: This chunk type only occurs in the first
592
             * FLI frame and it will update the entire frame. */
593
1.36k
            y_ptr = 0;
594
1.86M
            for (lines = 0; lines < s->avctx->height; lines++) {
595
1.86M
                pixel_ptr = y_ptr;
596
                /* disregard the line packets; instead, iterate through all
597
                 * pixels on a row */
598
1.86M
                 bytestream2_skip(&g2, 1);
599
1.86M
                pixel_countdown = s->avctx->width;
600
3.21M
                while (pixel_countdown > 0) {
601
2.99M
                    if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
602
1.64M
                        break;
603
1.35M
                    byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
604
1.35M
                    if (!byte_run) {
605
364
                        av_log(avctx, AV_LOG_ERROR, "Invalid byte run value.\n");
606
364
                        return AVERROR_INVALIDDATA;
607
364
                    }
608
609
1.35M
                    if (byte_run > 0) {
610
1.34M
                        palette_idx1 = bytestream2_get_byte(&g2);
611
1.34M
                        CHECK_PIXEL_PTR(byte_run);
612
37.4M
                        for (j = 0; j < byte_run; j++) {
613
36.0M
                            pixels[pixel_ptr++] = palette_idx1;
614
36.0M
                            pixel_countdown--;
615
36.0M
                            if (pixel_countdown < 0)
616
8.00M
                                av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
617
8.00M
                                       pixel_countdown, lines);
618
36.0M
                        }
619
1.34M
                    } else {  /* copy bytes if byte_run < 0 */
620
7.80k
                        byte_run = -byte_run;
621
7.80k
                        CHECK_PIXEL_PTR(byte_run);
622
7.59k
                        if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
623
1.30k
                            break;
624
63.5k
                        for (j = 0; j < byte_run; j++) {
625
57.2k
                            pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
626
57.2k
                            pixel_countdown--;
627
57.2k
                            if (pixel_countdown < 0)
628
11.4k
                                av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
629
11.4k
                                       pixel_countdown, lines);
630
57.2k
                        }
631
6.28k
                    }
632
1.35M
                }
633
634
1.86M
                y_ptr += s->frame->linesize[0];
635
1.86M
            }
636
556
            break;
637
638
1.28k
        case FLI_COPY:
639
            /* copy the chunk (uncompressed frame) */
640
1.28k
            if (chunk_size - 6 != FFALIGN(s->avctx->width, 4) * s->avctx->height) {
641
671
                av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
642
671
                       "has incorrect size, skipping chunk\n", chunk_size - 6);
643
671
                bytestream2_skip(&g2, chunk_size - 6);
644
671
            } else {
645
3.72k
                for (y_ptr = 0; check_pixel_ptr(y_ptr, s->avctx->width, pixel_limit, direction) == 0;
646
3.11k
                     y_ptr += s->frame->linesize[0]) {
647
3.11k
                    bytestream2_get_buffer(&g2, &pixels[y_ptr],
648
3.11k
                                           s->avctx->width);
649
3.11k
                    if (s->avctx->width & 3)
650
2.16k
                        bytestream2_skip(&g2, 4 - (s->avctx->width & 3));
651
3.11k
                }
652
613
            }
653
1.28k
            break;
654
655
250
        case FLI_MINI:
656
            /* some sort of a thumbnail? disregard this chunk... */
657
250
            break;
658
659
4.52k
        default:
660
4.52k
            av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
661
4.52k
            break;
662
17.0k
        }
663
664
13.3k
        if (stream_ptr_after_chunk - bytestream2_tell(&g2) >= 0) {
665
12.2k
            bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
666
12.2k
        } else {
667
1.10k
            av_log(avctx, AV_LOG_ERROR, "Chunk overread\n");
668
1.10k
            break;
669
1.10k
        }
670
671
12.2k
        frame_size -= chunk_size;
672
12.2k
        num_chunks--;
673
12.2k
    }
674
675
    /* by the end of the chunk, the stream ptr should equal the frame
676
     * size (minus 1 or 2, possibly); if it doesn't, issue a warning */
677
101k
    if (bytestream2_get_bytes_left(&g2) > 2)
678
23.9k
        av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
679
23.9k
               "and final chunk ptr = %d\n", buf_size,
680
23.9k
               buf_size - bytestream2_get_bytes_left(&g2));
681
682
    /* make the palette available on the way out */
683
101k
    memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE);
684
101k
    if (s->new_palette) {
685
503
#if FF_API_PALETTE_HAS_CHANGED
686
503
FF_DISABLE_DEPRECATION_WARNINGS
687
503
        s->frame->palette_has_changed = 1;
688
503
FF_ENABLE_DEPRECATION_WARNINGS
689
503
#endif
690
503
        s->new_palette = 0;
691
503
    }
692
693
101k
    if ((ret = av_frame_ref(rframe, s->frame)) < 0)
694
0
        return ret;
695
696
101k
    *got_frame = 1;
697
698
101k
    return buf_size;
699
101k
}
700
701
static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
702
                                      AVFrame *rframe, int *got_frame,
703
                                      const uint8_t *buf, int buf_size)
704
12.2k
{
705
    /* Note, the only difference between the 15Bpp and 16Bpp */
706
    /* Format is the pixel format, the packets are processed the same. */
707
12.2k
    FlicDecodeContext *s = avctx->priv_data;
708
709
12.2k
    GetByteContext g2;
710
12.2k
    ptrdiff_t pixel_ptr;
711
12.2k
    unsigned char palette_idx1;
712
713
12.2k
    unsigned int frame_size;
714
12.2k
    int num_chunks;
715
716
12.2k
    unsigned int chunk_size;
717
12.2k
    int chunk_type;
718
719
12.2k
    int i, j, ret, direction;
720
721
12.2k
    int lines;
722
12.2k
    int compressed_lines;
723
12.2k
    int line_packets;
724
12.2k
    ptrdiff_t y_ptr;
725
12.2k
    int byte_run;
726
12.2k
    int pixel_skip;
727
12.2k
    int pixel_countdown;
728
12.2k
    unsigned char *pixels;
729
12.2k
    int pixel;
730
12.2k
    ptrdiff_t pixel_limit;
731
732
12.2k
    bytestream2_init(&g2, buf, buf_size);
733
734
12.2k
    if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
735
335
        return ret;
736
737
11.8k
    direction = s->frame->linesize[0] > 0;
738
11.8k
    pixels = s->frame->data[0];
739
11.8k
    pixel_limit = s->avctx->height * s->frame->linesize[0];
740
741
11.8k
    frame_size = bytestream2_get_le32(&g2);
742
11.8k
    bytestream2_skip(&g2, 2);  /* skip the magic number */
743
11.8k
    num_chunks = bytestream2_get_le16(&g2);
744
11.8k
    bytestream2_skip(&g2, 8);  /* skip padding */
745
11.8k
    if (frame_size > buf_size)
746
10.7k
        frame_size = buf_size;
747
748
11.8k
    if (frame_size < 16)
749
1.15k
        return AVERROR_INVALIDDATA;
750
10.7k
    frame_size -= 16;
751
752
    /* iterate through the chunks */
753
16.9k
    while ((frame_size > 0) && (num_chunks > 0) &&
754
16.9k
            bytestream2_get_bytes_left(&g2) >= 4) {
755
9.56k
        int stream_ptr_after_chunk;
756
9.56k
        chunk_size = bytestream2_get_le32(&g2);
757
9.56k
        if (chunk_size > frame_size) {
758
7.13k
            av_log(avctx, AV_LOG_WARNING,
759
7.13k
                   "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
760
7.13k
            chunk_size = frame_size;
761
7.13k
        }
762
9.56k
        stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
763
764
9.56k
        chunk_type = bytestream2_get_le16(&g2);
765
766
767
9.56k
        switch (chunk_type) {
768
497
        case FLI_256_COLOR:
769
727
        case FLI_COLOR:
770
            /* For some reason, it seems that non-palettized flics do
771
             * include one of these chunks in their first frame.
772
             * Why I do not know, it seems rather extraneous. */
773
727
            ff_dlog(avctx,
774
727
                    "Unexpected Palette chunk %d in non-palettized FLC\n",
775
727
                    chunk_type);
776
727
            bytestream2_skip(&g2, chunk_size - 6);
777
727
            break;
778
779
2.05k
        case FLI_DELTA:
780
2.53k
        case FLI_DTA_LC:
781
2.53k
            y_ptr = 0;
782
2.53k
            compressed_lines = bytestream2_get_le16(&g2);
783
7.80k
            while (compressed_lines > 0) {
784
7.28k
                if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
785
908
                    break;
786
6.37k
                CHECK_Y_PTR()
787
6.12k
                line_packets = sign_extend(bytestream2_get_le16(&g2), 16);
788
6.12k
                if (line_packets < 0) {
789
1.22k
                    line_packets = -line_packets;
790
1.22k
                    if (line_packets > s->avctx->height)
791
415
                        return AVERROR_INVALIDDATA;
792
808
                    y_ptr += line_packets * s->frame->linesize[0];
793
4.89k
                } else {
794
4.89k
                    compressed_lines--;
795
4.89k
                    pixel_ptr = y_ptr;
796
4.89k
                    CHECK_PIXEL_PTR(0);
797
4.89k
                    pixel_countdown = s->avctx->width;
798
613k
                    for (i = 0; i < line_packets; i++) {
799
                        /* account for the skip bytes */
800
611k
                        if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
801
837
                            break;
802
610k
                        pixel_skip = bytestream2_get_byte(&g2);
803
610k
                        pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */
804
610k
                        pixel_countdown -= pixel_skip;
805
610k
                        byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
806
610k
                        if (byte_run < 0) {
807
139k
                            byte_run = -byte_run;
808
139k
                            pixel    = bytestream2_get_le16(&g2);
809
139k
                            CHECK_PIXEL_PTR(2 * byte_run);
810
6.08M
                            for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
811
5.95M
                                *((signed short*)(&pixels[pixel_ptr])) = pixel;
812
5.95M
                                pixel_ptr += 2;
813
5.95M
                            }
814
471k
                        } else {
815
471k
                            if (bytestream2_tell(&g2) + 2*byte_run > stream_ptr_after_chunk)
816
1.60k
                                break;
817
470k
                            CHECK_PIXEL_PTR(2 * byte_run);
818
2.75M
                            for (j = 0; j < byte_run; j++, pixel_countdown--) {
819
2.28M
                                *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
820
2.28M
                                pixel_ptr += 2;
821
2.28M
                            }
822
469k
                        }
823
610k
                    }
824
825
4.46k
                    y_ptr += s->frame->linesize[0];
826
4.46k
                }
827
6.12k
            }
828
1.43k
            break;
829
830
1.43k
        case FLI_LC:
831
478
            av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-palettized FLC\n");
832
478
            bytestream2_skip(&g2, chunk_size - 6);
833
478
            break;
834
835
238
        case FLI_BLACK:
836
            /* set the whole frame to 0x0000 which is black in both 15Bpp and 16Bpp modes. */
837
2.24M
            for (int y = 0; y < s->avctx->height; y++)
838
2.24M
                memset(pixels + y * s->frame->linesize[0], 0, s->avctx->width * 2);
839
238
            break;
840
841
784
        case FLI_BRUN:
842
784
            y_ptr = 0;
843
1.78M
            for (lines = 0; lines < s->avctx->height; lines++) {
844
1.78M
                pixel_ptr = y_ptr;
845
                /* disregard the line packets; instead, iterate through all
846
                 * pixels on a row */
847
1.78M
                bytestream2_skip(&g2, 1);
848
1.78M
                pixel_countdown = (s->avctx->width * 2);
849
850
2.40M
                while (pixel_countdown > 0) {
851
2.39M
                    if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
852
1.76M
                        break;
853
628k
                    byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
854
628k
                    if (byte_run > 0) {
855
214k
                        palette_idx1 = bytestream2_get_byte(&g2);
856
214k
                        CHECK_PIXEL_PTR(byte_run);
857
6.70M
                        for (j = 0; j < byte_run; j++) {
858
6.48M
                            pixels[pixel_ptr++] = palette_idx1;
859
6.48M
                            pixel_countdown--;
860
6.48M
                            if (pixel_countdown < 0)
861
359k
                                av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) (linea%d)\n",
862
359k
                                       pixel_countdown, lines);
863
6.48M
                        }
864
414k
                    } else {  /* copy bytes if byte_run < 0 */
865
414k
                        byte_run = -byte_run;
866
414k
                        if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
867
1.17k
                            break;
868
413k
                        CHECK_PIXEL_PTR(byte_run);
869
3.11M
                        for (j = 0; j < byte_run; j++) {
870
2.70M
                            palette_idx1 = bytestream2_get_byte(&g2);
871
2.70M
                            pixels[pixel_ptr++] = palette_idx1;
872
2.70M
                            pixel_countdown--;
873
2.70M
                            if (pixel_countdown < 0)
874
286k
                                av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
875
286k
                                       pixel_countdown, lines);
876
2.70M
                        }
877
413k
                    }
878
628k
                }
879
880
                /* Now FLX is strange, in that it is "byte" as opposed to "pixel" run length compressed.
881
                 * This does not give us any good opportunity to perform word endian conversion
882
                 * during decompression. So if it is required (i.e., this is not a LE target, we do
883
                 * a second pass over the line here, swapping the bytes.
884
                 */
885
#if HAVE_BIGENDIAN
886
                pixel_ptr = y_ptr;
887
                pixel_countdown = s->avctx->width;
888
                while (pixel_countdown > 0) {
889
                    *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[pixel_ptr]);
890
                    pixel_ptr += 2;
891
                }
892
#endif
893
1.78M
                y_ptr += s->frame->linesize[0];
894
1.78M
            }
895
377
            break;
896
897
850
        case FLI_DTA_BRUN:
898
850
            y_ptr = 0;
899
1.61M
            for (lines = 0; lines < s->avctx->height; lines++) {
900
1.61M
                pixel_ptr = y_ptr;
901
                /* disregard the line packets; instead, iterate through all
902
                 * pixels on a row */
903
1.61M
                bytestream2_skip(&g2, 1);
904
1.61M
                pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */
905
906
1.97M
                while (pixel_countdown > 0) {
907
1.96M
                    if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
908
1.59M
                        break;
909
365k
                    byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
910
365k
                    if (byte_run > 0) {
911
111k
                        pixel    = bytestream2_get_le16(&g2);
912
111k
                        CHECK_PIXEL_PTR(2 * byte_run);
913
2.29M
                        for (j = 0; j < byte_run; j++) {
914
2.18M
                            *((signed short*)(&pixels[pixel_ptr])) = pixel;
915
2.18M
                            pixel_ptr += 2;
916
2.18M
                            pixel_countdown--;
917
2.18M
                            if (pixel_countdown < 0)
918
293k
                                av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
919
293k
                                       pixel_countdown);
920
2.18M
                        }
921
254k
                    } else {  /* copy pixels if byte_run < 0 */
922
254k
                        byte_run = -byte_run;
923
254k
                        if (bytestream2_tell(&g2) + 2 * byte_run > stream_ptr_after_chunk)
924
988
                            break;
925
253k
                        CHECK_PIXEL_PTR(2 * byte_run);
926
2.12M
                        for (j = 0; j < byte_run; j++) {
927
1.87M
                            *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
928
1.87M
                            pixel_ptr  += 2;
929
1.87M
                            pixel_countdown--;
930
1.87M
                            if (pixel_countdown < 0)
931
310k
                                av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
932
310k
                                       pixel_countdown);
933
1.87M
                        }
934
252k
                    }
935
365k
                }
936
937
1.61M
                y_ptr += s->frame->linesize[0];
938
1.61M
            }
939
454
            break;
940
941
993
        case FLI_COPY:
942
1.22k
        case FLI_DTA_COPY:
943
            /* copy the chunk (uncompressed frame) */
944
1.22k
            if (chunk_size - 6 > (unsigned int)(FFALIGN(s->avctx->width, 2) * s->avctx->height)*2) {
945
679
                av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
946
679
                       "bigger than image, skipping chunk\n", chunk_size - 6);
947
679
                bytestream2_skip(&g2, chunk_size - 6);
948
679
            } else {
949
950
547
                if (bytestream2_get_bytes_left(&g2) < 2 * s->avctx->width * s->avctx->height )
951
299
                    return AVERROR_INVALIDDATA;
952
17.4k
                for (y_ptr = 0; check_pixel_ptr(y_ptr, 2*s->avctx->width, pixel_limit, direction) == 0;
953
17.2k
                     y_ptr += s->frame->linesize[0]) {
954
955
17.2k
                    pixel_countdown = s->avctx->width;
956
17.2k
                    pixel_ptr = 0;
957
91.8k
                    while (pixel_countdown > 0) {
958
74.5k
                      *((signed short*)(&pixels[y_ptr + pixel_ptr])) = bytestream2_get_le16(&g2);
959
74.5k
                      pixel_ptr += 2;
960
74.5k
                      pixel_countdown--;
961
74.5k
                    }
962
17.2k
                    if (s->avctx->width & 1)
963
16.8k
                        bytestream2_skip(&g2, 2);
964
17.2k
                }
965
248
            }
966
927
            break;
967
968
927
        case FLI_MINI:
969
            /* some sort of a thumbnail? disregard this chunk... */
970
433
            bytestream2_skip(&g2, chunk_size - 6);
971
433
            break;
972
973
2.29k
        default:
974
2.29k
            av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
975
2.29k
            break;
976
9.56k
        }
977
978
7.35k
        if (stream_ptr_after_chunk - bytestream2_tell(&g2) >= 0) {
979
6.25k
            bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
980
6.25k
        } else {
981
1.10k
            av_log(avctx, AV_LOG_ERROR, "Chunk overread\n");
982
1.10k
            break;
983
1.10k
        }
984
985
6.25k
        frame_size -= chunk_size;
986
6.25k
        num_chunks--;
987
6.25k
    }
988
989
    /* by the end of the chunk, the stream ptr should equal the frame
990
     * size (minus 1, possibly); if it doesn't, issue a warning */
991
8.53k
    if ((bytestream2_get_bytes_left(&g2) != 0) && (bytestream2_get_bytes_left(&g2) != 1))
992
1.34k
        av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
993
1.34k
               "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2));
994
995
8.53k
    if ((ret = av_frame_ref(rframe, s->frame)) < 0)
996
0
        return ret;
997
998
8.53k
    *got_frame = 1;
999
1000
8.53k
    return buf_size;
1001
8.53k
}
1002
1003
static int flic_decode_frame_24BPP(AVCodecContext *avctx,
1004
                                   AVFrame *rframe, int *got_frame,
1005
                                   const uint8_t *buf, int buf_size)
1006
11.6k
{
1007
11.6k
    FlicDecodeContext *s = avctx->priv_data;
1008
1009
11.6k
    GetByteContext g2;
1010
11.6k
    ptrdiff_t pixel_ptr;
1011
11.6k
    unsigned char palette_idx1;
1012
1013
11.6k
    unsigned int frame_size;
1014
11.6k
    int num_chunks;
1015
1016
11.6k
    unsigned int chunk_size;
1017
11.6k
    int chunk_type;
1018
1019
11.6k
    int i, j, ret, direction;
1020
1021
11.6k
    int lines;
1022
11.6k
    int compressed_lines;
1023
11.6k
    int line_packets;
1024
11.6k
    ptrdiff_t y_ptr;
1025
11.6k
    int byte_run;
1026
11.6k
    int pixel_skip;
1027
11.6k
    int pixel_countdown;
1028
11.6k
    unsigned char *pixels;
1029
11.6k
    int pixel;
1030
11.6k
    ptrdiff_t pixel_limit;
1031
1032
11.6k
    bytestream2_init(&g2, buf, buf_size);
1033
1034
11.6k
    if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
1035
211
        return ret;
1036
1037
11.4k
    direction = s->frame->linesize[0] > 0;
1038
11.4k
    pixels = s->frame->data[0];
1039
11.4k
    pixel_limit = s->avctx->height * s->frame->linesize[0];
1040
1041
11.4k
    frame_size = bytestream2_get_le32(&g2);
1042
11.4k
    bytestream2_skip(&g2, 2);  /* skip the magic number */
1043
11.4k
    num_chunks = bytestream2_get_le16(&g2);
1044
11.4k
    bytestream2_skip(&g2, 8);  /* skip padding */
1045
11.4k
    if (frame_size > buf_size)
1046
10.1k
        frame_size = buf_size;
1047
1048
11.4k
    if (frame_size < 16)
1049
1.77k
        return AVERROR_INVALIDDATA;
1050
9.70k
    frame_size -= 16;
1051
1052
    /* iterate through the chunks */
1053
15.8k
    while ((frame_size > 0) && (num_chunks > 0) &&
1054
15.8k
            bytestream2_get_bytes_left(&g2) >= 4) {
1055
9.38k
        int stream_ptr_after_chunk;
1056
9.38k
        chunk_size = bytestream2_get_le32(&g2);
1057
9.38k
        if (chunk_size > frame_size) {
1058
6.91k
            av_log(avctx, AV_LOG_WARNING,
1059
6.91k
                   "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
1060
6.91k
            chunk_size = frame_size;
1061
6.91k
        }
1062
9.38k
        stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
1063
1064
9.38k
        chunk_type = bytestream2_get_le16(&g2);
1065
1066
1067
9.38k
        switch (chunk_type) {
1068
481
        case FLI_256_COLOR:
1069
714
        case FLI_COLOR:
1070
            /* For some reason, it seems that non-palettized flics do
1071
             * include one of these chunks in their first frame.
1072
             * Why I do not know, it seems rather extraneous. */
1073
714
            ff_dlog(avctx,
1074
714
                    "Unexpected Palette chunk %d in non-palettized FLC\n",
1075
714
                    chunk_type);
1076
714
            bytestream2_skip(&g2, chunk_size - 6);
1077
714
            break;
1078
1079
2.15k
        case FLI_DELTA:
1080
2.38k
        case FLI_DTA_LC:
1081
2.38k
            y_ptr = 0;
1082
2.38k
            compressed_lines = bytestream2_get_le16(&g2);
1083
7.28k
            while (compressed_lines > 0) {
1084
6.71k
                if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
1085
868
                    break;
1086
5.84k
                CHECK_Y_PTR()
1087
5.62k
                line_packets = sign_extend(bytestream2_get_le16(&g2), 16);
1088
5.62k
                if (line_packets < 0) {
1089
1.10k
                    line_packets = -line_packets;
1090
1.10k
                    if (line_packets > s->avctx->height)
1091
285
                        return AVERROR_INVALIDDATA;
1092
816
                    y_ptr += line_packets * s->frame->linesize[0];
1093
4.52k
                } else {
1094
4.52k
                    compressed_lines--;
1095
4.52k
                    pixel_ptr = y_ptr;
1096
4.52k
                    CHECK_PIXEL_PTR(0);
1097
4.52k
                    pixel_countdown = s->avctx->width;
1098
662k
                    for (i = 0; i < line_packets; i++) {
1099
                        /* account for the skip bytes */
1100
660k
                        if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
1101
791
                            break;
1102
659k
                        pixel_skip = bytestream2_get_byte(&g2);
1103
659k
                        pixel_ptr += (pixel_skip*3); /* Pixel is 3 bytes wide */
1104
659k
                        pixel_countdown -= pixel_skip;
1105
659k
                        byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
1106
659k
                        if (byte_run < 0) {
1107
167k
                            byte_run = -byte_run;
1108
167k
                            pixel    = bytestream2_get_le24(&g2);
1109
167k
                            CHECK_PIXEL_PTR(3 * byte_run);
1110
6.38M
                            for (j = 0; j < byte_run; j++, pixel_countdown -= 1) {
1111
6.22M
                                AV_WL24(&pixels[pixel_ptr], pixel);
1112
6.22M
                                pixel_ptr += 3;
1113
6.22M
                            }
1114
492k
                        } else {
1115
492k
                            if (bytestream2_tell(&g2) + 2*byte_run > stream_ptr_after_chunk)
1116
1.59k
                                break;
1117
491k
                            CHECK_PIXEL_PTR(3 * byte_run);
1118
2.75M
                            for (j = 0; j < byte_run; j++, pixel_countdown--) {
1119
2.26M
                                pixel = bytestream2_get_le24(&g2);
1120
2.26M
                                AV_WL24(&pixels[pixel_ptr], pixel);
1121
2.26M
                                pixel_ptr += 3;
1122
2.26M
                            }
1123
490k
                        }
1124
659k
                    }
1125
1126
4.08k
                    y_ptr += s->frame->linesize[0];
1127
4.08k
                }
1128
5.62k
            }
1129
1.43k
            break;
1130
1131
1.43k
        case FLI_LC:
1132
741
            av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-palettized FLC\n");
1133
741
            bytestream2_skip(&g2, chunk_size - 6);
1134
741
            break;
1135
1136
266
        case FLI_BLACK:
1137
            /* set the whole frame to 0x00 which is black for 24 bit mode. */
1138
2.28M
            for (int y = 0; y < s->avctx->height; y++)
1139
2.28M
                memset(pixels + y * s->frame->linesize[0], 0, s->avctx->width * 3);
1140
266
            break;
1141
1142
925
        case FLI_BRUN:
1143
925
            y_ptr = 0;
1144
2.23M
            for (lines = 0; lines < s->avctx->height; lines++) {
1145
2.23M
                pixel_ptr = y_ptr;
1146
                /* disregard the line packets; instead, iterate through all
1147
                 * pixels on a row */
1148
2.23M
                bytestream2_skip(&g2, 1);
1149
2.23M
                pixel_countdown = (s->avctx->width * 3);
1150
1151
3.12M
                while (pixel_countdown > 0) {
1152
3.12M
                    if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
1153
2.23M
                        break;
1154
893k
                    byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
1155
893k
                    if (byte_run > 0) {
1156
359k
                        palette_idx1 = bytestream2_get_byte(&g2);
1157
359k
                        CHECK_PIXEL_PTR(byte_run);
1158
10.2M
                        for (j = 0; j < byte_run; j++) {
1159
9.91M
                            pixels[pixel_ptr++] = palette_idx1;
1160
9.91M
                            pixel_countdown--;
1161
9.91M
                            if (pixel_countdown < 0)
1162
50.4k
                                av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) (linea%d)\n",
1163
50.4k
                                       pixel_countdown, lines);
1164
9.91M
                        }
1165
533k
                    } else {  /* copy bytes if byte_run < 0 */
1166
533k
                        byte_run = -byte_run;
1167
533k
                        if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
1168
906
                            break;
1169
533k
                        CHECK_PIXEL_PTR(byte_run);
1170
5.23M
                        for (j = 0; j < byte_run; j++) {
1171
4.70M
                            palette_idx1 = bytestream2_get_byte(&g2);
1172
4.70M
                            pixels[pixel_ptr++] = palette_idx1;
1173
4.70M
                            pixel_countdown--;
1174
4.70M
                            if (pixel_countdown < 0)
1175
16.5k
                                av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
1176
16.5k
                                       pixel_countdown, lines);
1177
4.70M
                        }
1178
532k
                    }
1179
893k
                }
1180
1181
2.23M
                y_ptr += s->frame->linesize[0];
1182
2.23M
            }
1183
516
            break;
1184
1185
993
        case FLI_DTA_BRUN:
1186
993
            y_ptr = 0;
1187
3.08M
            for (lines = 0; lines < s->avctx->height; lines++) {
1188
3.08M
                pixel_ptr = y_ptr;
1189
                /* disregard the line packets; instead, iterate through all
1190
                 * pixels on a row */
1191
3.08M
                bytestream2_skip(&g2, 1);
1192
3.08M
                pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */
1193
1194
3.30M
                while (pixel_countdown > 0) {
1195
3.30M
                    if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
1196
3.08M
                        break;
1197
219k
                    byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
1198
219k
                    if (byte_run > 0) {
1199
36.8k
                        pixel = bytestream2_get_le24(&g2);
1200
36.8k
                        CHECK_PIXEL_PTR(3 * byte_run);
1201
1.48M
                        for (j = 0; j < byte_run; j++) {
1202
1.44M
                            AV_WL24(pixels + pixel_ptr, pixel);
1203
1.44M
                            pixel_ptr += 3;
1204
1.44M
                            pixel_countdown--;
1205
1.44M
                            if (pixel_countdown < 0)
1206
33.9k
                                av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
1207
33.9k
                                       pixel_countdown);
1208
1.44M
                        }
1209
182k
                    } else {  /* copy pixels if byte_run < 0 */
1210
182k
                        byte_run = -byte_run;
1211
182k
                        if (bytestream2_tell(&g2) + 3 * byte_run > stream_ptr_after_chunk)
1212
1.29k
                            break;
1213
181k
                        CHECK_PIXEL_PTR(3 * byte_run);
1214
1.48M
                        for (j = 0; j < byte_run; j++) {
1215
1.30M
                            pixel = bytestream2_get_le24(&g2);
1216
1.30M
                            AV_WL24(pixels + pixel_ptr, pixel);
1217
1.30M
                            pixel_ptr  += 3;
1218
1.30M
                            pixel_countdown--;
1219
1.30M
                            if (pixel_countdown < 0)
1220
14.0k
                                av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
1221
14.0k
                                       pixel_countdown);
1222
1.30M
                        }
1223
181k
                    }
1224
219k
                }
1225
1226
3.08M
                y_ptr += s->frame->linesize[0];
1227
3.08M
            }
1228
517
            break;
1229
1230
624
        case FLI_COPY:
1231
862
        case FLI_DTA_COPY:
1232
            /* copy the chunk (uncompressed frame) */
1233
862
            if (chunk_size - 6 > (unsigned int)(FFALIGN(s->avctx->width, 2) * s->avctx->height)*3) {
1234
478
                av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
1235
478
                       "bigger than image, skipping chunk\n", chunk_size - 6);
1236
478
                bytestream2_skip(&g2, chunk_size - 6);
1237
478
            } else {
1238
1.61M
                for (y_ptr = 0; check_pixel_ptr(y_ptr, 3*s->avctx->width, pixel_limit, direction) == 0;
1239
1.61M
                     y_ptr += s->frame->linesize[0]) {
1240
1241
1.61M
                    bytestream2_get_buffer(&g2, pixels + y_ptr, 3*s->avctx->width);
1242
1.61M
                    if (s->avctx->width & 1)
1243
304k
                        bytestream2_skip(&g2, 3);
1244
1.61M
                }
1245
384
            }
1246
862
            break;
1247
1248
672
        case FLI_MINI:
1249
            /* some sort of a thumbnail? disregard this chunk... */
1250
672
            bytestream2_skip(&g2, chunk_size - 6);
1251
672
            break;
1252
1253
1.83k
        default:
1254
1.83k
            av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
1255
1.83k
            break;
1256
9.38k
        }
1257
1258
7.56k
        if (stream_ptr_after_chunk - bytestream2_tell(&g2) >= 0) {
1259
6.14k
            bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
1260
6.14k
        } else {
1261
1.41k
            av_log(avctx, AV_LOG_ERROR, "Chunk overread\n");
1262
1.41k
            break;
1263
1.41k
        }
1264
1265
6.14k
        frame_size -= chunk_size;
1266
6.14k
        num_chunks--;
1267
6.14k
    }
1268
1269
    /* by the end of the chunk, the stream ptr should equal the frame
1270
     * size (minus 1, possibly); if it doesn't, issue a warning */
1271
7.87k
    if ((bytestream2_get_bytes_left(&g2) != 0) && (bytestream2_get_bytes_left(&g2) != 1))
1272
1.00k
        av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
1273
1.00k
               "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2));
1274
1275
7.87k
    if ((ret = av_frame_ref(rframe, s->frame)) < 0)
1276
0
        return ret;
1277
1278
7.87k
    *got_frame = 1;
1279
1280
7.87k
    return buf_size;
1281
7.87k
}
1282
1283
static int flic_decode_frame(AVCodecContext *avctx, AVFrame *frame,
1284
                             int *got_frame, AVPacket *avpkt)
1285
146k
{
1286
146k
    const uint8_t *buf = avpkt->data;
1287
146k
    int buf_size = avpkt->size;
1288
146k
    if (avctx->pix_fmt == AV_PIX_FMT_MONOBLACK) {
1289
9.03k
        return flic_decode_frame_1BPP(avctx, frame, got_frame,
1290
9.03k
                                      buf, buf_size);
1291
137k
    } else if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1292
113k
        return flic_decode_frame_8BPP(avctx, frame, got_frame,
1293
113k
                                      buf, buf_size);
1294
113k
    } else if ((avctx->pix_fmt == AV_PIX_FMT_RGB555) ||
1295
23.9k
               (avctx->pix_fmt == AV_PIX_FMT_RGB565)) {
1296
12.2k
        return flic_decode_frame_15_16BPP(avctx, frame, got_frame,
1297
12.2k
                                          buf, buf_size);
1298
12.2k
    } else if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {
1299
11.6k
        return flic_decode_frame_24BPP(avctx, frame, got_frame,
1300
11.6k
                                       buf, buf_size);
1301
11.6k
    }
1302
1303
    /* Should not get  here, ever as the pix_fmt is processed */
1304
    /* in flic_decode_init and the above if should deal with */
1305
    /* the finite set of possibilities allowable by here. */
1306
    /* But in case we do, just error out. */
1307
0
    av_log(avctx, AV_LOG_ERROR, "Unknown FLC format, my science cannot explain how this happened.\n");
1308
0
    return AVERROR_BUG;
1309
146k
}
1310
1311
1312
static av_cold int flic_decode_end(AVCodecContext *avctx)
1313
2.63k
{
1314
2.63k
    FlicDecodeContext *s = avctx->priv_data;
1315
1316
2.63k
    av_frame_free(&s->frame);
1317
1318
2.63k
    return 0;
1319
2.63k
}
1320
1321
const FFCodec ff_flic_decoder = {
1322
    .p.name         = "flic",
1323
    CODEC_LONG_NAME("Autodesk Animator Flic video"),
1324
    .p.type         = AVMEDIA_TYPE_VIDEO,
1325
    .p.id           = AV_CODEC_ID_FLIC,
1326
    .priv_data_size = sizeof(FlicDecodeContext),
1327
    .init           = flic_decode_init,
1328
    .close          = flic_decode_end,
1329
    FF_CODEC_DECODE_CB(flic_decode_frame),
1330
    .p.capabilities = AV_CODEC_CAP_DR1,
1331
};