46 #define FLI_256_COLOR 4
54 #define FLI_DTA_BRUN 25
55 #define FLI_DTA_COPY 26
58 #define FLI_TYPE_CODE (0xAF11)
59 #define FLC_FLX_TYPE_CODE (0xAF12)
60 #define FLC_DTA_TYPE_CODE (0xAF44)
61 #define FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE (0xAF13)
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; \
82 unsigned char *fli_header = (
unsigned char *)avctx->
extradata;
97 if (
s->avctx->extradata_size == 12) {
105 for (
i = 0;
i < 256;
i++) {
118 s->fli_type =
AV_RL16(&fli_header[4]);
119 depth =
AV_RL16(&fli_header[12]);
136 av_log(avctx,
AV_LOG_ERROR,
"Unknown FLC/FLX depth of %d Bpp is unsupported.\n",depth);
150 AVFrame *rframe,
int *got_frame,
151 const uint8_t *buf,
int buf_size)
158 unsigned char palette_idx1;
159 unsigned char palette_idx2;
164 unsigned int chunk_size;
172 unsigned char r,
g,
b;
175 int compressed_lines;
182 unsigned char *pixels;
183 unsigned int pixel_limit;
190 pixels =
s->frame->data[0];
191 pixel_limit =
s->avctx->height *
s->frame->linesize[0];
198 num_chunks = bytestream2_get_le16(&g2);
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);
218 chunk_type = bytestream2_get_le16(&g2);
220 switch (chunk_type) {
232 color_packets = bytestream2_get_le16(&g2);
234 for (
i = 0;
i < color_packets;
i++) {
236 palette_ptr += bytestream2_get_byte(&g2);
239 color_changes = bytestream2_get_byte(&g2);
242 if (color_changes == 0)
248 for (j = 0; j < color_changes; j++) {
252 if ((
unsigned)palette_ptr >= 256)
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;
270 compressed_lines = bytestream2_get_le16(&g2);
271 while (compressed_lines > 0) {
274 if (y_ptr > pixel_limit)
276 line_packets =
sign_extend(bytestream2_get_le16(&g2), 16);
277 if ((line_packets & 0xC000) == 0xC000) {
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) {
287 pixel_ptr= y_ptr +
s->frame->linesize[0] - 1;
289 pixels[pixel_ptr] = line_packets & 0xff;
294 pixel_countdown =
s->avctx->width;
295 for (
i = 0;
i < line_packets;
i++) {
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);
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;
316 for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
317 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
322 y_ptr +=
s->frame->linesize[0];
329 starting_line = bytestream2_get_le16(&g2);
330 if (starting_line >=
s->avctx->height)
333 y_ptr += starting_line *
s->frame->linesize[0];
335 compressed_lines = bytestream2_get_le16(&g2);
336 while (compressed_lines > 0) {
339 pixel_countdown =
s->avctx->width;
342 line_packets = bytestream2_get_byte(&g2);
343 if (line_packets > 0) {
344 for (
i = 0;
i < line_packets;
i++) {
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);
356 for (j = 0; j < byte_run; j++, pixel_countdown--) {
357 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
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;
370 y_ptr +=
s->frame->linesize[0];
378 s->frame->linesize[0] *
s->avctx->height);
385 for (lines = 0; lines <
s->avctx->height; lines++) {
390 pixel_countdown =
s->avctx->width;
391 while (pixel_countdown > 0) {
394 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
401 palette_idx1 = bytestream2_get_byte(&g2);
403 for (j = 0; j < byte_run; j++) {
404 pixels[pixel_ptr++] = palette_idx1;
406 if (pixel_countdown < 0)
408 pixel_countdown, lines);
411 byte_run = -byte_run;
415 for (j = 0; j < byte_run; j++) {
416 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
418 if (pixel_countdown < 0)
420 pixel_countdown, lines);
425 y_ptr +=
s->frame->linesize[0];
431 if (chunk_size - 6 !=
FFALIGN(
s->avctx->width, 4) *
s->avctx->height) {
433 "has incorrect size, skipping chunk\n", chunk_size - 6);
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)
470 "and final chunk ptr = %d\n", buf_size,
475 if (
s->new_palette) {
476 s->frame->palette_has_changed = 1;
489 AVFrame *rframe,
int *got_frame,
490 const uint8_t *buf,
int buf_size)
498 unsigned char palette_idx1;
503 unsigned int chunk_size;
509 int compressed_lines;
515 unsigned char *pixels;
517 unsigned int pixel_limit;
524 pixels =
s->frame->data[0];
525 pixel_limit =
s->avctx->height *
s->frame->linesize[0];
529 num_chunks = bytestream2_get_le16(&g2);
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);
550 chunk_type = bytestream2_get_le16(&g2);
553 switch (chunk_type) {
560 "Unexpected Palette chunk %d in non-palettized FLC\n",
568 compressed_lines = bytestream2_get_le16(&g2);
569 while (compressed_lines > 0) {
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];
584 pixel_countdown =
s->avctx->width;
585 for (
i = 0;
i < line_packets;
i++) {
589 pixel_skip = bytestream2_get_byte(&g2);
590 pixel_ptr += (pixel_skip*2);
591 pixel_countdown -= pixel_skip;
592 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
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;
605 for (j = 0; j < byte_run; j++, pixel_countdown--) {
606 *((
signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
612 y_ptr +=
s->frame->linesize[0];
624 memset(pixels, 0x0000,
625 s->frame->linesize[0] *
s->avctx->height);
630 for (lines = 0; lines <
s->avctx->height; lines++) {
635 pixel_countdown = (
s->avctx->width * 2);
637 while (pixel_countdown > 0) {
640 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
642 palette_idx1 = bytestream2_get_byte(&g2);
644 for (j = 0; j < byte_run; j++) {
645 pixels[pixel_ptr++] = palette_idx1;
647 if (pixel_countdown < 0)
649 pixel_countdown, lines);
652 byte_run = -byte_run;
656 for (j = 0; j < byte_run; j++) {
657 palette_idx1 = bytestream2_get_byte(&g2);
658 pixels[pixel_ptr++] = palette_idx1;
660 if (pixel_countdown < 0)
662 pixel_countdown, lines);
674 pixel_countdown =
s->avctx->width;
675 while (pixel_countdown > 0) {
676 *((
signed short*)(&pixels[pixel_ptr])) =
AV_RL16(&buf[pixel_ptr]);
680 y_ptr +=
s->frame->linesize[0];
686 for (lines = 0; lines <
s->avctx->height; lines++) {
691 pixel_countdown =
s->avctx->width;
693 while (pixel_countdown > 0) {
696 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
698 pixel = bytestream2_get_le16(&g2);
700 for (j = 0; j < byte_run; j++) {
701 *((
signed short*)(&pixels[pixel_ptr])) =
pixel;
704 if (pixel_countdown < 0)
709 byte_run = -byte_run;
713 for (j = 0; j < byte_run; j++) {
714 *((
signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
717 if (pixel_countdown < 0)
724 y_ptr +=
s->frame->linesize[0];
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);
739 for (y_ptr = 0; y_ptr <
s->frame->linesize[0] *
s->avctx->height;
740 y_ptr +=
s->frame->linesize[0]) {
742 pixel_countdown =
s->avctx->width;
744 while (pixel_countdown > 0) {
745 *((
signed short*)(&pixels[y_ptr + pixel_ptr])) = bytestream2_get_le16(&g2);
749 if (
s->avctx->width & 1)
791 AVFrame *rframe,
int *got_frame,
792 const uint8_t *buf,
int buf_size)
798 unsigned char palette_idx1;
803 unsigned int chunk_size;
809 int compressed_lines;
815 unsigned char *pixels;
817 unsigned int pixel_limit;
824 pixels =
s->frame->data[0];
825 pixel_limit =
s->avctx->height *
s->frame->linesize[0];
829 num_chunks = bytestream2_get_le16(&g2);
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);
850 chunk_type = bytestream2_get_le16(&g2);
853 switch (chunk_type) {
860 "Unexpected Palette chunk %d in non-palettized FLC\n",
868 compressed_lines = bytestream2_get_le16(&g2);
869 while (compressed_lines > 0) {
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];
884 pixel_countdown =
s->avctx->width;
885 for (
i = 0;
i < line_packets;
i++) {
889 pixel_skip = bytestream2_get_byte(&g2);
890 pixel_ptr += (pixel_skip*3);
891 pixel_countdown -= pixel_skip;
892 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
894 byte_run = -byte_run;
895 pixel = bytestream2_get_le24(&g2);
897 for (j = 0; j < byte_run; j++, pixel_countdown -= 1) {
905 for (j = 0; j < byte_run; j++, pixel_countdown--) {
906 pixel = bytestream2_get_le24(&g2);
913 y_ptr +=
s->frame->linesize[0];
926 s->frame->linesize[0] *
s->avctx->height);
931 for (lines = 0; lines <
s->avctx->height; lines++) {
936 pixel_countdown = (
s->avctx->width * 3);
938 while (pixel_countdown > 0) {
941 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
943 palette_idx1 = bytestream2_get_byte(&g2);
945 for (j = 0; j < byte_run; j++) {
946 pixels[pixel_ptr++] = palette_idx1;
948 if (pixel_countdown < 0)
950 pixel_countdown, lines);
953 byte_run = -byte_run;
957 for (j = 0; j < byte_run; j++) {
958 palette_idx1 = bytestream2_get_byte(&g2);
959 pixels[pixel_ptr++] = palette_idx1;
961 if (pixel_countdown < 0)
963 pixel_countdown, lines);
968 y_ptr +=
s->frame->linesize[0];
974 for (lines = 0; lines <
s->avctx->height; lines++) {
979 pixel_countdown =
s->avctx->width;
981 while (pixel_countdown > 0) {
984 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
986 pixel = bytestream2_get_le24(&g2);
988 for (j = 0; j < byte_run; j++) {
992 if (pixel_countdown < 0)
997 byte_run = -byte_run;
1001 for (j = 0; j < byte_run; j++) {
1002 pixel = bytestream2_get_le24(&g2);
1006 if (pixel_countdown < 0)
1013 y_ptr +=
s->frame->linesize[0];
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);
1025 for (y_ptr = 0; y_ptr <
s->frame->linesize[0] *
s->avctx->height;
1026 y_ptr +=
s->frame->linesize[0]) {
1029 if (
s->avctx->width & 1)
1073 const uint8_t *buf = avpkt->
data;
1074 int buf_size = avpkt->
size;
1091 av_log(avctx,
AV_LOG_ERROR,
"Unknown FLC format, my science cannot explain how this happened.\n");