48 #define FLI_256_COLOR 4
56 #define FLI_DTA_BRUN 25
57 #define FLI_DTA_COPY 26
60 #define FLI_TYPE_CODE (0xAF11)
61 #define FLC_FLX_TYPE_CODE (0xAF12)
62 #define FLC_DTA_TYPE_CODE (0xAF44)
63 #define FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE (0xAF13)
65 #define CHECK_PIXEL_PTR(n) \
66 if (pixel_ptr + n > pixel_limit) { \
67 av_log (s->avctx, AV_LOG_ERROR, "Invalid pixel_ptr = %d > pixel_limit = %d\n", \
68 pixel_ptr + n, pixel_limit); \
69 return AVERROR_INVALIDDATA; \
84 unsigned char *fli_header = (
unsigned char *)avctx->
extradata;
99 if (
s->avctx->extradata_size == 12) {
107 for (
i = 0;
i < 256;
i++) {
120 s->fli_type =
AV_RL16(&fli_header[4]);
121 depth =
AV_RL16(&fli_header[12]);
138 av_log(avctx,
AV_LOG_ERROR,
"Unknown FLC/FLX depth of %d Bpp is unsupported.\n",depth);
152 AVFrame *rframe,
int *got_frame,
153 const uint8_t *buf,
int buf_size)
160 unsigned char palette_idx1;
161 unsigned char palette_idx2;
166 unsigned int chunk_size;
174 unsigned char r,
g,
b;
177 int compressed_lines;
184 unsigned char *pixels;
185 unsigned int pixel_limit;
192 pixels =
s->frame->data[0];
193 pixel_limit =
s->avctx->height *
s->frame->linesize[0];
200 num_chunks = bytestream2_get_le16(&g2);
209 while ((
frame_size >= 6) && (num_chunks > 0) &&
211 int stream_ptr_after_chunk;
212 chunk_size = bytestream2_get_le32(&g2);
215 "Invalid chunk_size = %u > frame_size = %u\n", chunk_size,
frame_size);
220 chunk_type = bytestream2_get_le16(&g2);
222 switch (chunk_type) {
234 color_packets = bytestream2_get_le16(&g2);
236 for (
i = 0;
i < color_packets;
i++) {
238 palette_ptr += bytestream2_get_byte(&g2);
241 color_changes = bytestream2_get_byte(&g2);
244 if (color_changes == 0)
250 for (j = 0; j < color_changes; j++) {
254 if ((
unsigned)palette_ptr >= 256)
257 r = bytestream2_get_byte(&g2) << color_shift;
258 g = bytestream2_get_byte(&g2) << color_shift;
259 b = bytestream2_get_byte(&g2) << color_shift;
260 entry = 0xFF
U << 24 |
r << 16 |
g << 8 |
b;
261 if (color_shift == 2)
262 entry |= entry >> 6 & 0x30303;
263 if (
s->palette[palette_ptr] != entry)
265 s->palette[palette_ptr++] = entry;
272 compressed_lines = bytestream2_get_le16(&g2);
273 while (compressed_lines > 0) {
276 if (y_ptr > pixel_limit)
278 line_packets =
sign_extend(bytestream2_get_le16(&g2), 16);
279 if ((line_packets & 0xC000) == 0xC000) {
281 line_packets = -line_packets;
282 if (line_packets >
s->avctx->height)
284 y_ptr += line_packets *
s->frame->linesize[0];
285 }
else if ((line_packets & 0xC000) == 0x4000) {
287 }
else if ((line_packets & 0xC000) == 0x8000) {
289 pixel_ptr= y_ptr +
s->frame->linesize[0] - 1;
291 pixels[pixel_ptr] = line_packets & 0xff;
296 pixel_countdown =
s->avctx->width;
297 for (
i = 0;
i < line_packets;
i++) {
301 pixel_skip = bytestream2_get_byte(&g2);
302 pixel_ptr += pixel_skip;
303 pixel_countdown -= pixel_skip;
304 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
306 byte_run = -byte_run;
307 palette_idx1 = bytestream2_get_byte(&g2);
308 palette_idx2 = bytestream2_get_byte(&g2);
310 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
311 pixels[pixel_ptr++] = palette_idx1;
312 pixels[pixel_ptr++] = palette_idx2;
318 for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
319 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
324 y_ptr +=
s->frame->linesize[0];
331 starting_line = bytestream2_get_le16(&g2);
332 if (starting_line >=
s->avctx->height)
335 y_ptr += starting_line *
s->frame->linesize[0];
337 compressed_lines = bytestream2_get_le16(&g2);
338 while (compressed_lines > 0) {
341 pixel_countdown =
s->avctx->width;
344 line_packets = bytestream2_get_byte(&g2);
345 if (line_packets > 0) {
346 for (
i = 0;
i < line_packets;
i++) {
350 pixel_skip = bytestream2_get_byte(&g2);
351 pixel_ptr += pixel_skip;
352 pixel_countdown -= pixel_skip;
353 byte_run =
sign_extend(bytestream2_get_byte(&g2),8);
358 for (j = 0; j < byte_run; j++, pixel_countdown--) {
359 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
361 }
else if (byte_run < 0) {
362 byte_run = -byte_run;
363 palette_idx1 = bytestream2_get_byte(&g2);
365 for (j = 0; j < byte_run; j++, pixel_countdown--) {
366 pixels[pixel_ptr++] = palette_idx1;
372 y_ptr +=
s->frame->linesize[0];
380 s->frame->linesize[0] *
s->avctx->height);
387 for (lines = 0; lines <
s->avctx->height; lines++) {
392 pixel_countdown =
s->avctx->width;
393 while (pixel_countdown > 0) {
396 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
403 palette_idx1 = bytestream2_get_byte(&g2);
405 for (j = 0; j < byte_run; j++) {
406 pixels[pixel_ptr++] = palette_idx1;
408 if (pixel_countdown < 0)
410 pixel_countdown, lines);
413 byte_run = -byte_run;
417 for (j = 0; j < byte_run; j++) {
418 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
420 if (pixel_countdown < 0)
422 pixel_countdown, lines);
427 y_ptr +=
s->frame->linesize[0];
433 if (chunk_size - 6 !=
FFALIGN(
s->avctx->width, 4) *
s->avctx->height) {
435 "has incorrect size, skipping chunk\n", chunk_size - 6);
438 for (y_ptr = 0; y_ptr <
s->frame->linesize[0] *
s->avctx->height;
439 y_ptr +=
s->frame->linesize[0]) {
442 if (
s->avctx->width & 3)
472 "and final chunk ptr = %d\n", buf_size,
477 if (
s->new_palette) {
478 s->frame->palette_has_changed = 1;
491 AVFrame *rframe,
int *got_frame,
492 const uint8_t *buf,
int buf_size)
500 unsigned char palette_idx1;
505 unsigned int chunk_size;
511 int compressed_lines;
517 unsigned char *pixels;
519 unsigned int pixel_limit;
526 pixels =
s->frame->data[0];
527 pixel_limit =
s->avctx->height *
s->frame->linesize[0];
531 num_chunks = bytestream2_get_le16(&g2);
541 while ((
frame_size > 0) && (num_chunks > 0) &&
543 int stream_ptr_after_chunk;
544 chunk_size = bytestream2_get_le32(&g2);
547 "Invalid chunk_size = %u > frame_size = %u\n", chunk_size,
frame_size);
552 chunk_type = bytestream2_get_le16(&g2);
555 switch (chunk_type) {
562 "Unexpected Palette chunk %d in non-palettized FLC\n",
570 compressed_lines = bytestream2_get_le16(&g2);
571 while (compressed_lines > 0) {
574 if (y_ptr > pixel_limit)
576 line_packets =
sign_extend(bytestream2_get_le16(&g2), 16);
577 if (line_packets < 0) {
578 line_packets = -line_packets;
579 if (line_packets >
s->avctx->height)
581 y_ptr += line_packets *
s->frame->linesize[0];
586 pixel_countdown =
s->avctx->width;
587 for (
i = 0;
i < line_packets;
i++) {
591 pixel_skip = bytestream2_get_byte(&g2);
592 pixel_ptr += (pixel_skip*2);
593 pixel_countdown -= pixel_skip;
594 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
596 byte_run = -byte_run;
597 pixel = bytestream2_get_le16(&g2);
599 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
600 *((
signed short*)(&pixels[pixel_ptr])) =
pixel;
607 for (j = 0; j < byte_run; j++, pixel_countdown--) {
608 *((
signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
614 y_ptr +=
s->frame->linesize[0];
626 memset(pixels, 0x0000,
627 s->frame->linesize[0] *
s->avctx->height);
632 for (lines = 0; lines <
s->avctx->height; lines++) {
637 pixel_countdown = (
s->avctx->width * 2);
639 while (pixel_countdown > 0) {
642 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
644 palette_idx1 = bytestream2_get_byte(&g2);
646 for (j = 0; j < byte_run; j++) {
647 pixels[pixel_ptr++] = palette_idx1;
649 if (pixel_countdown < 0)
651 pixel_countdown, lines);
654 byte_run = -byte_run;
658 for (j = 0; j < byte_run; j++) {
659 palette_idx1 = bytestream2_get_byte(&g2);
660 pixels[pixel_ptr++] = palette_idx1;
662 if (pixel_countdown < 0)
664 pixel_countdown, lines);
676 pixel_countdown =
s->avctx->width;
677 while (pixel_countdown > 0) {
678 *((
signed short*)(&pixels[pixel_ptr])) =
AV_RL16(&buf[pixel_ptr]);
682 y_ptr +=
s->frame->linesize[0];
688 for (lines = 0; lines <
s->avctx->height; lines++) {
693 pixel_countdown =
s->avctx->width;
695 while (pixel_countdown > 0) {
698 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
700 pixel = bytestream2_get_le16(&g2);
702 for (j = 0; j < byte_run; j++) {
703 *((
signed short*)(&pixels[pixel_ptr])) =
pixel;
706 if (pixel_countdown < 0)
711 byte_run = -byte_run;
715 for (j = 0; j < byte_run; j++) {
716 *((
signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
719 if (pixel_countdown < 0)
726 y_ptr +=
s->frame->linesize[0];
733 if (chunk_size - 6 > (
unsigned int)(
FFALIGN(
s->avctx->width, 2) *
s->avctx->height)*2) {
735 "bigger than image, skipping chunk\n", chunk_size - 6);
741 for (y_ptr = 0; y_ptr <
s->frame->linesize[0] *
s->avctx->height;
742 y_ptr +=
s->frame->linesize[0]) {
744 pixel_countdown =
s->avctx->width;
746 while (pixel_countdown > 0) {
747 *((
signed short*)(&pixels[y_ptr + pixel_ptr])) = bytestream2_get_le16(&g2);
751 if (
s->avctx->width & 1)
793 AVFrame *rframe,
int *got_frame,
794 const uint8_t *buf,
int buf_size)
800 unsigned char palette_idx1;
805 unsigned int chunk_size;
811 int compressed_lines;
817 unsigned char *pixels;
819 unsigned int pixel_limit;
826 pixels =
s->frame->data[0];
827 pixel_limit =
s->avctx->height *
s->frame->linesize[0];
831 num_chunks = bytestream2_get_le16(&g2);
841 while ((
frame_size > 0) && (num_chunks > 0) &&
843 int stream_ptr_after_chunk;
844 chunk_size = bytestream2_get_le32(&g2);
847 "Invalid chunk_size = %u > frame_size = %u\n", chunk_size,
frame_size);
852 chunk_type = bytestream2_get_le16(&g2);
855 switch (chunk_type) {
862 "Unexpected Palette chunk %d in non-palettized FLC\n",
870 compressed_lines = bytestream2_get_le16(&g2);
871 while (compressed_lines > 0) {
874 if (y_ptr > pixel_limit)
876 line_packets =
sign_extend(bytestream2_get_le16(&g2), 16);
877 if (line_packets < 0) {
878 line_packets = -line_packets;
879 if (line_packets >
s->avctx->height)
881 y_ptr += line_packets *
s->frame->linesize[0];
886 pixel_countdown =
s->avctx->width;
887 for (
i = 0;
i < line_packets;
i++) {
891 pixel_skip = bytestream2_get_byte(&g2);
892 pixel_ptr += (pixel_skip*3);
893 pixel_countdown -= pixel_skip;
894 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
896 byte_run = -byte_run;
897 pixel = bytestream2_get_le24(&g2);
899 for (j = 0; j < byte_run; j++, pixel_countdown -= 1) {
907 for (j = 0; j < byte_run; j++, pixel_countdown--) {
908 pixel = bytestream2_get_le24(&g2);
915 y_ptr +=
s->frame->linesize[0];
928 s->frame->linesize[0] *
s->avctx->height);
933 for (lines = 0; lines <
s->avctx->height; lines++) {
938 pixel_countdown = (
s->avctx->width * 3);
940 while (pixel_countdown > 0) {
943 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
945 palette_idx1 = bytestream2_get_byte(&g2);
947 for (j = 0; j < byte_run; j++) {
948 pixels[pixel_ptr++] = palette_idx1;
950 if (pixel_countdown < 0)
952 pixel_countdown, lines);
955 byte_run = -byte_run;
959 for (j = 0; j < byte_run; j++) {
960 palette_idx1 = bytestream2_get_byte(&g2);
961 pixels[pixel_ptr++] = palette_idx1;
963 if (pixel_countdown < 0)
965 pixel_countdown, lines);
970 y_ptr +=
s->frame->linesize[0];
976 for (lines = 0; lines <
s->avctx->height; lines++) {
981 pixel_countdown =
s->avctx->width;
983 while (pixel_countdown > 0) {
986 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
988 pixel = bytestream2_get_le24(&g2);
990 for (j = 0; j < byte_run; j++) {
994 if (pixel_countdown < 0)
999 byte_run = -byte_run;
1003 for (j = 0; j < byte_run; j++) {
1004 pixel = bytestream2_get_le24(&g2);
1008 if (pixel_countdown < 0)
1015 y_ptr +=
s->frame->linesize[0];
1022 if (chunk_size - 6 > (
unsigned int)(
FFALIGN(
s->avctx->width, 2) *
s->avctx->height)*3) {
1024 "bigger than image, skipping chunk\n", chunk_size - 6);
1027 for (y_ptr = 0; y_ptr <
s->frame->linesize[0] *
s->avctx->height;
1028 y_ptr +=
s->frame->linesize[0]) {
1031 if (
s->avctx->width & 1)
1075 const uint8_t *buf = avpkt->
data;
1076 int buf_size = avpkt->
size;
1093 av_log(avctx,
AV_LOG_ERROR,
"Unknown FLC format, my science cannot explain how this happened.\n");