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
46
47 #define FLI_256_COLOR 4
55 #define FLI_DTA_BRUN 25
56 #define FLI_DTA_COPY 26
58
59 #define FLI_TYPE_CODE (0xAF11)
60 #define FLC_FLX_TYPE_CODE (0xAF12)
61 #define FLC_DTA_TYPE_CODE (0xAF44) /* Marks an "Extended FLC" comes from Dave's Targa Animator (DTA) */
62 #define FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE (0xAF13)
63
64 #define CHECK_PIXEL_PTR(n) \
65 if (pixel_ptr + n > pixel_limit) { \
66 av_log (s->avctx, AV_LOG_ERROR, "Invalid pixel_ptr = %d > pixel_limit = %d\n", \
67 pixel_ptr + n, pixel_limit); \
68 return AVERROR_INVALIDDATA; \
69 } \
70
74
77 int fli_type;
/* either 0xAF11 or 0xAF12, affects palette resolution */
79
81 {
83 unsigned char *fli_header = (
unsigned char *)avctx->
extradata;
84 int depth;
85
94 }
95
97
99 /* special case for magic carpet FLIs */
101 depth = 8;
104 int i;
105
106 for (i = 0; i < 256; i++) {
108 ptr += 4;
109 }
110 depth = 8;
111 /* FLI in MOV, see e.g. FFmpeg trac issue #626 */
114 /* see FFmpeg ticket #1234 */
117 depth = 8;
118 } else {
120 depth =
AV_RL16(&fli_header[12]);
121 }
122
123 if (depth == 0) {
124 depth = 8; /* Some FLC generators set depth to zero, when they mean 8Bpp. Fix up here */
125 }
126
128 depth = 15; /* Original Autodesk FLX's say the depth is 16Bpp when it is really 15Bpp */
129 }
130
131 switch (depth) {
136 default :
137 av_log(avctx,
AV_LOG_ERROR,
"Unknown FLC/FLX depth of %d Bpp is unsupported.\n",depth);
139 }
140
144
146
147 return 0;
148 }
149
151 void *
data,
int *got_frame,
153 {
155
157 int pixel_ptr;
158 int palette_ptr;
159 unsigned char palette_idx1;
160 unsigned char palette_idx2;
161
163 int num_chunks;
164
165 unsigned int chunk_size;
166 int chunk_type;
167
168 int i, j, ret;
169
170 int color_packets;
171 int color_changes;
172 int color_shift;
173 unsigned char r,
g,
b;
174
175 int lines;
176 int compressed_lines;
177 int starting_line;
178 signed short line_packets;
179 int y_ptr;
180 int byte_run;
181 int pixel_skip;
182 int pixel_countdown;
184 unsigned int pixel_limit;
185
187
189 return ret;
190
195 frame_size = bytestream2_get_le32(&g2);
196 if (frame_size > buf_size)
197 frame_size = buf_size;
199 num_chunks = bytestream2_get_le16(&g2);
201
202 if (frame_size < 16)
204
205 frame_size -= 16;
206
207 /* iterate through the chunks */
208 while ((frame_size >= 6) && (num_chunks > 0) &&
210 int stream_ptr_after_chunk;
211 chunk_size = bytestream2_get_le32(&g2);
212 if (chunk_size > frame_size) {
214 "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
216 }
218
219 chunk_type = bytestream2_get_le16(&g2);
220
221 switch (chunk_type) {
224 /* check special case: If this file is from the Magic Carpet
225 * game and uses 6-bit colors even though it reports 256-color
226 * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during
227 * initialization) */
229 color_shift = 0;
230 else
231 color_shift = 2;
232 /* set up the palette */
233 color_packets = bytestream2_get_le16(&g2);
234 palette_ptr = 0;
235 for (i = 0; i < color_packets; i++) {
236 /* first byte is how many colors to skip */
237 palette_ptr += bytestream2_get_byte(&g2);
238
239 /* next byte indicates how many entries to change */
240 color_changes = bytestream2_get_byte(&g2);
241
242 /* if there are 0 color changes, there are actually 256 */
243 if (color_changes == 0)
244 color_changes = 256;
245
247 break;
248
249 for (j = 0; j < color_changes; j++) {
250 unsigned int entry;
251
252 /* wrap around, for good measure */
253 if ((unsigned)palette_ptr >= 256)
254 palette_ptr = 0;
255
256 r = bytestream2_get_byte(&g2) << color_shift;
257 g = bytestream2_get_byte(&g2) << color_shift;
258 b = bytestream2_get_byte(&g2) << color_shift;
259 entry = 0xFF
U << 24 | r << 16 | g << 8 |
b;
260 if (color_shift == 2)
261 entry |= entry >> 6 & 0x30303;
262 if (s->
palette[palette_ptr] != entry)
264 s->
palette[palette_ptr++] = entry;
265 }
266 }
267 break;
268
270 y_ptr = 0;
271 compressed_lines = bytestream2_get_le16(&g2);
272 while (compressed_lines > 0) {
274 break;
275 if (y_ptr > pixel_limit)
277 line_packets = bytestream2_get_le16(&g2);
278 if ((line_packets & 0xC000) == 0xC000) {
279 // line skip opcode
280 line_packets = -line_packets;
284 } else if ((line_packets & 0xC000) == 0x4000) {
286 } else if ((line_packets & 0xC000) == 0x8000) {
287 // "last byte" opcode
290 pixels[pixel_ptr] = line_packets & 0xff;
291 } else {
292 compressed_lines--;
293 pixel_ptr = y_ptr;
296 for (i = 0; i < line_packets; i++) {
298 break;
299 /* account for the skip bytes */
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 byte_run = -byte_run;
306 palette_idx1 = bytestream2_get_byte(&g2);
307 palette_idx2 = bytestream2_get_byte(&g2);
309 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
310 pixels[pixel_ptr++] = palette_idx1;
311 pixels[pixel_ptr++] = palette_idx2;
312 }
313 } else {
316 break;
317 for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
318 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
319 }
320 }
321 }
322
324 }
325 }
326 break;
327
329 /* line compressed */
330 starting_line = bytestream2_get_le16(&g2);
333 y_ptr = 0;
335
336 compressed_lines = bytestream2_get_le16(&g2);
337 while (compressed_lines > 0) {
338 pixel_ptr = y_ptr;
342 break;
343 line_packets = bytestream2_get_byte(&g2);
344 if (line_packets > 0) {
345 for (i = 0; i < line_packets; i++) {
346 /* account for the skip bytes */
348 break;
349 pixel_skip = bytestream2_get_byte(&g2);
350 pixel_ptr += pixel_skip;
351 pixel_countdown -= pixel_skip;
352 byte_run =
sign_extend(bytestream2_get_byte(&g2),8);
353 if (byte_run > 0) {
356 break;
357 for (j = 0; j < byte_run; j++, pixel_countdown--) {
358 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
359 }
360 } else if (byte_run < 0) {
361 byte_run = -byte_run;
362 palette_idx1 = bytestream2_get_byte(&g2);
364 for (j = 0; j < byte_run; j++, pixel_countdown--) {
365 pixels[pixel_ptr++] = palette_idx1;
366 }
367 }
368 }
369 }
370
372 compressed_lines--;
373 }
374 break;
375
377 /* set the whole frame to color 0 (which is usually black) */
378 memset(pixels, 0,
380 break;
381
383 /* Byte run compression: This chunk type only occurs in the first
384 * FLI frame and it will update the entire frame. */
385 y_ptr = 0;
386 for (lines = 0; lines < s->
avctx->
height; lines++) {
387 pixel_ptr = y_ptr;
388 /* disregard the line packets; instead, iterate through all
389 * pixels on a row */
392 while (pixel_countdown > 0) {
394 break;
395 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
396 if (!byte_run) {
399 }
400
401 if (byte_run > 0) {
402 palette_idx1 = bytestream2_get_byte(&g2);
404 for (j = 0; j < byte_run; j++) {
405 pixels[pixel_ptr++] = palette_idx1;
406 pixel_countdown--;
407 if (pixel_countdown < 0)
409 pixel_countdown, lines);
410 }
411 } else { /* copy bytes if byte_run < 0 */
412 byte_run = -byte_run;
415 break;
416 for (j = 0; j < byte_run; j++) {
417 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
418 pixel_countdown--;
419 if (pixel_countdown < 0)
421 pixel_countdown, lines);
422 }
423 }
424 }
425
427 }
428 break;
429
431 /* copy the chunk (uncompressed frame) */
434 "has incorrect size, skipping chunk\n", chunk_size - 6);
436 } else {
443 }
444 }
445 break;
446
448 /* some sort of a thumbnail? disregard this chunk... */
449 break;
450
451 default:
453 break;
454 }
455
458 } else {
460 break;
461 }
462
463 frame_size -= chunk_size;
464 num_chunks--;
465 }
466
467 /* by the end of the chunk, the stream ptr should equal the frame
468 * size (minus 1 or 2, possibly); if it doesn't, issue a warning */
471 "and final chunk ptr = %d\n", buf_size,
473
474 /* make the palette available on the way out */
479 }
480
482 return ret;
483
484 *got_frame = 1;
485
486 return buf_size;
487 }
488
490 void *
data,
int *got_frame,
492 {
493 /* Note, the only difference between the 15Bpp and 16Bpp */
494 /* Format is the pixel format, the packets are processed the same. */
496
498 int pixel_ptr;
499 unsigned char palette_idx1;
500
502 int num_chunks;
503
504 unsigned int chunk_size;
505 int chunk_type;
506
507 int i, j, ret;
508
509 int lines;
510 int compressed_lines;
511 signed short line_packets;
512 int y_ptr;
513 int byte_run;
514 int pixel_skip;
515 int pixel_countdown;
518 unsigned int pixel_limit;
519
521
523 return ret;
524
527
528 frame_size = bytestream2_get_le32(&g2);
530 num_chunks = bytestream2_get_le16(&g2);
532 if (frame_size > buf_size)
533 frame_size = buf_size;
534
535 if (frame_size < 16)
537 frame_size -= 16;
538
539 /* iterate through the chunks */
540 while ((frame_size > 0) && (num_chunks > 0) &&
542 int stream_ptr_after_chunk;
543 chunk_size = bytestream2_get_le32(&g2);
544 if (chunk_size > frame_size) {
546 "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
548 }
550
551 chunk_type = bytestream2_get_le16(&g2);
552
553
554 switch (chunk_type) {
557 /* For some reason, it seems that non-palettized flics do
558 * include one of these chunks in their first frame.
559 * Why I do not know, it seems rather extraneous. */
561 "Unexpected Palette chunk %d in non-palettized FLC\n",
562 chunk_type);
564 break;
565
568 y_ptr = 0;
569 compressed_lines = bytestream2_get_le16(&g2);
570 while (compressed_lines > 0) {
572 break;
573 if (y_ptr > pixel_limit)
575 line_packets = bytestream2_get_le16(&g2);
576 if (line_packets < 0) {
577 line_packets = -line_packets;
581 } else {
582 compressed_lines--;
583 pixel_ptr = y_ptr;
586 for (i = 0; i < line_packets; i++) {
587 /* account for the skip bytes */
589 break;
590 pixel_skip = bytestream2_get_byte(&g2);
591 pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */
592 pixel_countdown -= pixel_skip;
593 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
594 if (byte_run < 0) {
595 byte_run = -byte_run;
596 pixel = bytestream2_get_le16(&g2);
598 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
599 *((signed short*)(&pixels[pixel_ptr])) = pixel;
600 pixel_ptr += 2;
601 }
602 } else {
604 break;
606 for (j = 0; j < byte_run; j++, pixel_countdown--) {
607 *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
608 pixel_ptr += 2;
609 }
610 }
611 }
612
614 }
615 }
616 break;
617
621 break;
622
624 /* set the whole frame to 0x0000 which is black in both 15Bpp and 16Bpp modes. */
625 memset(pixels, 0x0000,
627 break;
628
630 y_ptr = 0;
631 for (lines = 0; lines < s->
avctx->
height; lines++) {
632 pixel_ptr = y_ptr;
633 /* disregard the line packets; instead, iterate through all
634 * pixels on a row */
637
638 while (pixel_countdown > 0) {
640 break;
641 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
642 if (byte_run > 0) {
643 palette_idx1 = bytestream2_get_byte(&g2);
645 for (j = 0; j < byte_run; j++) {
646 pixels[pixel_ptr++] = palette_idx1;
647 pixel_countdown--;
648 if (pixel_countdown < 0)
650 pixel_countdown, lines);
651 }
652 } else { /* copy bytes if byte_run < 0 */
653 byte_run = -byte_run;
655 break;
657 for (j = 0; j < byte_run; j++) {
658 palette_idx1 = bytestream2_get_byte(&g2);
659 pixels[pixel_ptr++] = palette_idx1;
660 pixel_countdown--;
661 if (pixel_countdown < 0)
663 pixel_countdown, lines);
664 }
665 }
666 }
667
668 /* Now FLX is strange, in that it is "byte" as opposed to "pixel" run length compressed.
669 * This does not give us any good opportunity to perform word endian conversion
670 * during decompression. So if it is required (i.e., this is not a LE target, we do
671 * a second pass over the line here, swapping the bytes.
672 */
673 #if HAVE_BIGENDIAN
674 pixel_ptr = y_ptr;
676 while (pixel_countdown > 0) {
677 *((
signed short*)(&pixels[pixel_ptr])) =
AV_RL16(&buf[pixel_ptr]);
678 pixel_ptr += 2;
679 }
680 #endif
682 }
683 break;
684
686 y_ptr = 0;
687 for (lines = 0; lines < s->
avctx->
height; lines++) {
688 pixel_ptr = y_ptr;
689 /* disregard the line packets; instead, iterate through all
690 * pixels on a row */
692 pixel_countdown = s->
avctx->
width;
/* Width is in pixels, not bytes */
693
694 while (pixel_countdown > 0) {
696 break;
697 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
698 if (byte_run > 0) {
699 pixel = bytestream2_get_le16(&g2);
701 for (j = 0; j < byte_run; j++) {
702 *((signed short*)(&pixels[pixel_ptr])) = pixel;
703 pixel_ptr += 2;
704 pixel_countdown--;
705 if (pixel_countdown < 0)
707 pixel_countdown);
708 }
709 } else { /* copy pixels if byte_run < 0 */
710 byte_run = -byte_run;
712 break;
714 for (j = 0; j < byte_run; j++) {
715 *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
716 pixel_ptr += 2;
717 pixel_countdown--;
718 if (pixel_countdown < 0)
720 pixel_countdown);
721 }
722 }
723 }
724
726 }
727 break;
728
731 /* copy the chunk (uncompressed frame) */
734 "bigger than image, skipping chunk\n", chunk_size - 6);
736 } else {
737
740
742 pixel_ptr = 0;
743 while (pixel_countdown > 0) {
744 *((signed short*)(&pixels[y_ptr + pixel_ptr])) = bytestream2_get_le16(&g2);
745 pixel_ptr += 2;
746 pixel_countdown--;
747 }
750 }
751 }
752 break;
753
755 /* some sort of a thumbnail? disregard this chunk... */
757 break;
758
759 default:
761 break;
762 }
763
766 } else {
768 break;
769 }
770
771 frame_size -= chunk_size;
772 num_chunks--;
773 }
774
775 /* by the end of the chunk, the stream ptr should equal the frame
776 * size (minus 1, possibly); if it doesn't, issue a warning */
780
782 return ret;
783
784 *got_frame = 1;
785
786 return buf_size;
787 }
788
790 void *
data,
int *got_frame,
792 {
794
796 int pixel_ptr;
797 unsigned char palette_idx1;
798
800 int num_chunks;
801
802 unsigned int chunk_size;
803 int chunk_type;
804
805 int i, j, ret;
806
807 int lines;
808 int compressed_lines;
809 signed short line_packets;
810 int y_ptr;
811 int byte_run;
812 int pixel_skip;
813 int pixel_countdown;
816 unsigned int pixel_limit;
817
819
821 return ret;
822
825
826 frame_size = bytestream2_get_le32(&g2);
828 num_chunks = bytestream2_get_le16(&g2);
830 if (frame_size > buf_size)
831 frame_size = buf_size;
832
833 if (frame_size < 16)
835 frame_size -= 16;
836
837 /* iterate through the chunks */
838 while ((frame_size > 0) && (num_chunks > 0) &&
840 int stream_ptr_after_chunk;
841 chunk_size = bytestream2_get_le32(&g2);
842 if (chunk_size > frame_size) {
844 "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
846 }
848
849 chunk_type = bytestream2_get_le16(&g2);
850
851
852 switch (chunk_type) {
855 /* For some reason, it seems that non-palettized flics do
856 * include one of these chunks in their first frame.
857 * Why I do not know, it seems rather extraneous. */
859 "Unexpected Palette chunk %d in non-palettized FLC\n",
860 chunk_type);
862 break;
863
866 y_ptr = 0;
867 compressed_lines = bytestream2_get_le16(&g2);
868 while (compressed_lines > 0) {
870 break;
871 if (y_ptr > pixel_limit)
873 line_packets = bytestream2_get_le16(&g2);
874 if (line_packets < 0) {
875 line_packets = -line_packets;
879 } else {
880 compressed_lines--;
881 pixel_ptr = y_ptr;
884 for (i = 0; i < line_packets; i++) {
885 /* account for the skip bytes */
887 break;
888 pixel_skip = bytestream2_get_byte(&g2);
889 pixel_ptr += (pixel_skip*3); /* Pixel is 3 bytes wide */
890 pixel_countdown -= pixel_skip;
891 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
892 if (byte_run < 0) {
893 byte_run = -byte_run;
894 pixel = bytestream2_get_le24(&g2);
896 for (j = 0; j < byte_run; j++, pixel_countdown -= 1) {
897 AV_WL24(&pixels[pixel_ptr], pixel);
898 pixel_ptr += 3;
899 }
900 } else {
902 break;
904 for (j = 0; j < byte_run; j++, pixel_countdown--) {
905 pixel = bytestream2_get_le24(&g2);
906 AV_WL24(&pixels[pixel_ptr], pixel);
907 pixel_ptr += 3;
908 }
909 }
910 }
911
913 }
914 }
915 break;
916
920 break;
921
923 /* set the whole frame to 0x00 which is black for 24 bit mode. */
924 memset(pixels, 0x00,
926 break;
927
929 y_ptr = 0;
930 for (lines = 0; lines < s->
avctx->
height; lines++) {
931 pixel_ptr = y_ptr;
932 /* disregard the line packets; instead, iterate through all
933 * pixels on a row */
936
937 while (pixel_countdown > 0) {
939 break;
940 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
941 if (byte_run > 0) {
942 palette_idx1 = bytestream2_get_byte(&g2);
944 for (j = 0; j < byte_run; j++) {
945 pixels[pixel_ptr++] = palette_idx1;
946 pixel_countdown--;
947 if (pixel_countdown < 0)
949 pixel_countdown, lines);
950 }
951 } else { /* copy bytes if byte_run < 0 */
952 byte_run = -byte_run;
954 break;
956 for (j = 0; j < byte_run; j++) {
957 palette_idx1 = bytestream2_get_byte(&g2);
958 pixels[pixel_ptr++] = palette_idx1;
959 pixel_countdown--;
960 if (pixel_countdown < 0)
962 pixel_countdown, lines);
963 }
964 }
965 }
966
968 }
969 break;
970
972 y_ptr = 0;
973 for (lines = 0; lines < s->
avctx->
height; lines++) {
974 pixel_ptr = y_ptr;
975 /* disregard the line packets; instead, iterate through all
976 * pixels on a row */
978 pixel_countdown = s->
avctx->
width;
/* Width is in pixels, not bytes */
979
980 while (pixel_countdown > 0) {
982 break;
983 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
984 if (byte_run > 0) {
985 pixel = bytestream2_get_le24(&g2);
987 for (j = 0; j < byte_run; j++) {
988 AV_WL24(pixels + pixel_ptr, pixel);
989 pixel_ptr += 3;
990 pixel_countdown--;
991 if (pixel_countdown < 0)
993 pixel_countdown);
994 }
995 } else { /* copy pixels if byte_run < 0 */
996 byte_run = -byte_run;
998 break;
1000 for (j = 0; j < byte_run; j++) {
1001 pixel = bytestream2_get_le24(&g2);
1002 AV_WL24(pixels + pixel_ptr, pixel);
1003 pixel_ptr += 3;
1004 pixel_countdown--;
1005 if (pixel_countdown < 0)
1007 pixel_countdown);
1008 }
1009 }
1010 }
1011
1013 }
1014 break;
1015
1018 /* copy the chunk (uncompressed frame) */
1021 "bigger than image, skipping chunk\n", chunk_size - 6);
1023 } else {
1026
1028 pixel_ptr = 0;
1029 while (pixel_countdown > 0) {
1030 pixel = bytestream2_get_le24(&g2);
1031 AV_WL24(&pixels[y_ptr + pixel_ptr], pixel);
1032 pixel_ptr += 3;
1033 pixel_countdown--;
1034 }
1037 }
1038 }
1039 break;
1040
1042 /* some sort of a thumbnail? disregard this chunk... */
1044 break;
1045
1046 default:
1048 break;
1049 }
1050
1053 } else {
1055 break;
1056 }
1057
1058 frame_size -= chunk_size;
1059 num_chunks--;
1060 }
1061
1062 /* by the end of the chunk, the stream ptr should equal the frame
1063 * size (minus 1, possibly); if it doesn't, issue a warning */
1067
1069 return ret;
1070
1071 *got_frame = 1;
1072
1073 return buf_size;
1074 }
1075
1077 void *
data,
int *got_frame,
1079 {
1081 int buf_size = avpkt->
size;
1084 buf, buf_size);
1088 buf, buf_size);
1091 buf, buf_size);
1092 }
1093
1094 /* Should not get here, ever as the pix_fmt is processed */
1095 /* in flic_decode_init and the above if should deal with */
1096 /* the finite set of possibilities allowable by here. */
1097 /* But in case we do, just error out. */
1098 av_log(avctx,
AV_LOG_ERROR,
"Unknown FLC format, my science cannot explain how this happened.\n");
1100 }
1101
1102
1104 {
1106
1108
1109 return 0;
1110 }
1111
1122 };
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
This structure describes decoded (raw) audio or video data.
ptrdiff_t const GLvoid * data
#define AV_LOG_WARNING
Something somehow does not look correct.
#define CHECK_PIXEL_PTR(n)
static av_cold int init(AVCodecContext *avctx)
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, void *data, int *got_frame, const uint8_t *buf, int buf_size)
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame)
Identical in function to av_frame_make_writable(), except it uses ff_get_buffer() to allocate the buf...
static int flic_decode_frame_8BPP(AVCodecContext *avctx, void *data, int *got_frame, const uint8_t *buf, int buf_size)
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
8 bits with AV_PIX_FMT_RGB32 palette
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static int flic_decode_frame_24BPP(AVCodecContext *avctx, void *data, int *got_frame, const uint8_t *buf, int buf_size)
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
#define FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE
const char * name
Name of the codec implementation.
int width
picture width / height.
#define FLC_FLX_TYPE_CODE
packed RGB 8:8:8, 24bpp, BGRBGR...
static av_always_inline int bytestream2_tell(GetByteContext *g)
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
main external API structure.
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
static int flic_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
static av_cold int flic_decode_end(AVCodecContext *avctx)
int palette_has_changed
Tell user application that palette has changed from previous frame.
static av_const int sign_extend(int val, unsigned bits)
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
common internal api header.
#define AV_PIX_FMT_RGB555
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
unsigned int palette[256]
#define AV_PIX_FMT_RGB565
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
This structure stores compressed data.
static av_cold int flic_decode_init(AVCodecContext *avctx)
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.