FFmpeg
Loading...
Searching...
No Matches
flicvideo.c
Go to the documentation of this file.
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
40#include "avcodec.h"
41#include "bytestream.h"
42#include "codec_internal.h"
43#include "decode.h"
44#include "mathops.h"
45
46#define FLI_256_COLOR 4
47#define FLI_DELTA 7
48#define FLI_COLOR 11
49#define FLI_LC 12
50#define FLI_BLACK 13
51#define FLI_BRUN 15
52#define FLI_COPY 16
53#define FLI_MINI 18
54#define FLI_DTA_BRUN 25
55#define FLI_DTA_COPY 26
56#define FLI_DTA_LC 27
57
58#define FLI_TYPE_CODE (0xAF11)
59#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#define FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE (0xAF13)
62
63static inline int check_pixel_ptr(ptrdiff_t ptr, int n,
64 ptrdiff_t limit, int direction)
65{
66 if (( direction && ptr + n > limit) ||
67 (!direction && ptr + n < limit))
69 return 0;
70}
71
72#define CHECK_PIXEL_PTR(n) \
73{ \
74 ret = check_pixel_ptr(pixel_ptr, (n), pixel_limit, direction); \
75 if (ret < 0) \
76 return ret; \
77}
78
79#define CHECK_Y_PTR() \
80{ \
81 ret = check_pixel_ptr(y_ptr, 0, pixel_limit, direction); \
82 if (ret < 0) \
83 return ret; \
84}
85
86typedef struct FlicDecodeContext {
89
90 unsigned int palette[256];
92 int fli_type; /* either 0xAF11 or 0xAF12, affects palette resolution */
94
96{
98 uint8_t *fli_header = avctx->extradata;
99 int depth;
100
101 if (avctx->extradata_size != 0 &&
102 avctx->extradata_size != 12 &&
103 avctx->extradata_size != 128 &&
104 avctx->extradata_size != 256 &&
105 avctx->extradata_size != 904 &&
106 avctx->extradata_size != 1024) {
107 av_log(avctx, AV_LOG_ERROR, "Unexpected extradata size %d\n", avctx->extradata_size);
108 return AVERROR_INVALIDDATA;
109 }
110
111 s->avctx = avctx;
112
113 if (s->avctx->extradata_size == 12) {
114 /* special case for magic carpet FLIs */
116 depth = 8;
117 } else if (avctx->extradata_size == 1024) {
118 uint8_t *ptr = avctx->extradata;
119 int i;
120
121 for (i = 0; i < 256; i++) {
122 s->palette[i] = AV_RL32(ptr);
123 ptr += 4;
124 }
125 depth = 8;
126 /* FLI in MOV, see e.g. FFmpeg trac issue #626 */
127 } else if (avctx->extradata_size == 0 ||
128 avctx->extradata_size == 256 ||
129 /* see FFmpeg ticket #1234 */
130 avctx->extradata_size == 904) {
131 s->fli_type = FLI_TYPE_CODE;
132 depth = 8;
133 } else {
134 s->fli_type = AV_RL16(&fli_header[4]);
135 depth = AV_RL16(&fli_header[12]);
136 }
137
138 if (depth == 0) {
139 depth = 8; /* Some FLC generators set depth to zero, when they mean 8Bpp. Fix up here */
140 }
141
142 if ((s->fli_type == FLC_FLX_TYPE_CODE) && (depth == 16)) {
143 depth = 15; /* Original Autodesk FLX's say the depth is 16Bpp when it is really 15Bpp */
144 }
145
146 switch (depth) {
147 case 1 : avctx->pix_fmt = AV_PIX_FMT_MONOBLACK; break;
148 case 8 : avctx->pix_fmt = AV_PIX_FMT_PAL8; break;
149 case 15 : avctx->pix_fmt = AV_PIX_FMT_RGB555; break;
150 case 16 : avctx->pix_fmt = AV_PIX_FMT_RGB565; break;
151 case 24 : avctx->pix_fmt = AV_PIX_FMT_BGR24; break;
152 default :
153 av_log(avctx, AV_LOG_ERROR, "Unknown FLC/FLX depth of %d Bpp is unsupported.\n",depth);
154 return AVERROR_INVALIDDATA;
155 }
156
157 s->frame = av_frame_alloc();
158 if (!s->frame)
159 return AVERROR(ENOMEM);
160
161 s->new_palette = 0;
162
163 return 0;
164}
165
167 AVFrame *rframe, int *got_frame,
168 const uint8_t *buf, int buf_size)
169{
170 FlicDecodeContext *s = avctx->priv_data;
171
173 ptrdiff_t pixel_ptr;
174
175 unsigned int frame_size;
176 int num_chunks;
177
178 unsigned int chunk_size;
179 int chunk_type;
180
181 int i, j, ret, direction;
182
183 int lines;
184 int compressed_lines;
185 int starting_line;
186 int line_packets;
187 ptrdiff_t y_ptr;
188 int byte_run;
189 int pixel_skip;
190 int pixel_countdown;
191 unsigned char *pixels;
192 ptrdiff_t pixel_limit;
193
194 bytestream2_init(&g2, buf, buf_size);
195
196 if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
197 return ret;
198
199 direction = s->frame->linesize[0] > 0;
200 pixels = s->frame->data[0];
201 pixel_limit = s->avctx->height * s->frame->linesize[0];
202 if (buf_size < 16 || buf_size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
203 return AVERROR_INVALIDDATA;
204 frame_size = bytestream2_get_le32(&g2);
205 if (frame_size > buf_size)
206 frame_size = buf_size;
207 bytestream2_skip(&g2, 2); /* skip the magic number */
208 num_chunks = bytestream2_get_le16(&g2);
209 bytestream2_skip(&g2, 8); /* skip padding */
210
211 if (frame_size < 16)
212 return AVERROR_INVALIDDATA;
213
214 frame_size -= 16;
215
216 /* iterate through the chunks */
217 while ((frame_size >= 6) && (num_chunks > 0) &&
218 bytestream2_get_bytes_left(&g2) >= 4) {
219 int stream_ptr_after_chunk;
220 chunk_size = bytestream2_get_le32(&g2);
221 if (chunk_size > frame_size) {
222 av_log(avctx, AV_LOG_WARNING,
223 "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
224 chunk_size = frame_size;
225 }
226 stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
227
228 chunk_type = bytestream2_get_le16(&g2);
229
230 switch (chunk_type) {
231 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 y_ptr = 0;
235 for (lines = 0; lines < s->avctx->height; lines++) {
236 pixel_ptr = y_ptr;
237 /* disregard the line packets; instead, iterate through all
238 * pixels on a row */
239 bytestream2_skip(&g2, 1);
240 pixel_countdown = (s->avctx->width + 7) >> 3;
241 while (pixel_countdown > 0) {
242 if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
243 break;
244 byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
245 if (!byte_run) {
246 av_log(avctx, AV_LOG_ERROR, "Invalid byte run value.\n");
247 return AVERROR_INVALIDDATA;
248 }
249
250 if (byte_run > 0) {
251 int value = bytestream2_get_byte(&g2);
252 CHECK_PIXEL_PTR(byte_run);
253 for (j = 0; j < byte_run; j++) {
254 pixels[pixel_ptr++] = value;
255 pixel_countdown--;
256 if (pixel_countdown < 0)
257 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
258 pixel_countdown, lines);
259 }
260 } else { /* copy bytes if byte_run < 0 */
261 byte_run = -byte_run;
262 CHECK_PIXEL_PTR(byte_run);
263 if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
264 break;
265 for (j = 0; j < byte_run; j++) {
266 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
267 pixel_countdown--;
268 if (pixel_countdown < 0)
269 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
270 pixel_countdown, lines);
271 }
272 }
273 }
274
275 y_ptr += s->frame->linesize[0];
276 }
277 break;
278
279 case FLI_LC:
280 /* line compressed */
281 starting_line = bytestream2_get_le16(&g2);
282 if (starting_line >= s->avctx->height)
283 return AVERROR_INVALIDDATA;
284 y_ptr = 0;
285 y_ptr += starting_line * s->frame->linesize[0];
286
287 compressed_lines = bytestream2_get_le16(&g2);
288 while (compressed_lines > 0) {
289 pixel_ptr = y_ptr;
291 pixel_countdown = (s->avctx->width + 7) >> 3;
292 if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
293 break;
294 line_packets = bytestream2_get_byte(&g2);
295 if (line_packets > 0) {
296 for (i = 0; i < line_packets; i++) {
297 /* account for the skip bytes */
298 if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
299 break;
300 pixel_skip = bytestream2_get_byte(&g2);
301 pixel_ptr += pixel_skip;
302 pixel_countdown -= pixel_skip;
303 byte_run = sign_extend(bytestream2_get_byte(&g2),8);
304 if (byte_run > 0) {
305 CHECK_PIXEL_PTR(byte_run);
306 if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
307 break;
308 for (j = 0; j < byte_run; j++, pixel_countdown--) {
309 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
310 }
311 } else if (byte_run < 0) {
312 int value = bytestream2_get_byte(&g2);
313 byte_run = -byte_run;
314 CHECK_PIXEL_PTR(byte_run);
315 for (j = 0; j < byte_run; j++, pixel_countdown--) {
316 pixels[pixel_ptr++] = value;
317 }
318 }
319 }
320 }
321
322 y_ptr += s->frame->linesize[0];
323 compressed_lines--;
324 }
325 break;
326
327 default:
328 av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
329 break;
330 }
331
332 if (stream_ptr_after_chunk - bytestream2_tell(&g2) >= 0) {
333 bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
334 } else {
335 av_log(avctx, AV_LOG_ERROR, "Chunk overread\n");
336 break;
337 }
338
339 frame_size -= chunk_size;
340 num_chunks--;
341 }
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 if (bytestream2_get_bytes_left(&g2) > 2)
346 av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
347 "and final chunk ptr = %d\n", buf_size,
348 buf_size - bytestream2_get_bytes_left(&g2));
349
350 if ((ret = av_frame_ref(rframe, s->frame)) < 0)
351 return ret;
352
353 *got_frame = 1;
354
355 return buf_size;
356}
357
359 AVFrame *rframe, int *got_frame,
360 const uint8_t *buf, int buf_size)
361{
362 FlicDecodeContext *s = avctx->priv_data;
363
365 ptrdiff_t pixel_ptr;
366 int palette_ptr;
367 unsigned char palette_idx1;
368 unsigned char palette_idx2;
369
370 unsigned int frame_size;
371 int num_chunks;
372
373 unsigned int chunk_size;
374 int chunk_type;
375
376 int i, j, ret, direction;
377
378 int color_packets;
379 int color_changes;
380 int color_shift;
381 unsigned char r, g, b;
382
383 int lines;
384 int compressed_lines;
385 int starting_line;
386 int line_packets;
387 ptrdiff_t y_ptr;
388 int byte_run;
389 int pixel_skip;
390 int pixel_countdown;
391 unsigned char *pixels;
392 ptrdiff_t pixel_limit;
393
394 bytestream2_init(&g2, buf, buf_size);
395
396 if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
397 return ret;
398
399 direction = s->frame->linesize[0] > 0;
400 pixels = s->frame->data[0];
401 pixel_limit = s->avctx->height * s->frame->linesize[0];
402 if (buf_size < 16 || buf_size > INT_MAX - (3 * 256 + AV_INPUT_BUFFER_PADDING_SIZE))
403 return AVERROR_INVALIDDATA;
404 frame_size = bytestream2_get_le32(&g2);
405 if (frame_size > buf_size)
406 frame_size = buf_size;
407 bytestream2_skip(&g2, 2); /* skip the magic number */
408 num_chunks = bytestream2_get_le16(&g2);
409 bytestream2_skip(&g2, 8); /* skip padding */
410
411 if (frame_size < 16)
412 return AVERROR_INVALIDDATA;
413
414 frame_size -= 16;
415
416 /* iterate through the chunks */
417 while ((frame_size >= 6) && (num_chunks > 0) &&
418 bytestream2_get_bytes_left(&g2) >= 4) {
419 int stream_ptr_after_chunk;
420 chunk_size = bytestream2_get_le32(&g2);
421 if (chunk_size > frame_size) {
422 av_log(avctx, AV_LOG_WARNING,
423 "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
424 chunk_size = frame_size;
425 }
426 stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
427
428 chunk_type = bytestream2_get_le16(&g2);
429
430 switch (chunk_type) {
431 case FLI_256_COLOR:
432 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 if ((chunk_type == FLI_256_COLOR) && (s->fli_type != FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE))
438 color_shift = 0;
439 else
440 color_shift = 2;
441 /* set up the palette */
442 color_packets = bytestream2_get_le16(&g2);
443 palette_ptr = 0;
444 for (i = 0; i < color_packets; i++) {
445 /* first byte is how many colors to skip */
446 palette_ptr += bytestream2_get_byte(&g2);
447
448 /* next byte indicates how many entries to change */
449 color_changes = bytestream2_get_byte(&g2);
450
451 /* if there are 0 color changes, there are actually 256 */
452 if (color_changes == 0)
453 color_changes = 256;
454
455 if (bytestream2_tell(&g2) + color_changes * 3 > stream_ptr_after_chunk)
456 break;
457
458 for (j = 0; j < color_changes; j++) {
459 unsigned int entry;
460
461 /* wrap around, for good measure */
462 if ((unsigned)palette_ptr >= 256)
463 palette_ptr = 0;
464
465 r = bytestream2_get_byte(&g2) << color_shift;
466 g = bytestream2_get_byte(&g2) << color_shift;
467 b = bytestream2_get_byte(&g2) << color_shift;
468 entry = 0xFFU << 24 | r << 16 | g << 8 | b;
469 if (color_shift == 2)
470 entry |= entry >> 6 & 0x30303;
471 if (s->palette[palette_ptr] != entry)
472 s->new_palette = 1;
473 s->palette[palette_ptr++] = entry;
474 }
475 }
476 break;
477
478 case FLI_DELTA:
479 y_ptr = 0;
480 compressed_lines = bytestream2_get_le16(&g2);
481 while (compressed_lines > 0) {
482 if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
483 break;
485 line_packets = sign_extend(bytestream2_get_le16(&g2), 16);
486 if ((line_packets & 0xC000) == 0xC000) {
487 // line skip opcode
488 line_packets = -line_packets;
489 if (line_packets > s->avctx->height)
490 return AVERROR_INVALIDDATA;
491 y_ptr += line_packets * s->frame->linesize[0];
492 } else if ((line_packets & 0xC000) == 0x4000) {
493 av_log(avctx, AV_LOG_ERROR, "Undefined opcode (%x) in DELTA_FLI\n", line_packets);
494 } else if ((line_packets & 0xC000) == 0x8000) {
495 // "last byte" opcode
496 pixel_ptr= y_ptr + s->frame->linesize[0] - 1;
498 pixels[pixel_ptr] = line_packets & 0xff;
499 } else {
500 compressed_lines--;
501 pixel_ptr = y_ptr;
503 pixel_countdown = s->avctx->width;
504 for (i = 0; i < line_packets; i++) {
505 if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
506 break;
507 /* account for the skip bytes */
508 pixel_skip = bytestream2_get_byte(&g2);
509 pixel_ptr += pixel_skip;
510 pixel_countdown -= pixel_skip;
511 byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
512 if (byte_run < 0) {
513 byte_run = -byte_run;
514 palette_idx1 = bytestream2_get_byte(&g2);
515 palette_idx2 = bytestream2_get_byte(&g2);
516 CHECK_PIXEL_PTR(byte_run * 2);
517 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
518 pixels[pixel_ptr++] = palette_idx1;
519 pixels[pixel_ptr++] = palette_idx2;
520 }
521 } else {
522 CHECK_PIXEL_PTR(byte_run * 2);
523 if (bytestream2_tell(&g2) + byte_run * 2 > stream_ptr_after_chunk)
524 break;
525 for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
526 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
527 }
528 }
529 }
530
531 y_ptr += s->frame->linesize[0];
532 }
533 }
534 break;
535
536 case FLI_LC:
537 /* line compressed */
538 starting_line = bytestream2_get_le16(&g2);
539 if (starting_line >= s->avctx->height)
540 return AVERROR_INVALIDDATA;
541 y_ptr = 0;
542 y_ptr += starting_line * s->frame->linesize[0];
543
544 compressed_lines = bytestream2_get_le16(&g2);
545 while (compressed_lines > 0) {
546 pixel_ptr = y_ptr;
548 pixel_countdown = s->avctx->width;
549 if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
550 break;
551 line_packets = bytestream2_get_byte(&g2);
552 if (line_packets > 0) {
553 for (i = 0; i < line_packets; i++) {
554 /* account for the skip bytes */
555 if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
556 break;
557 pixel_skip = bytestream2_get_byte(&g2);
558 pixel_ptr += pixel_skip;
559 pixel_countdown -= pixel_skip;
560 byte_run = sign_extend(bytestream2_get_byte(&g2),8);
561 if (byte_run > 0) {
562 CHECK_PIXEL_PTR(byte_run);
563 if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
564 break;
565 for (j = 0; j < byte_run; j++, pixel_countdown--) {
566 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
567 }
568 } else if (byte_run < 0) {
569 byte_run = -byte_run;
570 palette_idx1 = bytestream2_get_byte(&g2);
571 CHECK_PIXEL_PTR(byte_run);
572 for (j = 0; j < byte_run; j++, pixel_countdown--) {
573 pixels[pixel_ptr++] = palette_idx1;
574 }
575 }
576 }
577 }
578
579 y_ptr += s->frame->linesize[0];
580 compressed_lines--;
581 }
582 break;
583
584 case FLI_BLACK:
585 /* set the whole frame to color 0 (which is usually black) */
586 for (int y = 0; y < s->avctx->height; y++)
587 memset(pixels + y * s->frame->linesize[0], 0, s->avctx->width);
588 break;
589
590 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 y_ptr = 0;
594 for (lines = 0; lines < s->avctx->height; lines++) {
595 pixel_ptr = y_ptr;
596 /* disregard the line packets; instead, iterate through all
597 * pixels on a row */
598 bytestream2_skip(&g2, 1);
599 pixel_countdown = s->avctx->width;
600 while (pixel_countdown > 0) {
601 if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
602 break;
603 byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
604 if (!byte_run) {
605 av_log(avctx, AV_LOG_ERROR, "Invalid byte run value.\n");
606 return AVERROR_INVALIDDATA;
607 }
608
609 if (byte_run > 0) {
610 palette_idx1 = bytestream2_get_byte(&g2);
611 CHECK_PIXEL_PTR(byte_run);
612 for (j = 0; j < byte_run; j++) {
613 pixels[pixel_ptr++] = palette_idx1;
614 pixel_countdown--;
615 if (pixel_countdown < 0)
616 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
617 pixel_countdown, lines);
618 }
619 } else { /* copy bytes if byte_run < 0 */
620 byte_run = -byte_run;
621 CHECK_PIXEL_PTR(byte_run);
622 if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
623 break;
624 for (j = 0; j < byte_run; j++) {
625 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
626 pixel_countdown--;
627 if (pixel_countdown < 0)
628 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
629 pixel_countdown, lines);
630 }
631 }
632 }
633
634 y_ptr += s->frame->linesize[0];
635 }
636 break;
637
638 case FLI_COPY:
639 /* copy the chunk (uncompressed frame) */
640 if (chunk_size - 6 != FFALIGN(s->avctx->width, 4) * s->avctx->height) {
641 av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
642 "has incorrect size, skipping chunk\n", chunk_size - 6);
643 bytestream2_skip(&g2, chunk_size - 6);
644 } else {
645 for (y_ptr = 0; check_pixel_ptr(y_ptr, s->avctx->width, pixel_limit, direction) == 0;
646 y_ptr += s->frame->linesize[0]) {
647 bytestream2_get_buffer(&g2, &pixels[y_ptr],
648 s->avctx->width);
649 if (s->avctx->width & 3)
650 bytestream2_skip(&g2, 4 - (s->avctx->width & 3));
651 }
652 }
653 break;
654
655 case FLI_MINI:
656 /* some sort of a thumbnail? disregard this chunk... */
657 break;
658
659 default:
660 av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
661 break;
662 }
663
664 if (stream_ptr_after_chunk - bytestream2_tell(&g2) >= 0) {
665 bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
666 } else {
667 av_log(avctx, AV_LOG_ERROR, "Chunk overread\n");
668 break;
669 }
670
671 frame_size -= chunk_size;
672 num_chunks--;
673 }
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 if (bytestream2_get_bytes_left(&g2) > 2)
678 av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
679 "and final chunk ptr = %d\n", buf_size,
680 buf_size - bytestream2_get_bytes_left(&g2));
681
682 /* make the palette available on the way out */
683 memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE);
684 if (s->new_palette) {
685 s->new_palette = 0;
686 }
687
688 if ((ret = av_frame_ref(rframe, s->frame)) < 0)
689 return ret;
690
691 *got_frame = 1;
692
693 return buf_size;
694}
695
697 AVFrame *rframe, int *got_frame,
698 const uint8_t *buf, int buf_size)
699{
700 /* Note, the only difference between the 15Bpp and 16Bpp */
701 /* Format is the pixel format, the packets are processed the same. */
702 FlicDecodeContext *s = avctx->priv_data;
703
705 ptrdiff_t pixel_ptr;
706 unsigned char palette_idx1;
707
708 unsigned int frame_size;
709 int num_chunks;
710
711 unsigned int chunk_size;
712 int chunk_type;
713
714 int i, j, ret, direction;
715
716 int lines;
717 int compressed_lines;
718 int line_packets;
719 ptrdiff_t y_ptr;
720 int byte_run;
721 int pixel_skip;
722 int pixel_countdown;
723 unsigned char *pixels;
724 int pixel;
725 ptrdiff_t pixel_limit;
726
727 bytestream2_init(&g2, buf, buf_size);
728
729 if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
730 return ret;
731
732 direction = s->frame->linesize[0] > 0;
733 pixels = s->frame->data[0];
734 pixel_limit = s->avctx->height * s->frame->linesize[0];
735
736 frame_size = bytestream2_get_le32(&g2);
737 bytestream2_skip(&g2, 2); /* skip the magic number */
738 num_chunks = bytestream2_get_le16(&g2);
739 bytestream2_skip(&g2, 8); /* skip padding */
740 if (frame_size > buf_size)
741 frame_size = buf_size;
742
743 if (frame_size < 16)
744 return AVERROR_INVALIDDATA;
745 frame_size -= 16;
746
747 /* iterate through the chunks */
748 while ((frame_size > 0) && (num_chunks > 0) &&
749 bytestream2_get_bytes_left(&g2) >= 4) {
750 int stream_ptr_after_chunk;
751 chunk_size = bytestream2_get_le32(&g2);
752 if (chunk_size > frame_size) {
753 av_log(avctx, AV_LOG_WARNING,
754 "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
755 chunk_size = frame_size;
756 }
757 stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
758
759 chunk_type = bytestream2_get_le16(&g2);
760
761
762 switch (chunk_type) {
763 case FLI_256_COLOR:
764 case FLI_COLOR:
765 /* For some reason, it seems that non-palettized flics do
766 * include one of these chunks in their first frame.
767 * Why I do not know, it seems rather extraneous. */
768 ff_dlog(avctx,
769 "Unexpected Palette chunk %d in non-palettized FLC\n",
770 chunk_type);
771 bytestream2_skip(&g2, chunk_size - 6);
772 break;
773
774 case FLI_DELTA:
775 case FLI_DTA_LC:
776 y_ptr = 0;
777 compressed_lines = bytestream2_get_le16(&g2);
778 while (compressed_lines > 0) {
779 if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
780 break;
782 line_packets = sign_extend(bytestream2_get_le16(&g2), 16);
783 if (line_packets < 0) {
784 line_packets = -line_packets;
785 if (line_packets > s->avctx->height)
786 return AVERROR_INVALIDDATA;
787 y_ptr += line_packets * s->frame->linesize[0];
788 } else {
789 compressed_lines--;
790 pixel_ptr = y_ptr;
792 pixel_countdown = s->avctx->width;
793 for (i = 0; i < line_packets; i++) {
794 /* account for the skip bytes */
795 if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
796 break;
797 pixel_skip = bytestream2_get_byte(&g2);
798 pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */
799 pixel_countdown -= pixel_skip;
800 byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
801 if (byte_run < 0) {
802 byte_run = -byte_run;
803 pixel = bytestream2_get_le16(&g2);
804 CHECK_PIXEL_PTR(2 * byte_run);
805 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
806 *((signed short*)(&pixels[pixel_ptr])) = pixel;
807 pixel_ptr += 2;
808 }
809 } else {
810 if (bytestream2_tell(&g2) + 2*byte_run > stream_ptr_after_chunk)
811 break;
812 CHECK_PIXEL_PTR(2 * byte_run);
813 for (j = 0; j < byte_run; j++, pixel_countdown--) {
814 *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
815 pixel_ptr += 2;
816 }
817 }
818 }
819
820 y_ptr += s->frame->linesize[0];
821 }
822 }
823 break;
824
825 case FLI_LC:
826 av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-palettized FLC\n");
827 bytestream2_skip(&g2, chunk_size - 6);
828 break;
829
830 case FLI_BLACK:
831 /* set the whole frame to 0x0000 which is black in both 15Bpp and 16Bpp modes. */
832 for (int y = 0; y < s->avctx->height; y++)
833 memset(pixels + y * s->frame->linesize[0], 0, s->avctx->width * 2);
834 break;
835
836 case FLI_BRUN:
837 y_ptr = 0;
838 for (lines = 0; lines < s->avctx->height; lines++) {
839 pixel_ptr = y_ptr;
840 /* disregard the line packets; instead, iterate through all
841 * pixels on a row */
842 bytestream2_skip(&g2, 1);
843 pixel_countdown = (s->avctx->width * 2);
844
845 while (pixel_countdown > 0) {
846 if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
847 break;
848 byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
849 if (byte_run > 0) {
850 palette_idx1 = bytestream2_get_byte(&g2);
851 CHECK_PIXEL_PTR(byte_run);
852 for (j = 0; j < byte_run; j++) {
853 pixels[pixel_ptr++] = palette_idx1;
854 pixel_countdown--;
855 if (pixel_countdown < 0)
856 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) (linea%d)\n",
857 pixel_countdown, lines);
858 }
859 } else { /* copy bytes if byte_run < 0 */
860 byte_run = -byte_run;
861 if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
862 break;
863 CHECK_PIXEL_PTR(byte_run);
864 for (j = 0; j < byte_run; j++) {
865 palette_idx1 = bytestream2_get_byte(&g2);
866 pixels[pixel_ptr++] = palette_idx1;
867 pixel_countdown--;
868 if (pixel_countdown < 0)
869 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
870 pixel_countdown, lines);
871 }
872 }
873 }
874
875 /* Now FLX is strange, in that it is "byte" as opposed to "pixel" run length compressed.
876 * This does not give us any good opportunity to perform word endian conversion
877 * during decompression. So if it is required (i.e., this is not a LE target, we do
878 * a second pass over the line here, swapping the bytes.
879 */
880#if HAVE_BIGENDIAN
881 pixel_ptr = y_ptr;
882 pixel_countdown = s->avctx->width;
883 while (pixel_countdown > 0) {
884 *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[pixel_ptr]);
885 pixel_ptr += 2;
886 }
887#endif
888 y_ptr += s->frame->linesize[0];
889 }
890 break;
891
892 case FLI_DTA_BRUN:
893 y_ptr = 0;
894 for (lines = 0; lines < s->avctx->height; lines++) {
895 pixel_ptr = y_ptr;
896 /* disregard the line packets; instead, iterate through all
897 * pixels on a row */
898 bytestream2_skip(&g2, 1);
899 pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */
900
901 while (pixel_countdown > 0) {
902 if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
903 break;
904 byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
905 if (byte_run > 0) {
906 pixel = bytestream2_get_le16(&g2);
907 CHECK_PIXEL_PTR(2 * byte_run);
908 for (j = 0; j < byte_run; j++) {
909 *((signed short*)(&pixels[pixel_ptr])) = pixel;
910 pixel_ptr += 2;
911 pixel_countdown--;
912 if (pixel_countdown < 0)
913 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
914 pixel_countdown);
915 }
916 } else { /* copy pixels if byte_run < 0 */
917 byte_run = -byte_run;
918 if (bytestream2_tell(&g2) + 2 * byte_run > stream_ptr_after_chunk)
919 break;
920 CHECK_PIXEL_PTR(2 * byte_run);
921 for (j = 0; j < byte_run; j++) {
922 *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
923 pixel_ptr += 2;
924 pixel_countdown--;
925 if (pixel_countdown < 0)
926 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
927 pixel_countdown);
928 }
929 }
930 }
931
932 y_ptr += s->frame->linesize[0];
933 }
934 break;
935
936 case FLI_COPY:
937 case FLI_DTA_COPY:
938 /* copy the chunk (uncompressed frame) */
939 if (chunk_size - 6 > (unsigned int)(FFALIGN(s->avctx->width, 2) * s->avctx->height)*2) {
940 av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
941 "bigger than image, skipping chunk\n", chunk_size - 6);
942 bytestream2_skip(&g2, chunk_size - 6);
943 } else {
944
945 if (bytestream2_get_bytes_left(&g2) < 2 * s->avctx->width * s->avctx->height )
946 return AVERROR_INVALIDDATA;
947 for (y_ptr = 0; check_pixel_ptr(y_ptr, 2*s->avctx->width, pixel_limit, direction) == 0;
948 y_ptr += s->frame->linesize[0]) {
949
950 pixel_countdown = s->avctx->width;
951 pixel_ptr = 0;
952 while (pixel_countdown > 0) {
953 *((signed short*)(&pixels[y_ptr + pixel_ptr])) = bytestream2_get_le16(&g2);
954 pixel_ptr += 2;
955 pixel_countdown--;
956 }
957 if (s->avctx->width & 1)
958 bytestream2_skip(&g2, 2);
959 }
960 }
961 break;
962
963 case FLI_MINI:
964 /* some sort of a thumbnail? disregard this chunk... */
965 bytestream2_skip(&g2, chunk_size - 6);
966 break;
967
968 default:
969 av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
970 break;
971 }
972
973 if (stream_ptr_after_chunk - bytestream2_tell(&g2) >= 0) {
974 bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
975 } else {
976 av_log(avctx, AV_LOG_ERROR, "Chunk overread\n");
977 break;
978 }
979
980 frame_size -= chunk_size;
981 num_chunks--;
982 }
983
984 /* by the end of the chunk, the stream ptr should equal the frame
985 * size (minus 1, possibly); if it doesn't, issue a warning */
986 if ((bytestream2_get_bytes_left(&g2) != 0) && (bytestream2_get_bytes_left(&g2) != 1))
987 av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
988 "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2));
989
990 if ((ret = av_frame_ref(rframe, s->frame)) < 0)
991 return ret;
992
993 *got_frame = 1;
994
995 return buf_size;
996}
997
999 AVFrame *rframe, int *got_frame,
1000 const uint8_t *buf, int buf_size)
1001{
1002 FlicDecodeContext *s = avctx->priv_data;
1003
1004 GetByteContext g2;
1005 ptrdiff_t pixel_ptr;
1006 unsigned char palette_idx1;
1007
1008 unsigned int frame_size;
1009 int num_chunks;
1010
1011 unsigned int chunk_size;
1012 int chunk_type;
1013
1014 int i, j, ret, direction;
1015
1016 int lines;
1017 int compressed_lines;
1018 int line_packets;
1019 ptrdiff_t y_ptr;
1020 int byte_run;
1021 int pixel_skip;
1022 int pixel_countdown;
1023 unsigned char *pixels;
1024 int pixel;
1025 ptrdiff_t pixel_limit;
1026
1027 bytestream2_init(&g2, buf, buf_size);
1028
1029 if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
1030 return ret;
1031
1032 direction = s->frame->linesize[0] > 0;
1033 pixels = s->frame->data[0];
1034 pixel_limit = s->avctx->height * s->frame->linesize[0];
1035
1036 frame_size = bytestream2_get_le32(&g2);
1037 bytestream2_skip(&g2, 2); /* skip the magic number */
1038 num_chunks = bytestream2_get_le16(&g2);
1039 bytestream2_skip(&g2, 8); /* skip padding */
1040 if (frame_size > buf_size)
1041 frame_size = buf_size;
1042
1043 if (frame_size < 16)
1044 return AVERROR_INVALIDDATA;
1045 frame_size -= 16;
1046
1047 /* iterate through the chunks */
1048 while ((frame_size > 0) && (num_chunks > 0) &&
1049 bytestream2_get_bytes_left(&g2) >= 4) {
1050 int stream_ptr_after_chunk;
1051 chunk_size = bytestream2_get_le32(&g2);
1052 if (chunk_size > frame_size) {
1053 av_log(avctx, AV_LOG_WARNING,
1054 "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
1055 chunk_size = frame_size;
1056 }
1057 stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
1058
1059 chunk_type = bytestream2_get_le16(&g2);
1060
1061
1062 switch (chunk_type) {
1063 case FLI_256_COLOR:
1064 case FLI_COLOR:
1065 /* For some reason, it seems that non-palettized flics do
1066 * include one of these chunks in their first frame.
1067 * Why I do not know, it seems rather extraneous. */
1068 ff_dlog(avctx,
1069 "Unexpected Palette chunk %d in non-palettized FLC\n",
1070 chunk_type);
1071 bytestream2_skip(&g2, chunk_size - 6);
1072 break;
1073
1074 case FLI_DELTA:
1075 case FLI_DTA_LC:
1076 y_ptr = 0;
1077 compressed_lines = bytestream2_get_le16(&g2);
1078 while (compressed_lines > 0) {
1079 if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
1080 break;
1081 CHECK_Y_PTR()
1082 line_packets = sign_extend(bytestream2_get_le16(&g2), 16);
1083 if (line_packets < 0) {
1084 line_packets = -line_packets;
1085 if (line_packets > s->avctx->height)
1086 return AVERROR_INVALIDDATA;
1087 y_ptr += line_packets * s->frame->linesize[0];
1088 } else {
1089 compressed_lines--;
1090 pixel_ptr = y_ptr;
1091 CHECK_PIXEL_PTR(0);
1092 pixel_countdown = s->avctx->width;
1093 for (i = 0; i < line_packets; i++) {
1094 /* account for the skip bytes */
1095 if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
1096 break;
1097 pixel_skip = bytestream2_get_byte(&g2);
1098 pixel_ptr += (pixel_skip*3); /* Pixel is 3 bytes wide */
1099 pixel_countdown -= pixel_skip;
1100 byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
1101 if (byte_run < 0) {
1102 byte_run = -byte_run;
1103 pixel = bytestream2_get_le24(&g2);
1104 CHECK_PIXEL_PTR(3 * byte_run);
1105 for (j = 0; j < byte_run; j++, pixel_countdown -= 1) {
1106 AV_WL24(&pixels[pixel_ptr], pixel);
1107 pixel_ptr += 3;
1108 }
1109 } else {
1110 if (bytestream2_tell(&g2) + 2*byte_run > stream_ptr_after_chunk)
1111 break;
1112 CHECK_PIXEL_PTR(3 * byte_run);
1113 for (j = 0; j < byte_run; j++, pixel_countdown--) {
1114 pixel = bytestream2_get_le24(&g2);
1115 AV_WL24(&pixels[pixel_ptr], pixel);
1116 pixel_ptr += 3;
1117 }
1118 }
1119 }
1120
1121 y_ptr += s->frame->linesize[0];
1122 }
1123 }
1124 break;
1125
1126 case FLI_LC:
1127 av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-palettized FLC\n");
1128 bytestream2_skip(&g2, chunk_size - 6);
1129 break;
1130
1131 case FLI_BLACK:
1132 /* set the whole frame to 0x00 which is black for 24 bit mode. */
1133 for (int y = 0; y < s->avctx->height; y++)
1134 memset(pixels + y * s->frame->linesize[0], 0, s->avctx->width * 3);
1135 break;
1136
1137 case FLI_BRUN:
1138 y_ptr = 0;
1139 for (lines = 0; lines < s->avctx->height; lines++) {
1140 pixel_ptr = y_ptr;
1141 /* disregard the line packets; instead, iterate through all
1142 * pixels on a row */
1143 bytestream2_skip(&g2, 1);
1144 pixel_countdown = (s->avctx->width * 3);
1145
1146 while (pixel_countdown > 0) {
1147 if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
1148 break;
1149 byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
1150 if (byte_run > 0) {
1151 palette_idx1 = bytestream2_get_byte(&g2);
1152 CHECK_PIXEL_PTR(byte_run);
1153 for (j = 0; j < byte_run; j++) {
1154 pixels[pixel_ptr++] = palette_idx1;
1155 pixel_countdown--;
1156 if (pixel_countdown < 0)
1157 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) (linea%d)\n",
1158 pixel_countdown, lines);
1159 }
1160 } else { /* copy bytes if byte_run < 0 */
1161 byte_run = -byte_run;
1162 if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
1163 break;
1164 CHECK_PIXEL_PTR(byte_run);
1165 for (j = 0; j < byte_run; j++) {
1166 palette_idx1 = bytestream2_get_byte(&g2);
1167 pixels[pixel_ptr++] = palette_idx1;
1168 pixel_countdown--;
1169 if (pixel_countdown < 0)
1170 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
1171 pixel_countdown, lines);
1172 }
1173 }
1174 }
1175
1176 y_ptr += s->frame->linesize[0];
1177 }
1178 break;
1179
1180 case FLI_DTA_BRUN:
1181 y_ptr = 0;
1182 for (lines = 0; lines < s->avctx->height; lines++) {
1183 pixel_ptr = y_ptr;
1184 /* disregard the line packets; instead, iterate through all
1185 * pixels on a row */
1186 bytestream2_skip(&g2, 1);
1187 pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */
1188
1189 while (pixel_countdown > 0) {
1190 if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
1191 break;
1192 byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
1193 if (byte_run > 0) {
1194 pixel = bytestream2_get_le24(&g2);
1195 CHECK_PIXEL_PTR(3 * byte_run);
1196 for (j = 0; j < byte_run; j++) {
1197 AV_WL24(pixels + pixel_ptr, pixel);
1198 pixel_ptr += 3;
1199 pixel_countdown--;
1200 if (pixel_countdown < 0)
1201 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
1202 pixel_countdown);
1203 }
1204 } else { /* copy pixels if byte_run < 0 */
1205 byte_run = -byte_run;
1206 if (bytestream2_tell(&g2) + 3 * byte_run > stream_ptr_after_chunk)
1207 break;
1208 CHECK_PIXEL_PTR(3 * byte_run);
1209 for (j = 0; j < byte_run; j++) {
1210 pixel = bytestream2_get_le24(&g2);
1211 AV_WL24(pixels + pixel_ptr, pixel);
1212 pixel_ptr += 3;
1213 pixel_countdown--;
1214 if (pixel_countdown < 0)
1215 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
1216 pixel_countdown);
1217 }
1218 }
1219 }
1220
1221 y_ptr += s->frame->linesize[0];
1222 }
1223 break;
1224
1225 case FLI_COPY:
1226 case FLI_DTA_COPY:
1227 /* copy the chunk (uncompressed frame) */
1228 if (chunk_size - 6 > (unsigned int)(FFALIGN(s->avctx->width, 2) * s->avctx->height)*3) {
1229 av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
1230 "bigger than image, skipping chunk\n", chunk_size - 6);
1231 bytestream2_skip(&g2, chunk_size - 6);
1232 } else {
1233 for (y_ptr = 0; check_pixel_ptr(y_ptr, 3*s->avctx->width, pixel_limit, direction) == 0;
1234 y_ptr += s->frame->linesize[0]) {
1235
1236 bytestream2_get_buffer(&g2, pixels + y_ptr, 3*s->avctx->width);
1237 if (s->avctx->width & 1)
1238 bytestream2_skip(&g2, 3);
1239 }
1240 }
1241 break;
1242
1243 case FLI_MINI:
1244 /* some sort of a thumbnail? disregard this chunk... */
1245 bytestream2_skip(&g2, chunk_size - 6);
1246 break;
1247
1248 default:
1249 av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
1250 break;
1251 }
1252
1253 if (stream_ptr_after_chunk - bytestream2_tell(&g2) >= 0) {
1254 bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
1255 } else {
1256 av_log(avctx, AV_LOG_ERROR, "Chunk overread\n");
1257 break;
1258 }
1259
1260 frame_size -= chunk_size;
1261 num_chunks--;
1262 }
1263
1264 /* by the end of the chunk, the stream ptr should equal the frame
1265 * size (minus 1, possibly); if it doesn't, issue a warning */
1266 if ((bytestream2_get_bytes_left(&g2) != 0) && (bytestream2_get_bytes_left(&g2) != 1))
1267 av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
1268 "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2));
1269
1270 if ((ret = av_frame_ref(rframe, s->frame)) < 0)
1271 return ret;
1272
1273 *got_frame = 1;
1274
1275 return buf_size;
1276}
1277
1279 int *got_frame, AVPacket *avpkt)
1280{
1281 const uint8_t *buf = avpkt->data;
1282 int buf_size = avpkt->size;
1283 if (avctx->pix_fmt == AV_PIX_FMT_MONOBLACK) {
1284 return flic_decode_frame_1BPP(avctx, frame, got_frame,
1285 buf, buf_size);
1286 } else if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1287 return flic_decode_frame_8BPP(avctx, frame, got_frame,
1288 buf, buf_size);
1289 } else if ((avctx->pix_fmt == AV_PIX_FMT_RGB555) ||
1290 (avctx->pix_fmt == AV_PIX_FMT_RGB565)) {
1291 return flic_decode_frame_15_16BPP(avctx, frame, got_frame,
1292 buf, buf_size);
1293 } else if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {
1294 return flic_decode_frame_24BPP(avctx, frame, got_frame,
1295 buf, buf_size);
1296 }
1297
1298 /* Should not get here, ever as the pix_fmt is processed */
1299 /* in flic_decode_init and the above if should deal with */
1300 /* the finite set of possibilities allowable by here. */
1301 /* But in case we do, just error out. */
1302 av_log(avctx, AV_LOG_ERROR, "Unknown FLC format, my science cannot explain how this happened.\n");
1303 return AVERROR_BUG;
1304}
1305
1306
1308{
1309 FlicDecodeContext *s = avctx->priv_data;
1310
1311 av_frame_free(&s->frame);
1312
1313 return 0;
1314}
1315
1317 .p.name = "flic",
1318 CODEC_LONG_NAME("Autodesk Animator Flic video"),
1319 .p.type = AVMEDIA_TYPE_VIDEO,
1320 .p.id = AV_CODEC_ID_FLIC,
1321 .priv_data_size = sizeof(FlicDecodeContext),
1325 .p.capabilities = AV_CODEC_CAP_DR1,
1326};
const FFCodec ff_flic_decoder
Definition flicvideo.c:1316
#define entry
static av_cold void close(AVCodecParserContext *s)
Definition apv_parser.c:197
Libavcodec external API header.
#define pixel
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition bytestream.h:267
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
Definition bytestream.h:158
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition bytestream.h:137
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition bytestream.h:168
static av_always_inline int bytestream2_tell(const GetByteContext *g)
Definition bytestream.h:192
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
#define FF_CODEC_DECODE_CB(func)
#define CODEC_LONG_NAME(str)
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Identical in function to ff_get_buffer(), except it reuses the existing buffer if available.
Definition decode.c:1906
static AVFrame * frame
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
double value
Definition eval.c:102
static av_cold int flic_decode_init(AVCodecContext *avctx)
Definition flicvideo.c:95
#define FLI_COPY
Definition flicvideo.c:52
#define FLC_FLX_TYPE_CODE
Definition flicvideo.c:59
static int check_pixel_ptr(ptrdiff_t ptr, int n, ptrdiff_t limit, int direction)
Definition flicvideo.c:63
static int flic_decode_frame_24BPP(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, const uint8_t *buf, int buf_size)
Definition flicvideo.c:998
#define FLI_BLACK
Definition flicvideo.c:50
#define FLI_MINI
Definition flicvideo.c:53
static int flic_decode_frame_8BPP(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, const uint8_t *buf, int buf_size)
Definition flicvideo.c:358
#define FLI_256_COLOR
Definition flicvideo.c:46
#define FLI_DTA_COPY
Definition flicvideo.c:55
static int flic_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *avpkt)
Definition flicvideo.c:1278
static av_cold int flic_decode_end(AVCodecContext *avctx)
Definition flicvideo.c:1307
#define FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE
Definition flicvideo.c:61
#define FLI_BRUN
Definition flicvideo.c:51
#define FLI_DTA_BRUN
Definition flicvideo.c:54
#define FLI_LC
Definition flicvideo.c:49
#define CHECK_Y_PTR()
Definition flicvideo.c:79
#define FLI_DELTA
Definition flicvideo.c:47
static int flic_decode_frame_1BPP(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, const uint8_t *buf, int buf_size)
Definition flicvideo.c:166
#define FLI_DTA_LC
Definition flicvideo.c:56
static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, const uint8_t *buf, int buf_size)
Definition flicvideo.c:696
#define FLI_TYPE_CODE
Definition flicvideo.c:58
#define CHECK_PIXEL_PTR(n)
Definition flicvideo.c:72
#define FLI_COLOR
Definition flicvideo.c:48
static const uint8_t frame_size[4]
Definition g723_1.h:222
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
@ AV_CODEC_ID_FLIC
Definition codec_id.h:100
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition error.h:52
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition frame.c:278
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition frame.c:52
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define r
Definition input.c:42
#define b
Definition input.c:43
#define AV_RL32(p)
#define AV_WL24(p, d)
#define AV_RL16(p)
#define av_cold
Definition attributes.h:117
#define FFALIGN(x, a)
Definition macros.h:78
static av_const int sign_extend(int val, unsigned bits)
Definition mathops.h:135
@ AV_PIX_FMT_MONOBLACK
Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb.
Definition pixfmt.h:83
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition pixfmt.h:84
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition pixfmt.h:76
#define AV_PIX_FMT_RGB565
Definition pixfmt.h:532
#define AVPALETTE_SIZE
Definition pixfmt.h:32
#define AV_PIX_FMT_RGB555
Definition pixfmt.h:533
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:643
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition avcodec.h:526
int extradata_size
Definition avcodec.h:527
void * priv_data
Definition avcodec.h:470
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
This structure stores compressed data.
Definition packet.h:580
int size
Definition packet.h:604
uint8_t * data
Definition packet.h:603
unsigned int palette[256]
Definition flicvideo.c:90
AVCodecContext * avctx
Definition flicvideo.c:87
AVFrame * frame
Definition flicvideo.c:88
#define ff_dlog(a,...)
#define av_log(a,...)
const char * g
Definition vf_curves.c:128
static double limit(double x)