FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/flicvideo.c
Date: 2022-07-04 19:11:22
Exec Total Coverage
Lines: 186 605 30.7%
Branches: 110 411 26.8%

Line Branch Exec Source
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 <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40
41 #include "libavutil/intreadwrite.h"
42 #include "avcodec.h"
43 #include "bytestream.h"
44 #include "codec_internal.h"
45 #include "internal.h"
46 #include "mathops.h"
47
48 #define FLI_256_COLOR 4
49 #define FLI_DELTA 7
50 #define FLI_COLOR 11
51 #define FLI_LC 12
52 #define FLI_BLACK 13
53 #define FLI_BRUN 15
54 #define FLI_COPY 16
55 #define FLI_MINI 18
56 #define FLI_DTA_BRUN 25
57 #define FLI_DTA_COPY 26
58 #define FLI_DTA_LC 27
59
60 #define FLI_TYPE_CODE (0xAF11)
61 #define FLC_FLX_TYPE_CODE (0xAF12)
62 #define FLC_DTA_TYPE_CODE (0xAF44) /* Marks an "Extended FLC" comes from Dave's Targa Animator (DTA) */
63 #define FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE (0xAF13)
64
65 #define CHECK_PIXEL_PTR(n) \
66 if (pixel_ptr + n > pixel_limit) { \
67 av_log (s->avctx, AV_LOG_ERROR, "Invalid pixel_ptr = %d > pixel_limit = %d\n", \
68 pixel_ptr + n, pixel_limit); \
69 return AVERROR_INVALIDDATA; \
70 } \
71
72 typedef struct FlicDecodeContext {
73 AVCodecContext *avctx;
74 AVFrame *frame;
75
76 unsigned int palette[256];
77 int new_palette;
78 int fli_type; /* either 0xAF11 or 0xAF12, affects palette resolution */
79 } FlicDecodeContext;
80
81 8 static av_cold int flic_decode_init(AVCodecContext *avctx)
82 {
83 8 FlicDecodeContext *s = avctx->priv_data;
84 8 unsigned char *fli_header = (unsigned char *)avctx->extradata;
85 int depth;
86
87
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if (avctx->extradata_size != 0 &&
88
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
8 avctx->extradata_size != 12 &&
89
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 avctx->extradata_size != 128 &&
90 avctx->extradata_size != 256 &&
91 avctx->extradata_size != 904 &&
92 avctx->extradata_size != 1024) {
93 av_log(avctx, AV_LOG_ERROR, "Unexpected extradata size %d\n", avctx->extradata_size);
94 return AVERROR_INVALIDDATA;
95 }
96
97 8 s->avctx = avctx;
98
99
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
8 if (s->avctx->extradata_size == 12) {
100 /* special case for magic carpet FLIs */
101 2 s->fli_type = FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE;
102 2 depth = 8;
103
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 } else if (avctx->extradata_size == 1024) {
104 uint8_t *ptr = avctx->extradata;
105 int i;
106
107 for (i = 0; i < 256; i++) {
108 s->palette[i] = AV_RL32(ptr);
109 ptr += 4;
110 }
111 depth = 8;
112 /* FLI in MOV, see e.g. FFmpeg trac issue #626 */
113
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 } else if (avctx->extradata_size == 0 ||
114
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 avctx->extradata_size == 256 ||
115 /* see FFmpeg ticket #1234 */
116
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 avctx->extradata_size == 904) {
117 s->fli_type = FLI_TYPE_CODE;
118 depth = 8;
119 } else {
120 6 s->fli_type = AV_RL16(&fli_header[4]);
121 6 depth = AV_RL16(&fli_header[12]);
122 }
123
124
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (depth == 0) {
125 depth = 8; /* Some FLC generators set depth to zero, when they mean 8Bpp. Fix up here */
126 }
127
128
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
8 if ((s->fli_type == FLC_FLX_TYPE_CODE) && (depth == 16)) {
129 depth = 15; /* Original Autodesk FLX's say the depth is 16Bpp when it is really 15Bpp */
130 }
131
132
1/5
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
8 switch (depth) {
133 8 case 8 : avctx->pix_fmt = AV_PIX_FMT_PAL8; break;
134 case 15 : avctx->pix_fmt = AV_PIX_FMT_RGB555; break;
135 case 16 : avctx->pix_fmt = AV_PIX_FMT_RGB565; break;
136 case 24 : avctx->pix_fmt = AV_PIX_FMT_BGR24; break;
137 default :
138 av_log(avctx, AV_LOG_ERROR, "Unknown FLC/FLX depth of %d Bpp is unsupported.\n",depth);
139 return AVERROR_INVALIDDATA;
140 }
141
142 8 s->frame = av_frame_alloc();
143
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (!s->frame)
144 return AVERROR(ENOMEM);
145
146 8 s->new_palette = 0;
147
148 8 return 0;
149 }
150
151 501 static int flic_decode_frame_8BPP(AVCodecContext *avctx,
152 AVFrame *rframe, int *got_frame,
153 const uint8_t *buf, int buf_size)
154 {
155 501 FlicDecodeContext *s = avctx->priv_data;
156
157 GetByteContext g2;
158 int pixel_ptr;
159 int palette_ptr;
160 unsigned char palette_idx1;
161 unsigned char palette_idx2;
162
163 unsigned int frame_size;
164 int num_chunks;
165
166 unsigned int chunk_size;
167 int chunk_type;
168
169 int i, j, ret;
170
171 int color_packets;
172 int color_changes;
173 int color_shift;
174 unsigned char r, g, b;
175
176 int lines;
177 int compressed_lines;
178 int starting_line;
179 int line_packets;
180 int y_ptr;
181 int byte_run;
182 int pixel_skip;
183 int pixel_countdown;
184 unsigned char *pixels;
185 unsigned int pixel_limit;
186
187 501 bytestream2_init(&g2, buf, buf_size);
188
189
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 501 times.
501 if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
190 return ret;
191
192 501 pixels = s->frame->data[0];
193 501 pixel_limit = s->avctx->height * s->frame->linesize[0];
194
2/4
✓ Branch 0 taken 501 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 501 times.
501 if (buf_size < 16 || buf_size > INT_MAX - (3 * 256 + AV_INPUT_BUFFER_PADDING_SIZE))
195 return AVERROR_INVALIDDATA;
196 501 frame_size = bytestream2_get_le32(&g2);
197
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 501 times.
501 if (frame_size > buf_size)
198 frame_size = buf_size;
199 501 bytestream2_skip(&g2, 2); /* skip the magic number */
200 501 num_chunks = bytestream2_get_le16(&g2);
201 501 bytestream2_skip(&g2, 8); /* skip padding */
202
203
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 501 times.
501 if (frame_size < 16)
204 return AVERROR_INVALIDDATA;
205
206 501 frame_size -= 16;
207
208 /* iterate through the chunks */
209
4/6
✓ Branch 0 taken 524 times.
✓ Branch 1 taken 501 times.
✓ Branch 2 taken 524 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 524 times.
✗ Branch 5 not taken.
1549 while ((frame_size >= 6) && (num_chunks > 0) &&
210 524 bytestream2_get_bytes_left(&g2) >= 4) {
211 int stream_ptr_after_chunk;
212 524 chunk_size = bytestream2_get_le32(&g2);
213
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 524 times.
524 if (chunk_size > frame_size) {
214 av_log(avctx, AV_LOG_WARNING,
215 "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
216 chunk_size = frame_size;
217 }
218 524 stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
219
220 524 chunk_type = bytestream2_get_le16(&g2);
221
222
4/8
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 67 times.
✓ Branch 2 taken 411 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
524 switch (chunk_type) {
223 42 case FLI_256_COLOR:
224 case FLI_COLOR:
225 /* check special case: If this file is from the Magic Carpet
226 * game and uses 6-bit colors even though it reports 256-color
227 * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during
228 * initialization) */
229
4/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 40 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
42 if ((chunk_type == FLI_256_COLOR) && (s->fli_type != FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE))
230 1 color_shift = 0;
231 else
232 41 color_shift = 2;
233 /* set up the palette */
234 42 color_packets = bytestream2_get_le16(&g2);
235 42 palette_ptr = 0;
236
2/2
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 42 times.
297 for (i = 0; i < color_packets; i++) {
237 /* first byte is how many colors to skip */
238 255 palette_ptr += bytestream2_get_byte(&g2);
239
240 /* next byte indicates how many entries to change */
241 255 color_changes = bytestream2_get_byte(&g2);
242
243 /* if there are 0 color changes, there are actually 256 */
244
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 251 times.
255 if (color_changes == 0)
245 4 color_changes = 256;
246
247
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 255 times.
255 if (bytestream2_tell(&g2) + color_changes * 3 > stream_ptr_after_chunk)
248 break;
249
250
2/2
✓ Branch 0 taken 10388 times.
✓ Branch 1 taken 255 times.
10643 for (j = 0; j < color_changes; j++) {
251 unsigned int entry;
252
253 /* wrap around, for good measure */
254
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10388 times.
10388 if ((unsigned)palette_ptr >= 256)
255 palette_ptr = 0;
256
257 10388 r = bytestream2_get_byte(&g2) << color_shift;
258 10388 g = bytestream2_get_byte(&g2) << color_shift;
259 10388 b = bytestream2_get_byte(&g2) << color_shift;
260 10388 entry = 0xFFU << 24 | r << 16 | g << 8 | b;
261
2/2
✓ Branch 0 taken 10132 times.
✓ Branch 1 taken 256 times.
10388 if (color_shift == 2)
262 10132 entry |= entry >> 6 & 0x30303;
263
1/2
✓ Branch 0 taken 10388 times.
✗ Branch 1 not taken.
10388 if (s->palette[palette_ptr] != entry)
264 10388 s->new_palette = 1;
265 10388 s->palette[palette_ptr++] = entry;
266 }
267 }
268 42 break;
269
270 67 case FLI_DELTA:
271 67 y_ptr = 0;
272 67 compressed_lines = bytestream2_get_le16(&g2);
273
2/2
✓ Branch 0 taken 8221 times.
✓ Branch 1 taken 67 times.
8288 while (compressed_lines > 0) {
274
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8221 times.
8221 if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
275 break;
276
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8221 times.
8221 if (y_ptr > pixel_limit)
277 return AVERROR_INVALIDDATA;
278 8221 line_packets = sign_extend(bytestream2_get_le16(&g2), 16);
279
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 8113 times.
8221 if ((line_packets & 0xC000) == 0xC000) {
280 // line skip opcode
281 108 line_packets = -line_packets;
282
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if (line_packets > s->avctx->height)
283 return AVERROR_INVALIDDATA;
284 108 y_ptr += line_packets * s->frame->linesize[0];
285
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8113 times.
8113 } else if ((line_packets & 0xC000) == 0x4000) {
286 av_log(avctx, AV_LOG_ERROR, "Undefined opcode (%x) in DELTA_FLI\n", line_packets);
287
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8113 times.
8113 } else if ((line_packets & 0xC000) == 0x8000) {
288 // "last byte" opcode
289 pixel_ptr= y_ptr + s->frame->linesize[0] - 1;
290 CHECK_PIXEL_PTR(0);
291 pixels[pixel_ptr] = line_packets & 0xff;
292 } else {
293 8113 compressed_lines--;
294 8113 pixel_ptr = y_ptr;
295
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8113 times.
8113 CHECK_PIXEL_PTR(0);
296 8113 pixel_countdown = s->avctx->width;
297
2/2
✓ Branch 0 taken 124608 times.
✓ Branch 1 taken 8113 times.
132721 for (i = 0; i < line_packets; i++) {
298
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 124608 times.
124608 if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
299 break;
300 /* account for the skip bytes */
301 124608 pixel_skip = bytestream2_get_byte(&g2);
302 124608 pixel_ptr += pixel_skip;
303 124608 pixel_countdown -= pixel_skip;
304 124608 byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
305
2/2
✓ Branch 0 taken 37508 times.
✓ Branch 1 taken 87100 times.
124608 if (byte_run < 0) {
306 37508 byte_run = -byte_run;
307 37508 palette_idx1 = bytestream2_get_byte(&g2);
308 37508 palette_idx2 = bytestream2_get_byte(&g2);
309
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37508 times.
37508 CHECK_PIXEL_PTR(byte_run * 2);
310
2/2
✓ Branch 0 taken 182495 times.
✓ Branch 1 taken 37508 times.
220003 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
311 182495 pixels[pixel_ptr++] = palette_idx1;
312 182495 pixels[pixel_ptr++] = palette_idx2;
313 }
314 } else {
315
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 87100 times.
87100 CHECK_PIXEL_PTR(byte_run * 2);
316
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 87100 times.
87100 if (bytestream2_tell(&g2) + byte_run * 2 > stream_ptr_after_chunk)
317 break;
318
2/2
✓ Branch 0 taken 819286 times.
✓ Branch 1 taken 87100 times.
906386 for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
319 819286 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
320 }
321 }
322 }
323
324 8113 y_ptr += s->frame->linesize[0];
325 }
326 }
327 67 break;
328
329 411 case FLI_LC:
330 /* line compressed */
331 411 starting_line = bytestream2_get_le16(&g2);
332
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 411 times.
411 if (starting_line >= s->avctx->height)
333 return AVERROR_INVALIDDATA;
334 411 y_ptr = 0;
335 411 y_ptr += starting_line * s->frame->linesize[0];
336
337 411 compressed_lines = bytestream2_get_le16(&g2);
338
2/2
✓ Branch 0 taken 53266 times.
✓ Branch 1 taken 411 times.
53677 while (compressed_lines > 0) {
339 53266 pixel_ptr = y_ptr;
340
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53266 times.
53266 CHECK_PIXEL_PTR(0);
341 53266 pixel_countdown = s->avctx->width;
342
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 53266 times.
53266 if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
343 break;
344 53266 line_packets = bytestream2_get_byte(&g2);
345
2/2
✓ Branch 0 taken 48300 times.
✓ Branch 1 taken 4966 times.
53266 if (line_packets > 0) {
346
2/2
✓ Branch 0 taken 320826 times.
✓ Branch 1 taken 48300 times.
369126 for (i = 0; i < line_packets; i++) {
347 /* account for the skip bytes */
348
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 320826 times.
320826 if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
349 break;
350 320826 pixel_skip = bytestream2_get_byte(&g2);
351 320826 pixel_ptr += pixel_skip;
352 320826 pixel_countdown -= pixel_skip;
353 320826 byte_run = sign_extend(bytestream2_get_byte(&g2),8);
354
2/2
✓ Branch 0 taken 235604 times.
✓ Branch 1 taken 85222 times.
320826 if (byte_run > 0) {
355
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 235604 times.
235604 CHECK_PIXEL_PTR(byte_run);
356
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 235604 times.
235604 if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
357 break;
358
2/2
✓ Branch 0 taken 1364786 times.
✓ Branch 1 taken 235604 times.
1600390 for (j = 0; j < byte_run; j++, pixel_countdown--) {
359 1364786 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
360 }
361
1/2
✓ Branch 0 taken 85222 times.
✗ Branch 1 not taken.
85222 } else if (byte_run < 0) {
362 85222 byte_run = -byte_run;
363 85222 palette_idx1 = bytestream2_get_byte(&g2);
364
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 85222 times.
85222 CHECK_PIXEL_PTR(byte_run);
365
2/2
✓ Branch 0 taken 540390 times.
✓ Branch 1 taken 85222 times.
625612 for (j = 0; j < byte_run; j++, pixel_countdown--) {
366 540390 pixels[pixel_ptr++] = palette_idx1;
367 }
368 }
369 }
370 }
371
372 53266 y_ptr += s->frame->linesize[0];
373 53266 compressed_lines--;
374 }
375 411 break;
376
377 case FLI_BLACK:
378 /* set the whole frame to color 0 (which is usually black) */
379 memset(pixels, 0,
380 s->frame->linesize[0] * s->avctx->height);
381 break;
382
383 4 case FLI_BRUN:
384 /* Byte run compression: This chunk type only occurs in the first
385 * FLI frame and it will update the entire frame. */
386 4 y_ptr = 0;
387
2/2
✓ Branch 0 taken 1080 times.
✓ Branch 1 taken 4 times.
1084 for (lines = 0; lines < s->avctx->height; lines++) {
388 1080 pixel_ptr = y_ptr;
389 /* disregard the line packets; instead, iterate through all
390 * pixels on a row */
391 1080 bytestream2_skip(&g2, 1);
392 1080 pixel_countdown = s->avctx->width;
393
2/2
✓ Branch 0 taken 22787 times.
✓ Branch 1 taken 1080 times.
23867 while (pixel_countdown > 0) {
394
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 22787 times.
22787 if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
395 break;
396 22787 byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
397
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22787 times.
22787 if (!byte_run) {
398 av_log(avctx, AV_LOG_ERROR, "Invalid byte run value.\n");
399 return AVERROR_INVALIDDATA;
400 }
401
402
2/2
✓ Branch 0 taken 14467 times.
✓ Branch 1 taken 8320 times.
22787 if (byte_run > 0) {
403 14467 palette_idx1 = bytestream2_get_byte(&g2);
404
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14467 times.
14467 CHECK_PIXEL_PTR(byte_run);
405
2/2
✓ Branch 0 taken 478048 times.
✓ Branch 1 taken 14467 times.
492515 for (j = 0; j < byte_run; j++) {
406 478048 pixels[pixel_ptr++] = palette_idx1;
407 478048 pixel_countdown--;
408
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 478048 times.
478048 if (pixel_countdown < 0)
409 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
410 pixel_countdown, lines);
411 }
412 } else { /* copy bytes if byte_run < 0 */
413 8320 byte_run = -byte_run;
414
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8320 times.
8320 CHECK_PIXEL_PTR(byte_run);
415
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8320 times.
8320 if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
416 break;
417
2/2
✓ Branch 0 taken 21152 times.
✓ Branch 1 taken 8320 times.
29472 for (j = 0; j < byte_run; j++) {
418 21152 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
419 21152 pixel_countdown--;
420
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21152 times.
21152 if (pixel_countdown < 0)
421 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
422 pixel_countdown, lines);
423 }
424 }
425 }
426
427 1080 y_ptr += s->frame->linesize[0];
428 }
429 4 break;
430
431 case FLI_COPY:
432 /* copy the chunk (uncompressed frame) */
433 if (chunk_size - 6 != FFALIGN(s->avctx->width, 4) * s->avctx->height) {
434 av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
435 "has incorrect size, skipping chunk\n", chunk_size - 6);
436 bytestream2_skip(&g2, chunk_size - 6);
437 } else {
438 for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height;
439 y_ptr += s->frame->linesize[0]) {
440 bytestream2_get_buffer(&g2, &pixels[y_ptr],
441 s->avctx->width);
442 if (s->avctx->width & 3)
443 bytestream2_skip(&g2, 4 - (s->avctx->width & 3));
444 }
445 }
446 break;
447
448 case FLI_MINI:
449 /* some sort of a thumbnail? disregard this chunk... */
450 break;
451
452 default:
453 av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
454 break;
455 }
456
457
1/2
✓ Branch 1 taken 524 times.
✗ Branch 2 not taken.
524 if (stream_ptr_after_chunk - bytestream2_tell(&g2) >= 0) {
458 524 bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
459 } else {
460 av_log(avctx, AV_LOG_ERROR, "Chunk overread\n");
461 break;
462 }
463
464 524 frame_size -= chunk_size;
465 524 num_chunks--;
466 }
467
468 /* by the end of the chunk, the stream ptr should equal the frame
469 * size (minus 1 or 2, possibly); if it doesn't, issue a warning */
470
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 501 times.
501 if (bytestream2_get_bytes_left(&g2) > 2)
471 av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
472 "and final chunk ptr = %d\n", buf_size,
473 buf_size - bytestream2_get_bytes_left(&g2));
474
475 /* make the palette available on the way out */
476 501 memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE);
477
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 459 times.
501 if (s->new_palette) {
478 42 s->frame->palette_has_changed = 1;
479 42 s->new_palette = 0;
480 }
481
482
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 501 times.
501 if ((ret = av_frame_ref(rframe, s->frame)) < 0)
483 return ret;
484
485 501 *got_frame = 1;
486
487 501 return buf_size;
488 }
489
490 static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
491 AVFrame *rframe, int *got_frame,
492 const uint8_t *buf, int buf_size)
493 {
494 /* Note, the only difference between the 15Bpp and 16Bpp */
495 /* Format is the pixel format, the packets are processed the same. */
496 FlicDecodeContext *s = avctx->priv_data;
497
498 GetByteContext g2;
499 int pixel_ptr;
500 unsigned char palette_idx1;
501
502 unsigned int frame_size;
503 int num_chunks;
504
505 unsigned int chunk_size;
506 int chunk_type;
507
508 int i, j, ret;
509
510 int lines;
511 int compressed_lines;
512 int line_packets;
513 int y_ptr;
514 int byte_run;
515 int pixel_skip;
516 int pixel_countdown;
517 unsigned char *pixels;
518 int pixel;
519 unsigned int pixel_limit;
520
521 bytestream2_init(&g2, buf, buf_size);
522
523 if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
524 return ret;
525
526 pixels = s->frame->data[0];
527 pixel_limit = s->avctx->height * s->frame->linesize[0];
528
529 frame_size = bytestream2_get_le32(&g2);
530 bytestream2_skip(&g2, 2); /* skip the magic number */
531 num_chunks = bytestream2_get_le16(&g2);
532 bytestream2_skip(&g2, 8); /* skip padding */
533 if (frame_size > buf_size)
534 frame_size = buf_size;
535
536 if (frame_size < 16)
537 return AVERROR_INVALIDDATA;
538 frame_size -= 16;
539
540 /* iterate through the chunks */
541 while ((frame_size > 0) && (num_chunks > 0) &&
542 bytestream2_get_bytes_left(&g2) >= 4) {
543 int stream_ptr_after_chunk;
544 chunk_size = bytestream2_get_le32(&g2);
545 if (chunk_size > frame_size) {
546 av_log(avctx, AV_LOG_WARNING,
547 "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
548 chunk_size = frame_size;
549 }
550 stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
551
552 chunk_type = bytestream2_get_le16(&g2);
553
554
555 switch (chunk_type) {
556 case FLI_256_COLOR:
557 case FLI_COLOR:
558 /* For some reason, it seems that non-palettized flics do
559 * include one of these chunks in their first frame.
560 * Why I do not know, it seems rather extraneous. */
561 ff_dlog(avctx,
562 "Unexpected Palette chunk %d in non-palettized FLC\n",
563 chunk_type);
564 bytestream2_skip(&g2, chunk_size - 6);
565 break;
566
567 case FLI_DELTA:
568 case FLI_DTA_LC:
569 y_ptr = 0;
570 compressed_lines = bytestream2_get_le16(&g2);
571 while (compressed_lines > 0) {
572 if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
573 break;
574 if (y_ptr > pixel_limit)
575 return AVERROR_INVALIDDATA;
576 line_packets = sign_extend(bytestream2_get_le16(&g2), 16);
577 if (line_packets < 0) {
578 line_packets = -line_packets;
579 if (line_packets > s->avctx->height)
580 return AVERROR_INVALIDDATA;
581 y_ptr += line_packets * s->frame->linesize[0];
582 } else {
583 compressed_lines--;
584 pixel_ptr = y_ptr;
585 CHECK_PIXEL_PTR(0);
586 pixel_countdown = s->avctx->width;
587 for (i = 0; i < line_packets; i++) {
588 /* account for the skip bytes */
589 if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
590 break;
591 pixel_skip = bytestream2_get_byte(&g2);
592 pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */
593 pixel_countdown -= pixel_skip;
594 byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
595 if (byte_run < 0) {
596 byte_run = -byte_run;
597 pixel = bytestream2_get_le16(&g2);
598 CHECK_PIXEL_PTR(2 * byte_run);
599 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
600 *((signed short*)(&pixels[pixel_ptr])) = pixel;
601 pixel_ptr += 2;
602 }
603 } else {
604 if (bytestream2_tell(&g2) + 2*byte_run > stream_ptr_after_chunk)
605 break;
606 CHECK_PIXEL_PTR(2 * byte_run);
607 for (j = 0; j < byte_run; j++, pixel_countdown--) {
608 *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
609 pixel_ptr += 2;
610 }
611 }
612 }
613
614 y_ptr += s->frame->linesize[0];
615 }
616 }
617 break;
618
619 case FLI_LC:
620 av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-palettized FLC\n");
621 bytestream2_skip(&g2, chunk_size - 6);
622 break;
623
624 case FLI_BLACK:
625 /* set the whole frame to 0x0000 which is black in both 15Bpp and 16Bpp modes. */
626 memset(pixels, 0x0000,
627 s->frame->linesize[0] * s->avctx->height);
628 break;
629
630 case FLI_BRUN:
631 y_ptr = 0;
632 for (lines = 0; lines < s->avctx->height; lines++) {
633 pixel_ptr = y_ptr;
634 /* disregard the line packets; instead, iterate through all
635 * pixels on a row */
636 bytestream2_skip(&g2, 1);
637 pixel_countdown = (s->avctx->width * 2);
638
639 while (pixel_countdown > 0) {
640 if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
641 break;
642 byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
643 if (byte_run > 0) {
644 palette_idx1 = bytestream2_get_byte(&g2);
645 CHECK_PIXEL_PTR(byte_run);
646 for (j = 0; j < byte_run; j++) {
647 pixels[pixel_ptr++] = palette_idx1;
648 pixel_countdown--;
649 if (pixel_countdown < 0)
650 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) (linea%d)\n",
651 pixel_countdown, lines);
652 }
653 } else { /* copy bytes if byte_run < 0 */
654 byte_run = -byte_run;
655 if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
656 break;
657 CHECK_PIXEL_PTR(byte_run);
658 for (j = 0; j < byte_run; j++) {
659 palette_idx1 = bytestream2_get_byte(&g2);
660 pixels[pixel_ptr++] = palette_idx1;
661 pixel_countdown--;
662 if (pixel_countdown < 0)
663 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
664 pixel_countdown, lines);
665 }
666 }
667 }
668
669 /* Now FLX is strange, in that it is "byte" as opposed to "pixel" run length compressed.
670 * This does not give us any good opportunity to perform word endian conversion
671 * during decompression. So if it is required (i.e., this is not a LE target, we do
672 * a second pass over the line here, swapping the bytes.
673 */
674 #if HAVE_BIGENDIAN
675 pixel_ptr = y_ptr;
676 pixel_countdown = s->avctx->width;
677 while (pixel_countdown > 0) {
678 *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[pixel_ptr]);
679 pixel_ptr += 2;
680 }
681 #endif
682 y_ptr += s->frame->linesize[0];
683 }
684 break;
685
686 case FLI_DTA_BRUN:
687 y_ptr = 0;
688 for (lines = 0; lines < s->avctx->height; lines++) {
689 pixel_ptr = y_ptr;
690 /* disregard the line packets; instead, iterate through all
691 * pixels on a row */
692 bytestream2_skip(&g2, 1);
693 pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */
694
695 while (pixel_countdown > 0) {
696 if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
697 break;
698 byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
699 if (byte_run > 0) {
700 pixel = bytestream2_get_le16(&g2);
701 CHECK_PIXEL_PTR(2 * byte_run);
702 for (j = 0; j < byte_run; j++) {
703 *((signed short*)(&pixels[pixel_ptr])) = pixel;
704 pixel_ptr += 2;
705 pixel_countdown--;
706 if (pixel_countdown < 0)
707 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
708 pixel_countdown);
709 }
710 } else { /* copy pixels if byte_run < 0 */
711 byte_run = -byte_run;
712 if (bytestream2_tell(&g2) + 2 * byte_run > stream_ptr_after_chunk)
713 break;
714 CHECK_PIXEL_PTR(2 * byte_run);
715 for (j = 0; j < byte_run; j++) {
716 *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
717 pixel_ptr += 2;
718 pixel_countdown--;
719 if (pixel_countdown < 0)
720 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
721 pixel_countdown);
722 }
723 }
724 }
725
726 y_ptr += s->frame->linesize[0];
727 }
728 break;
729
730 case FLI_COPY:
731 case FLI_DTA_COPY:
732 /* copy the chunk (uncompressed frame) */
733 if (chunk_size - 6 > (unsigned int)(FFALIGN(s->avctx->width, 2) * s->avctx->height)*2) {
734 av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
735 "bigger than image, skipping chunk\n", chunk_size - 6);
736 bytestream2_skip(&g2, chunk_size - 6);
737 } else {
738
739 if (bytestream2_get_bytes_left(&g2) < 2 * s->avctx->width * s->avctx->height )
740 return AVERROR_INVALIDDATA;
741 for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height;
742 y_ptr += s->frame->linesize[0]) {
743
744 pixel_countdown = s->avctx->width;
745 pixel_ptr = 0;
746 while (pixel_countdown > 0) {
747 *((signed short*)(&pixels[y_ptr + pixel_ptr])) = bytestream2_get_le16(&g2);
748 pixel_ptr += 2;
749 pixel_countdown--;
750 }
751 if (s->avctx->width & 1)
752 bytestream2_skip(&g2, 2);
753 }
754 }
755 break;
756
757 case FLI_MINI:
758 /* some sort of a thumbnail? disregard this chunk... */
759 bytestream2_skip(&g2, chunk_size - 6);
760 break;
761
762 default:
763 av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
764 break;
765 }
766
767 if (stream_ptr_after_chunk - bytestream2_tell(&g2) >= 0) {
768 bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
769 } else {
770 av_log(avctx, AV_LOG_ERROR, "Chunk overread\n");
771 break;
772 }
773
774 frame_size -= chunk_size;
775 num_chunks--;
776 }
777
778 /* by the end of the chunk, the stream ptr should equal the frame
779 * size (minus 1, possibly); if it doesn't, issue a warning */
780 if ((bytestream2_get_bytes_left(&g2) != 0) && (bytestream2_get_bytes_left(&g2) != 1))
781 av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
782 "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2));
783
784 if ((ret = av_frame_ref(rframe, s->frame)) < 0)
785 return ret;
786
787 *got_frame = 1;
788
789 return buf_size;
790 }
791
792 static int flic_decode_frame_24BPP(AVCodecContext *avctx,
793 AVFrame *rframe, int *got_frame,
794 const uint8_t *buf, int buf_size)
795 {
796 FlicDecodeContext *s = avctx->priv_data;
797
798 GetByteContext g2;
799 int pixel_ptr;
800 unsigned char palette_idx1;
801
802 unsigned int frame_size;
803 int num_chunks;
804
805 unsigned int chunk_size;
806 int chunk_type;
807
808 int i, j, ret;
809
810 int lines;
811 int compressed_lines;
812 int line_packets;
813 int y_ptr;
814 int byte_run;
815 int pixel_skip;
816 int pixel_countdown;
817 unsigned char *pixels;
818 int pixel;
819 unsigned int pixel_limit;
820
821 bytestream2_init(&g2, buf, buf_size);
822
823 if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
824 return ret;
825
826 pixels = s->frame->data[0];
827 pixel_limit = s->avctx->height * s->frame->linesize[0];
828
829 frame_size = bytestream2_get_le32(&g2);
830 bytestream2_skip(&g2, 2); /* skip the magic number */
831 num_chunks = bytestream2_get_le16(&g2);
832 bytestream2_skip(&g2, 8); /* skip padding */
833 if (frame_size > buf_size)
834 frame_size = buf_size;
835
836 if (frame_size < 16)
837 return AVERROR_INVALIDDATA;
838 frame_size -= 16;
839
840 /* iterate through the chunks */
841 while ((frame_size > 0) && (num_chunks > 0) &&
842 bytestream2_get_bytes_left(&g2) >= 4) {
843 int stream_ptr_after_chunk;
844 chunk_size = bytestream2_get_le32(&g2);
845 if (chunk_size > frame_size) {
846 av_log(avctx, AV_LOG_WARNING,
847 "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
848 chunk_size = frame_size;
849 }
850 stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
851
852 chunk_type = bytestream2_get_le16(&g2);
853
854
855 switch (chunk_type) {
856 case FLI_256_COLOR:
857 case FLI_COLOR:
858 /* For some reason, it seems that non-palettized flics do
859 * include one of these chunks in their first frame.
860 * Why I do not know, it seems rather extraneous. */
861 ff_dlog(avctx,
862 "Unexpected Palette chunk %d in non-palettized FLC\n",
863 chunk_type);
864 bytestream2_skip(&g2, chunk_size - 6);
865 break;
866
867 case FLI_DELTA:
868 case FLI_DTA_LC:
869 y_ptr = 0;
870 compressed_lines = bytestream2_get_le16(&g2);
871 while (compressed_lines > 0) {
872 if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
873 break;
874 if (y_ptr > pixel_limit)
875 return AVERROR_INVALIDDATA;
876 line_packets = sign_extend(bytestream2_get_le16(&g2), 16);
877 if (line_packets < 0) {
878 line_packets = -line_packets;
879 if (line_packets > s->avctx->height)
880 return AVERROR_INVALIDDATA;
881 y_ptr += line_packets * s->frame->linesize[0];
882 } else {
883 compressed_lines--;
884 pixel_ptr = y_ptr;
885 CHECK_PIXEL_PTR(0);
886 pixel_countdown = s->avctx->width;
887 for (i = 0; i < line_packets; i++) {
888 /* account for the skip bytes */
889 if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
890 break;
891 pixel_skip = bytestream2_get_byte(&g2);
892 pixel_ptr += (pixel_skip*3); /* Pixel is 3 bytes wide */
893 pixel_countdown -= pixel_skip;
894 byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
895 if (byte_run < 0) {
896 byte_run = -byte_run;
897 pixel = bytestream2_get_le24(&g2);
898 CHECK_PIXEL_PTR(3 * byte_run);
899 for (j = 0; j < byte_run; j++, pixel_countdown -= 1) {
900 AV_WL24(&pixels[pixel_ptr], pixel);
901 pixel_ptr += 3;
902 }
903 } else {
904 if (bytestream2_tell(&g2) + 2*byte_run > stream_ptr_after_chunk)
905 break;
906 CHECK_PIXEL_PTR(3 * byte_run);
907 for (j = 0; j < byte_run; j++, pixel_countdown--) {
908 pixel = bytestream2_get_le24(&g2);
909 AV_WL24(&pixels[pixel_ptr], pixel);
910 pixel_ptr += 3;
911 }
912 }
913 }
914
915 y_ptr += s->frame->linesize[0];
916 }
917 }
918 break;
919
920 case FLI_LC:
921 av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-palettized FLC\n");
922 bytestream2_skip(&g2, chunk_size - 6);
923 break;
924
925 case FLI_BLACK:
926 /* set the whole frame to 0x00 which is black for 24 bit mode. */
927 memset(pixels, 0x00,
928 s->frame->linesize[0] * s->avctx->height);
929 break;
930
931 case FLI_BRUN:
932 y_ptr = 0;
933 for (lines = 0; lines < s->avctx->height; lines++) {
934 pixel_ptr = y_ptr;
935 /* disregard the line packets; instead, iterate through all
936 * pixels on a row */
937 bytestream2_skip(&g2, 1);
938 pixel_countdown = (s->avctx->width * 3);
939
940 while (pixel_countdown > 0) {
941 if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
942 break;
943 byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
944 if (byte_run > 0) {
945 palette_idx1 = bytestream2_get_byte(&g2);
946 CHECK_PIXEL_PTR(byte_run);
947 for (j = 0; j < byte_run; j++) {
948 pixels[pixel_ptr++] = palette_idx1;
949 pixel_countdown--;
950 if (pixel_countdown < 0)
951 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) (linea%d)\n",
952 pixel_countdown, lines);
953 }
954 } else { /* copy bytes if byte_run < 0 */
955 byte_run = -byte_run;
956 if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
957 break;
958 CHECK_PIXEL_PTR(byte_run);
959 for (j = 0; j < byte_run; j++) {
960 palette_idx1 = bytestream2_get_byte(&g2);
961 pixels[pixel_ptr++] = palette_idx1;
962 pixel_countdown--;
963 if (pixel_countdown < 0)
964 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
965 pixel_countdown, lines);
966 }
967 }
968 }
969
970 y_ptr += s->frame->linesize[0];
971 }
972 break;
973
974 case FLI_DTA_BRUN:
975 y_ptr = 0;
976 for (lines = 0; lines < s->avctx->height; lines++) {
977 pixel_ptr = y_ptr;
978 /* disregard the line packets; instead, iterate through all
979 * pixels on a row */
980 bytestream2_skip(&g2, 1);
981 pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */
982
983 while (pixel_countdown > 0) {
984 if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
985 break;
986 byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
987 if (byte_run > 0) {
988 pixel = bytestream2_get_le24(&g2);
989 CHECK_PIXEL_PTR(3 * byte_run);
990 for (j = 0; j < byte_run; j++) {
991 AV_WL24(pixels + pixel_ptr, pixel);
992 pixel_ptr += 3;
993 pixel_countdown--;
994 if (pixel_countdown < 0)
995 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
996 pixel_countdown);
997 }
998 } else { /* copy pixels if byte_run < 0 */
999 byte_run = -byte_run;
1000 if (bytestream2_tell(&g2) + 3 * byte_run > stream_ptr_after_chunk)
1001 break;
1002 CHECK_PIXEL_PTR(3 * byte_run);
1003 for (j = 0; j < byte_run; j++) {
1004 pixel = bytestream2_get_le24(&g2);
1005 AV_WL24(pixels + pixel_ptr, pixel);
1006 pixel_ptr += 3;
1007 pixel_countdown--;
1008 if (pixel_countdown < 0)
1009 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
1010 pixel_countdown);
1011 }
1012 }
1013 }
1014
1015 y_ptr += s->frame->linesize[0];
1016 }
1017 break;
1018
1019 case FLI_COPY:
1020 case FLI_DTA_COPY:
1021 /* copy the chunk (uncompressed frame) */
1022 if (chunk_size - 6 > (unsigned int)(FFALIGN(s->avctx->width, 2) * s->avctx->height)*3) {
1023 av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
1024 "bigger than image, skipping chunk\n", chunk_size - 6);
1025 bytestream2_skip(&g2, chunk_size - 6);
1026 } else {
1027 for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height;
1028 y_ptr += s->frame->linesize[0]) {
1029
1030 bytestream2_get_buffer(&g2, pixels + y_ptr, 3*s->avctx->width);
1031 if (s->avctx->width & 1)
1032 bytestream2_skip(&g2, 3);
1033 }
1034 }
1035 break;
1036
1037 case FLI_MINI:
1038 /* some sort of a thumbnail? disregard this chunk... */
1039 bytestream2_skip(&g2, chunk_size - 6);
1040 break;
1041
1042 default:
1043 av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
1044 break;
1045 }
1046
1047 if (stream_ptr_after_chunk - bytestream2_tell(&g2) >= 0) {
1048 bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
1049 } else {
1050 av_log(avctx, AV_LOG_ERROR, "Chunk overread\n");
1051 break;
1052 }
1053
1054 frame_size -= chunk_size;
1055 num_chunks--;
1056 }
1057
1058 /* by the end of the chunk, the stream ptr should equal the frame
1059 * size (minus 1, possibly); if it doesn't, issue a warning */
1060 if ((bytestream2_get_bytes_left(&g2) != 0) && (bytestream2_get_bytes_left(&g2) != 1))
1061 av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
1062 "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2));
1063
1064 if ((ret = av_frame_ref(rframe, s->frame)) < 0)
1065 return ret;
1066
1067 *got_frame = 1;
1068
1069 return buf_size;
1070 }
1071
1072 501 static int flic_decode_frame(AVCodecContext *avctx, AVFrame *frame,
1073 int *got_frame, AVPacket *avpkt)
1074 {
1075 501 const uint8_t *buf = avpkt->data;
1076 501 int buf_size = avpkt->size;
1077
1/2
✓ Branch 0 taken 501 times.
✗ Branch 1 not taken.
501 if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1078 501 return flic_decode_frame_8BPP(avctx, frame, got_frame,
1079 buf, buf_size);
1080 } else if ((avctx->pix_fmt == AV_PIX_FMT_RGB555) ||
1081 (avctx->pix_fmt == AV_PIX_FMT_RGB565)) {
1082 return flic_decode_frame_15_16BPP(avctx, frame, got_frame,
1083 buf, buf_size);
1084 } else if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {
1085 return flic_decode_frame_24BPP(avctx, frame, got_frame,
1086 buf, buf_size);
1087 }
1088
1089 /* Should not get here, ever as the pix_fmt is processed */
1090 /* in flic_decode_init and the above if should deal with */
1091 /* the finite set of possibilities allowable by here. */
1092 /* But in case we do, just error out. */
1093 av_log(avctx, AV_LOG_ERROR, "Unknown FLC format, my science cannot explain how this happened.\n");
1094 return AVERROR_BUG;
1095 }
1096
1097
1098 8 static av_cold int flic_decode_end(AVCodecContext *avctx)
1099 {
1100 8 FlicDecodeContext *s = avctx->priv_data;
1101
1102 8 av_frame_free(&s->frame);
1103
1104 8 return 0;
1105 }
1106
1107 const FFCodec ff_flic_decoder = {
1108 .p.name = "flic",
1109 .p.long_name = NULL_IF_CONFIG_SMALL("Autodesk Animator Flic video"),
1110 .p.type = AVMEDIA_TYPE_VIDEO,
1111 .p.id = AV_CODEC_ID_FLIC,
1112 .priv_data_size = sizeof(FlicDecodeContext),
1113 .init = flic_decode_init,
1114 .close = flic_decode_end,
1115 FF_CODEC_DECODE_CB(flic_decode_frame),
1116 .p.capabilities = AV_CODEC_CAP_DR1,
1117 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
1118 };
1119