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
45
46 #define FLI_256_COLOR 4
54 #define FLI_DTA_BRUN 25
55 #define FLI_DTA_COPY 26
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
63 #define CHECK_PIXEL_PTR(n) \
64 if (pixel_ptr + n > pixel_limit) { \
65 av_log (s->avctx, AV_LOG_ERROR, "Invalid pixel_ptr = %d > pixel_limit = %d\n", \
66 pixel_ptr + n, pixel_limit); \
67 return AVERROR_INVALIDDATA; \
68 } \
69
73
76 int fli_type;
/* either 0xAF11 or 0xAF12, affects palette resolution */
78
80 {
82 unsigned char *fli_header = (
unsigned char *)avctx->
extradata;
83 int depth;
84
93 }
94
96
97 if (
s->avctx->extradata_size == 12) {
98 /* special case for magic carpet FLIs */
100 depth = 8;
104
105 for (
i = 0;
i < 256;
i++) {
107 ptr += 4;
108 }
109 depth = 8;
110 /* FLI in MOV, see e.g. FFmpeg trac issue #626 */
113 /* see FFmpeg ticket #1234 */
116 depth = 8;
117 } else {
118 s->fli_type =
AV_RL16(&fli_header[4]);
119 depth =
AV_RL16(&fli_header[12]);
120 }
121
122 if (depth == 0) {
123 depth = 8; /* Some FLC generators set depth to zero, when they mean 8Bpp. Fix up here */
124 }
125
127 depth = 15; /* Original Autodesk FLX's say the depth is 16Bpp when it is really 15Bpp */
128 }
129
130 switch (depth) {
135 default :
136 av_log(avctx,
AV_LOG_ERROR,
"Unknown FLC/FLX depth of %d Bpp is unsupported.\n",depth);
138 }
139
143
145
146 return 0;
147 }
148
150 AVFrame *rframe,
int *got_frame,
151 const uint8_t *buf, int buf_size)
152 {
154
156 int pixel_ptr;
157 int palette_ptr;
158 unsigned char palette_idx1;
159 unsigned char palette_idx2;
160
162 int num_chunks;
163
164 unsigned int chunk_size;
165 int chunk_type;
166
168
169 int color_packets;
170 int color_changes;
171 int color_shift;
172 unsigned char r,
g,
b;
173
174 int lines;
175 int compressed_lines;
176 int starting_line;
177 int line_packets;
178 int y_ptr;
179 int byte_run;
180 int pixel_skip;
181 int pixel_countdown;
182 unsigned char *pixels;
183 unsigned int pixel_limit;
184
186
189
190 pixels =
s->frame->data[0];
191 pixel_limit =
s->avctx->height *
s->frame->linesize[0];
198 num_chunks = bytestream2_get_le16(&g2);
200
203
205
206 /* iterate through the chunks */
207 while ((
frame_size >= 6) && (num_chunks > 0) &&
209 int stream_ptr_after_chunk;
210 chunk_size = bytestream2_get_le32(&g2);
213 "Invalid chunk_size = %u > frame_size = %u\n", chunk_size,
frame_size);
215 }
217
218 chunk_type = bytestream2_get_le16(&g2);
219
220 switch (chunk_type) {
223 /* check special case: If this file is from the Magic Carpet
224 * game and uses 6-bit colors even though it reports 256-color
225 * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during
226 * initialization) */
228 color_shift = 0;
229 else
230 color_shift = 2;
231 /* set up the palette */
232 color_packets = bytestream2_get_le16(&g2);
233 palette_ptr = 0;
234 for (
i = 0;
i < color_packets;
i++) {
235 /* first byte is how many colors to skip */
236 palette_ptr += bytestream2_get_byte(&g2);
237
238 /* next byte indicates how many entries to change */
239 color_changes = bytestream2_get_byte(&g2);
240
241 /* if there are 0 color changes, there are actually 256 */
242 if (color_changes == 0)
243 color_changes = 256;
244
246 break;
247
248 for (j = 0; j < color_changes; j++) {
249 unsigned int entry;
250
251 /* wrap around, for good measure */
252 if ((unsigned)palette_ptr >= 256)
253 palette_ptr = 0;
254
255 r = bytestream2_get_byte(&g2) << color_shift;
256 g = bytestream2_get_byte(&g2) << color_shift;
257 b = bytestream2_get_byte(&g2) << color_shift;
258 entry = 0xFF
U << 24 |
r << 16 |
g << 8 |
b;
259 if (color_shift == 2)
260 entry |= entry >> 6 & 0x30303;
261 if (
s->palette[palette_ptr] != entry)
263 s->palette[palette_ptr++] = entry;
264 }
265 }
266 break;
267
269 y_ptr = 0;
270 compressed_lines = bytestream2_get_le16(&g2);
271 while (compressed_lines > 0) {
273 break;
274 if (y_ptr > pixel_limit)
276 line_packets =
sign_extend(bytestream2_get_le16(&g2), 16);
277 if ((line_packets & 0xC000) == 0xC000) {
278 // line skip opcode
279 line_packets = -line_packets;
280 if (line_packets >
s->avctx->height)
282 y_ptr += line_packets *
s->frame->linesize[0];
283 } else if ((line_packets & 0xC000) == 0x4000) {
285 } else if ((line_packets & 0xC000) == 0x8000) {
286 // "last byte" opcode
287 pixel_ptr= y_ptr +
s->frame->linesize[0] - 1;
289 pixels[pixel_ptr] = line_packets & 0xff;
290 } else {
291 compressed_lines--;
292 pixel_ptr = y_ptr;
294 pixel_countdown =
s->avctx->width;
295 for (
i = 0;
i < line_packets;
i++) {
297 break;
298 /* account for the skip bytes */
299 pixel_skip = bytestream2_get_byte(&g2);
300 pixel_ptr += pixel_skip;
301 pixel_countdown -= pixel_skip;
302 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
303 if (byte_run < 0) {
304 byte_run = -byte_run;
305 palette_idx1 = bytestream2_get_byte(&g2);
306 palette_idx2 = bytestream2_get_byte(&g2);
308 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
309 pixels[pixel_ptr++] = palette_idx1;
310 pixels[pixel_ptr++] = palette_idx2;
311 }
312 } else {
315 break;
316 for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
317 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
318 }
319 }
320 }
321
322 y_ptr +=
s->frame->linesize[0];
323 }
324 }
325 break;
326
328 /* line compressed */
329 starting_line = bytestream2_get_le16(&g2);
330 if (starting_line >=
s->avctx->height)
332 y_ptr = 0;
333 y_ptr += starting_line *
s->frame->linesize[0];
334
335 compressed_lines = bytestream2_get_le16(&g2);
336 while (compressed_lines > 0) {
337 pixel_ptr = y_ptr;
339 pixel_countdown =
s->avctx->width;
341 break;
342 line_packets = bytestream2_get_byte(&g2);
343 if (line_packets > 0) {
344 for (
i = 0;
i < line_packets;
i++) {
345 /* account for the skip bytes */
347 break;
348 pixel_skip = bytestream2_get_byte(&g2);
349 pixel_ptr += pixel_skip;
350 pixel_countdown -= pixel_skip;
351 byte_run =
sign_extend(bytestream2_get_byte(&g2),8);
352 if (byte_run > 0) {
355 break;
356 for (j = 0; j < byte_run; j++, pixel_countdown--) {
357 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
358 }
359 } else if (byte_run < 0) {
360 byte_run = -byte_run;
361 palette_idx1 = bytestream2_get_byte(&g2);
363 for (j = 0; j < byte_run; j++, pixel_countdown--) {
364 pixels[pixel_ptr++] = palette_idx1;
365 }
366 }
367 }
368 }
369
370 y_ptr +=
s->frame->linesize[0];
371 compressed_lines--;
372 }
373 break;
374
376 /* set the whole frame to color 0 (which is usually black) */
377 memset(pixels, 0,
378 s->frame->linesize[0] *
s->avctx->height);
379 break;
380
382 /* Byte run compression: This chunk type only occurs in the first
383 * FLI frame and it will update the entire frame. */
384 y_ptr = 0;
385 for (lines = 0; lines <
s->avctx->height; lines++) {
386 pixel_ptr = y_ptr;
387 /* disregard the line packets; instead, iterate through all
388 * pixels on a row */
390 pixel_countdown =
s->avctx->width;
391 while (pixel_countdown > 0) {
393 break;
394 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
395 if (!byte_run) {
398 }
399
400 if (byte_run > 0) {
401 palette_idx1 = bytestream2_get_byte(&g2);
403 for (j = 0; j < byte_run; j++) {
404 pixels[pixel_ptr++] = palette_idx1;
405 pixel_countdown--;
406 if (pixel_countdown < 0)
408 pixel_countdown, lines);
409 }
410 } else { /* copy bytes if byte_run < 0 */
411 byte_run = -byte_run;
414 break;
415 for (j = 0; j < byte_run; j++) {
416 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
417 pixel_countdown--;
418 if (pixel_countdown < 0)
420 pixel_countdown, lines);
421 }
422 }
423 }
424
425 y_ptr +=
s->frame->linesize[0];
426 }
427 break;
428
430 /* copy the chunk (uncompressed frame) */
431 if (chunk_size - 6 !=
FFALIGN(
s->avctx->width, 4) *
s->avctx->height) {
433 "has incorrect size, skipping chunk\n", chunk_size - 6);
435 } else {
436 for (y_ptr = 0; y_ptr <
s->frame->linesize[0] *
s->avctx->height;
437 y_ptr +=
s->frame->linesize[0]) {
440 if (
s->avctx->width & 3)
442 }
443 }
444 break;
445
447 /* some sort of a thumbnail? disregard this chunk... */
448 break;
449
450 default:
452 break;
453 }
454
457 } else {
459 break;
460 }
461
463 num_chunks--;
464 }
465
466 /* by the end of the chunk, the stream ptr should equal the frame
467 * size (minus 1 or 2, possibly); if it doesn't, issue a warning */
470 "and final chunk ptr = %d\n", buf_size,
472
473 /* make the palette available on the way out */
475 if (
s->new_palette) {
476 s->frame->palette_has_changed = 1;
478 }
479
482
483 *got_frame = 1;
484
485 return buf_size;
486 }
487
489 AVFrame *rframe,
int *got_frame,
490 const uint8_t *buf, int buf_size)
491 {
492 /* Note, the only difference between the 15Bpp and 16Bpp */
493 /* Format is the pixel format, the packets are processed the same. */
495
497 int pixel_ptr;
498 unsigned char palette_idx1;
499
501 int num_chunks;
502
503 unsigned int chunk_size;
504 int chunk_type;
505
507
508 int lines;
509 int compressed_lines;
510 int line_packets;
511 int y_ptr;
512 int byte_run;
513 int pixel_skip;
514 int pixel_countdown;
515 unsigned char *pixels;
517 unsigned int pixel_limit;
518
520
523
524 pixels =
s->frame->data[0];
525 pixel_limit =
s->avctx->height *
s->frame->linesize[0];
526
529 num_chunks = bytestream2_get_le16(&g2);
533
537
538 /* iterate through the chunks */
539 while ((
frame_size > 0) && (num_chunks > 0) &&
541 int stream_ptr_after_chunk;
542 chunk_size = bytestream2_get_le32(&g2);
545 "Invalid chunk_size = %u > frame_size = %u\n", chunk_size,
frame_size);
547 }
549
550 chunk_type = bytestream2_get_le16(&g2);
551
552
553 switch (chunk_type) {
556 /* For some reason, it seems that non-palettized flics do
557 * include one of these chunks in their first frame.
558 * Why I do not know, it seems rather extraneous. */
560 "Unexpected Palette chunk %d in non-palettized FLC\n",
561 chunk_type);
563 break;
564
567 y_ptr = 0;
568 compressed_lines = bytestream2_get_le16(&g2);
569 while (compressed_lines > 0) {
571 break;
572 if (y_ptr > pixel_limit)
574 line_packets =
sign_extend(bytestream2_get_le16(&g2), 16);
575 if (line_packets < 0) {
576 line_packets = -line_packets;
577 if (line_packets >
s->avctx->height)
579 y_ptr += line_packets *
s->frame->linesize[0];
580 } else {
581 compressed_lines--;
582 pixel_ptr = y_ptr;
584 pixel_countdown =
s->avctx->width;
585 for (
i = 0;
i < line_packets;
i++) {
586 /* account for the skip bytes */
588 break;
589 pixel_skip = bytestream2_get_byte(&g2);
590 pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */
591 pixel_countdown -= pixel_skip;
592 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
593 if (byte_run < 0) {
594 byte_run = -byte_run;
595 pixel = bytestream2_get_le16(&g2);
597 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
598 *((
signed short*)(&pixels[pixel_ptr])) =
pixel;
599 pixel_ptr += 2;
600 }
601 } else {
603 break;
605 for (j = 0; j < byte_run; j++, pixel_countdown--) {
606 *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
607 pixel_ptr += 2;
608 }
609 }
610 }
611
612 y_ptr +=
s->frame->linesize[0];
613 }
614 }
615 break;
616
620 break;
621
623 /* set the whole frame to 0x0000 which is black in both 15Bpp and 16Bpp modes. */
624 memset(pixels, 0x0000,
625 s->frame->linesize[0] *
s->avctx->height);
626 break;
627
629 y_ptr = 0;
630 for (lines = 0; lines <
s->avctx->height; lines++) {
631 pixel_ptr = y_ptr;
632 /* disregard the line packets; instead, iterate through all
633 * pixels on a row */
635 pixel_countdown = (
s->avctx->width * 2);
636
637 while (pixel_countdown > 0) {
639 break;
640 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
641 if (byte_run > 0) {
642 palette_idx1 = bytestream2_get_byte(&g2);
644 for (j = 0; j < byte_run; j++) {
645 pixels[pixel_ptr++] = palette_idx1;
646 pixel_countdown--;
647 if (pixel_countdown < 0)
649 pixel_countdown, lines);
650 }
651 } else { /* copy bytes if byte_run < 0 */
652 byte_run = -byte_run;
654 break;
656 for (j = 0; j < byte_run; j++) {
657 palette_idx1 = bytestream2_get_byte(&g2);
658 pixels[pixel_ptr++] = palette_idx1;
659 pixel_countdown--;
660 if (pixel_countdown < 0)
662 pixel_countdown, lines);
663 }
664 }
665 }
666
667 /* Now FLX is strange, in that it is "byte" as opposed to "pixel" run length compressed.
668 * This does not give us any good opportunity to perform word endian conversion
669 * during decompression. So if it is required (i.e., this is not a LE target, we do
670 * a second pass over the line here, swapping the bytes.
671 */
672 #if HAVE_BIGENDIAN
673 pixel_ptr = y_ptr;
674 pixel_countdown =
s->avctx->width;
675 while (pixel_countdown > 0) {
676 *((
signed short*)(&pixels[pixel_ptr])) =
AV_RL16(&buf[pixel_ptr]);
677 pixel_ptr += 2;
678 }
679 #endif
680 y_ptr +=
s->frame->linesize[0];
681 }
682 break;
683
685 y_ptr = 0;
686 for (lines = 0; lines <
s->avctx->height; lines++) {
687 pixel_ptr = y_ptr;
688 /* disregard the line packets; instead, iterate through all
689 * pixels on a row */
691 pixel_countdown =
s->avctx->width;
/* Width is in pixels, not bytes */
692
693 while (pixel_countdown > 0) {
695 break;
696 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
697 if (byte_run > 0) {
698 pixel = bytestream2_get_le16(&g2);
700 for (j = 0; j < byte_run; j++) {
701 *((
signed short*)(&pixels[pixel_ptr])) =
pixel;
702 pixel_ptr += 2;
703 pixel_countdown--;
704 if (pixel_countdown < 0)
706 pixel_countdown);
707 }
708 } else { /* copy pixels if byte_run < 0 */
709 byte_run = -byte_run;
711 break;
713 for (j = 0; j < byte_run; j++) {
714 *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
715 pixel_ptr += 2;
716 pixel_countdown--;
717 if (pixel_countdown < 0)
719 pixel_countdown);
720 }
721 }
722 }
723
724 y_ptr +=
s->frame->linesize[0];
725 }
726 break;
727
730 /* copy the chunk (uncompressed frame) */
731 if (chunk_size - 6 > (
unsigned int)(
FFALIGN(
s->avctx->width, 2) *
s->avctx->height)*2) {
733 "bigger than image, skipping chunk\n", chunk_size - 6);
735 } else {
736
739 for (y_ptr = 0; y_ptr <
s->frame->linesize[0] *
s->avctx->height;
740 y_ptr +=
s->frame->linesize[0]) {
741
742 pixel_countdown =
s->avctx->width;
743 pixel_ptr = 0;
744 while (pixel_countdown > 0) {
745 *((signed short*)(&pixels[y_ptr + pixel_ptr])) = bytestream2_get_le16(&g2);
746 pixel_ptr += 2;
747 pixel_countdown--;
748 }
749 if (
s->avctx->width & 1)
751 }
752 }
753 break;
754
756 /* some sort of a thumbnail? disregard this chunk... */
758 break;
759
760 default:
762 break;
763 }
764
767 } else {
769 break;
770 }
771
773 num_chunks--;
774 }
775
776 /* by the end of the chunk, the stream ptr should equal the frame
777 * size (minus 1, possibly); if it doesn't, issue a warning */
781
784
785 *got_frame = 1;
786
787 return buf_size;
788 }
789
791 AVFrame *rframe,
int *got_frame,
792 const uint8_t *buf, int buf_size)
793 {
795
797 int pixel_ptr;
798 unsigned char palette_idx1;
799
801 int num_chunks;
802
803 unsigned int chunk_size;
804 int chunk_type;
805
807
808 int lines;
809 int compressed_lines;
810 int line_packets;
811 int y_ptr;
812 int byte_run;
813 int pixel_skip;
814 int pixel_countdown;
815 unsigned char *pixels;
817 unsigned int pixel_limit;
818
820
823
824 pixels =
s->frame->data[0];
825 pixel_limit =
s->avctx->height *
s->frame->linesize[0];
826
829 num_chunks = bytestream2_get_le16(&g2);
833
837
838 /* iterate through the chunks */
839 while ((
frame_size > 0) && (num_chunks > 0) &&
841 int stream_ptr_after_chunk;
842 chunk_size = bytestream2_get_le32(&g2);
845 "Invalid chunk_size = %u > frame_size = %u\n", chunk_size,
frame_size);
847 }
849
850 chunk_type = bytestream2_get_le16(&g2);
851
852
853 switch (chunk_type) {
856 /* For some reason, it seems that non-palettized flics do
857 * include one of these chunks in their first frame.
858 * Why I do not know, it seems rather extraneous. */
860 "Unexpected Palette chunk %d in non-palettized FLC\n",
861 chunk_type);
863 break;
864
867 y_ptr = 0;
868 compressed_lines = bytestream2_get_le16(&g2);
869 while (compressed_lines > 0) {
871 break;
872 if (y_ptr > pixel_limit)
874 line_packets =
sign_extend(bytestream2_get_le16(&g2), 16);
875 if (line_packets < 0) {
876 line_packets = -line_packets;
877 if (line_packets >
s->avctx->height)
879 y_ptr += line_packets *
s->frame->linesize[0];
880 } else {
881 compressed_lines--;
882 pixel_ptr = y_ptr;
884 pixel_countdown =
s->avctx->width;
885 for (
i = 0;
i < line_packets;
i++) {
886 /* account for the skip bytes */
888 break;
889 pixel_skip = bytestream2_get_byte(&g2);
890 pixel_ptr += (pixel_skip*3); /* Pixel is 3 bytes wide */
891 pixel_countdown -= pixel_skip;
892 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
893 if (byte_run < 0) {
894 byte_run = -byte_run;
895 pixel = bytestream2_get_le24(&g2);
897 for (j = 0; j < byte_run; j++, pixel_countdown -= 1) {
899 pixel_ptr += 3;
900 }
901 } else {
903 break;
905 for (j = 0; j < byte_run; j++, pixel_countdown--) {
906 pixel = bytestream2_get_le24(&g2);
908 pixel_ptr += 3;
909 }
910 }
911 }
912
913 y_ptr +=
s->frame->linesize[0];
914 }
915 }
916 break;
917
921 break;
922
924 /* set the whole frame to 0x00 which is black for 24 bit mode. */
925 memset(pixels, 0x00,
926 s->frame->linesize[0] *
s->avctx->height);
927 break;
928
930 y_ptr = 0;
931 for (lines = 0; lines <
s->avctx->height; lines++) {
932 pixel_ptr = y_ptr;
933 /* disregard the line packets; instead, iterate through all
934 * pixels on a row */
936 pixel_countdown = (
s->avctx->width * 3);
937
938 while (pixel_countdown > 0) {
940 break;
941 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
942 if (byte_run > 0) {
943 palette_idx1 = bytestream2_get_byte(&g2);
945 for (j = 0; j < byte_run; j++) {
946 pixels[pixel_ptr++] = palette_idx1;
947 pixel_countdown--;
948 if (pixel_countdown < 0)
950 pixel_countdown, lines);
951 }
952 } else { /* copy bytes if byte_run < 0 */
953 byte_run = -byte_run;
955 break;
957 for (j = 0; j < byte_run; j++) {
958 palette_idx1 = bytestream2_get_byte(&g2);
959 pixels[pixel_ptr++] = palette_idx1;
960 pixel_countdown--;
961 if (pixel_countdown < 0)
963 pixel_countdown, lines);
964 }
965 }
966 }
967
968 y_ptr +=
s->frame->linesize[0];
969 }
970 break;
971
973 y_ptr = 0;
974 for (lines = 0; lines <
s->avctx->height; lines++) {
975 pixel_ptr = y_ptr;
976 /* disregard the line packets; instead, iterate through all
977 * pixels on a row */
979 pixel_countdown =
s->avctx->width;
/* Width is in pixels, not bytes */
980
981 while (pixel_countdown > 0) {
983 break;
984 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
985 if (byte_run > 0) {
986 pixel = bytestream2_get_le24(&g2);
988 for (j = 0; j < byte_run; j++) {
990 pixel_ptr += 3;
991 pixel_countdown--;
992 if (pixel_countdown < 0)
994 pixel_countdown);
995 }
996 } else { /* copy pixels if byte_run < 0 */
997 byte_run = -byte_run;
999 break;
1001 for (j = 0; j < byte_run; j++) {
1002 pixel = bytestream2_get_le24(&g2);
1004 pixel_ptr += 3;
1005 pixel_countdown--;
1006 if (pixel_countdown < 0)
1008 pixel_countdown);
1009 }
1010 }
1011 }
1012
1013 y_ptr +=
s->frame->linesize[0];
1014 }
1015 break;
1016
1019 /* copy the chunk (uncompressed frame) */
1020 if (chunk_size - 6 > (
unsigned int)(
FFALIGN(
s->avctx->width, 2) *
s->avctx->height)*3) {
1022 "bigger than image, skipping chunk\n", chunk_size - 6);
1024 } else {
1025 for (y_ptr = 0; y_ptr <
s->frame->linesize[0] *
s->avctx->height;
1026 y_ptr +=
s->frame->linesize[0]) {
1027
1029 if (
s->avctx->width & 1)
1031 }
1032 }
1033 break;
1034
1036 /* some sort of a thumbnail? disregard this chunk... */
1038 break;
1039
1040 default:
1042 break;
1043 }
1044
1047 } else {
1049 break;
1050 }
1051
1053 num_chunks--;
1054 }
1055
1056 /* by the end of the chunk, the stream ptr should equal the frame
1057 * size (minus 1, possibly); if it doesn't, issue a warning */
1061
1064
1065 *got_frame = 1;
1066
1067 return buf_size;
1068 }
1069
1072 {
1073 const uint8_t *buf = avpkt->
data;
1074 int buf_size = avpkt->
size;
1077 buf, buf_size);
1081 buf, buf_size);
1084 buf, buf_size);
1085 }
1086
1087 /* Should not get here, ever as the pix_fmt is processed */
1088 /* in flic_decode_init and the above if should deal with */
1089 /* the finite set of possibilities allowable by here. */
1090 /* But in case we do, just error out. */
1091 av_log(avctx,
AV_LOG_ERROR,
"Unknown FLC format, my science cannot explain how this happened.\n");
1093 }
1094
1095
1097 {
1099
1101
1102 return 0;
1103 }
1104
1115 };