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)
64 ptrdiff_t
limit,
int direction)
66 if (( direction && ptr + n >
limit) ||
67 (!direction && ptr + n <
limit))
72 #define CHECK_PIXEL_PTR(n) \
74 ret = check_pixel_ptr(pixel_ptr, (n), pixel_limit, direction); \
79 #define CHECK_Y_PTR() \
81 ret = check_pixel_ptr(y_ptr, 0, pixel_limit, direction); \
113 if (
s->avctx->extradata_size == 12) {
121 for (
i = 0;
i < 256;
i++) {
134 s->fli_type =
AV_RL16(&fli_header[4]);
135 depth =
AV_RL16(&fli_header[12]);
153 av_log(avctx,
AV_LOG_ERROR,
"Unknown FLC/FLX depth of %d Bpp is unsupported.\n",depth);
167 AVFrame *rframe,
int *got_frame,
168 const uint8_t *buf,
int buf_size)
178 unsigned int chunk_size;
181 int i, j,
ret, direction;
184 int compressed_lines;
191 unsigned char *pixels;
192 ptrdiff_t pixel_limit;
199 direction =
s->frame->linesize[0] > 0;
200 pixels =
s->frame->data[0];
201 pixel_limit =
s->avctx->height *
s->frame->linesize[0];
208 num_chunks = bytestream2_get_le16(&g2);
217 while ((
frame_size >= 6) && (num_chunks > 0) &&
219 int stream_ptr_after_chunk;
220 chunk_size = bytestream2_get_le32(&g2);
223 "Invalid chunk_size = %u > frame_size = %u\n", chunk_size,
frame_size);
228 chunk_type = bytestream2_get_le16(&g2);
230 switch (chunk_type) {
235 for (lines = 0; lines <
s->avctx->height; lines++) {
240 pixel_countdown = (
s->avctx->width + 7) >> 3;
241 while (pixel_countdown > 0) {
244 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
251 int value = bytestream2_get_byte(&g2);
253 for (j = 0; j < byte_run; j++) {
254 pixels[pixel_ptr++] =
value;
256 if (pixel_countdown < 0)
258 pixel_countdown, lines);
261 byte_run = -byte_run;
265 for (j = 0; j < byte_run; j++) {
266 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
268 if (pixel_countdown < 0)
270 pixel_countdown, lines);
275 y_ptr +=
s->frame->linesize[0];
281 starting_line = bytestream2_get_le16(&g2);
282 if (starting_line >=
s->avctx->height)
285 y_ptr += starting_line *
s->frame->linesize[0];
287 compressed_lines = bytestream2_get_le16(&g2);
288 while (compressed_lines > 0) {
291 pixel_countdown = (
s->avctx->width + 7) >> 3;
294 line_packets = bytestream2_get_byte(&g2);
295 if (line_packets > 0) {
296 for (
i = 0;
i < line_packets;
i++) {
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);
308 for (j = 0; j < byte_run; j++, pixel_countdown--) {
309 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
311 }
else if (byte_run < 0) {
312 int value = bytestream2_get_byte(&g2);
313 byte_run = -byte_run;
315 for (j = 0; j < byte_run; j++, pixel_countdown--) {
316 pixels[pixel_ptr++] =
value;
322 y_ptr +=
s->frame->linesize[0];
347 "and final chunk ptr = %d\n", buf_size,
359 AVFrame *rframe,
int *got_frame,
360 const uint8_t *buf,
int buf_size)
367 unsigned char palette_idx1;
368 unsigned char palette_idx2;
373 unsigned int chunk_size;
376 int i, j,
ret, direction;
381 unsigned char r,
g,
b;
384 int compressed_lines;
391 unsigned char *pixels;
392 ptrdiff_t pixel_limit;
399 direction =
s->frame->linesize[0] > 0;
400 pixels =
s->frame->data[0];
401 pixel_limit =
s->avctx->height *
s->frame->linesize[0];
408 num_chunks = bytestream2_get_le16(&g2);
417 while ((
frame_size >= 6) && (num_chunks > 0) &&
419 int stream_ptr_after_chunk;
420 chunk_size = bytestream2_get_le32(&g2);
423 "Invalid chunk_size = %u > frame_size = %u\n", chunk_size,
frame_size);
428 chunk_type = bytestream2_get_le16(&g2);
430 switch (chunk_type) {
442 color_packets = bytestream2_get_le16(&g2);
444 for (
i = 0;
i < color_packets;
i++) {
446 palette_ptr += bytestream2_get_byte(&g2);
449 color_changes = bytestream2_get_byte(&g2);
452 if (color_changes == 0)
458 for (j = 0; j < color_changes; j++) {
462 if ((
unsigned)palette_ptr >= 256)
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 = 0xFF
U << 24 |
r << 16 |
g << 8 |
b;
469 if (color_shift == 2)
471 if (
s->palette[palette_ptr] !=
entry)
473 s->palette[palette_ptr++] =
entry;
480 compressed_lines = bytestream2_get_le16(&g2);
481 while (compressed_lines > 0) {
485 line_packets =
sign_extend(bytestream2_get_le16(&g2), 16);
486 if ((line_packets & 0xC000) == 0xC000) {
488 line_packets = -line_packets;
489 if (line_packets >
s->avctx->height)
491 y_ptr += line_packets *
s->frame->linesize[0];
492 }
else if ((line_packets & 0xC000) == 0x4000) {
494 }
else if ((line_packets & 0xC000) == 0x8000) {
496 pixel_ptr= y_ptr +
s->frame->linesize[0] - 1;
498 pixels[pixel_ptr] = line_packets & 0xff;
503 pixel_countdown =
s->avctx->width;
504 for (
i = 0;
i < line_packets;
i++) {
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);
513 byte_run = -byte_run;
514 palette_idx1 = bytestream2_get_byte(&g2);
515 palette_idx2 = bytestream2_get_byte(&g2);
517 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
518 pixels[pixel_ptr++] = palette_idx1;
519 pixels[pixel_ptr++] = palette_idx2;
525 for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
526 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
531 y_ptr +=
s->frame->linesize[0];
538 starting_line = bytestream2_get_le16(&g2);
539 if (starting_line >=
s->avctx->height)
542 y_ptr += starting_line *
s->frame->linesize[0];
544 compressed_lines = bytestream2_get_le16(&g2);
545 while (compressed_lines > 0) {
548 pixel_countdown =
s->avctx->width;
551 line_packets = bytestream2_get_byte(&g2);
552 if (line_packets > 0) {
553 for (
i = 0;
i < line_packets;
i++) {
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);
565 for (j = 0; j < byte_run; j++, pixel_countdown--) {
566 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
568 }
else if (byte_run < 0) {
569 byte_run = -byte_run;
570 palette_idx1 = bytestream2_get_byte(&g2);
572 for (j = 0; j < byte_run; j++, pixel_countdown--) {
573 pixels[pixel_ptr++] = palette_idx1;
579 y_ptr +=
s->frame->linesize[0];
586 for (
int y = 0; y <
s->avctx->height; y++)
587 memset(pixels + y *
s->frame->linesize[0], 0,
s->avctx->width);
594 for (lines = 0; lines <
s->avctx->height; lines++) {
599 pixel_countdown =
s->avctx->width;
600 while (pixel_countdown > 0) {
603 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
610 palette_idx1 = bytestream2_get_byte(&g2);
612 for (j = 0; j < byte_run; j++) {
613 pixels[pixel_ptr++] = palette_idx1;
615 if (pixel_countdown < 0)
617 pixel_countdown, lines);
620 byte_run = -byte_run;
624 for (j = 0; j < byte_run; j++) {
625 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
627 if (pixel_countdown < 0)
629 pixel_countdown, lines);
634 y_ptr +=
s->frame->linesize[0];
640 if (chunk_size - 6 !=
FFALIGN(
s->avctx->width, 4) *
s->avctx->height) {
642 "has incorrect size, skipping chunk\n", chunk_size - 6);
645 for (y_ptr = 0;
check_pixel_ptr(y_ptr,
s->avctx->width, pixel_limit, direction) == 0;
646 y_ptr +=
s->frame->linesize[0]) {
649 if (
s->avctx->width & 3)
679 "and final chunk ptr = %d\n", buf_size,
684 if (
s->new_palette) {
685 #if FF_API_PALETTE_HAS_CHANGED
687 s->frame->palette_has_changed = 1;
702 AVFrame *rframe,
int *got_frame,
703 const uint8_t *buf,
int buf_size)
711 unsigned char palette_idx1;
716 unsigned int chunk_size;
719 int i, j,
ret, direction;
722 int compressed_lines;
728 unsigned char *pixels;
730 ptrdiff_t pixel_limit;
737 direction =
s->frame->linesize[0] > 0;
738 pixels =
s->frame->data[0];
739 pixel_limit =
s->avctx->height *
s->frame->linesize[0];
743 num_chunks = bytestream2_get_le16(&g2);
753 while ((
frame_size > 0) && (num_chunks > 0) &&
755 int stream_ptr_after_chunk;
756 chunk_size = bytestream2_get_le32(&g2);
759 "Invalid chunk_size = %u > frame_size = %u\n", chunk_size,
frame_size);
764 chunk_type = bytestream2_get_le16(&g2);
767 switch (chunk_type) {
774 "Unexpected Palette chunk %d in non-palettized FLC\n",
782 compressed_lines = bytestream2_get_le16(&g2);
783 while (compressed_lines > 0) {
787 line_packets =
sign_extend(bytestream2_get_le16(&g2), 16);
788 if (line_packets < 0) {
789 line_packets = -line_packets;
790 if (line_packets >
s->avctx->height)
792 y_ptr += line_packets *
s->frame->linesize[0];
797 pixel_countdown =
s->avctx->width;
798 for (
i = 0;
i < line_packets;
i++) {
802 pixel_skip = bytestream2_get_byte(&g2);
803 pixel_ptr += (pixel_skip*2);
804 pixel_countdown -= pixel_skip;
805 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
807 byte_run = -byte_run;
808 pixel = bytestream2_get_le16(&g2);
810 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
811 *((
signed short*)(&pixels[pixel_ptr])) =
pixel;
818 for (j = 0; j < byte_run; j++, pixel_countdown--) {
819 *((
signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
825 y_ptr +=
s->frame->linesize[0];
837 for (
int y = 0; y <
s->avctx->height; y++)
838 memset(pixels + y *
s->frame->linesize[0], 0,
s->avctx->width * 2);
843 for (lines = 0; lines <
s->avctx->height; lines++) {
848 pixel_countdown = (
s->avctx->width * 2);
850 while (pixel_countdown > 0) {
853 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
855 palette_idx1 = bytestream2_get_byte(&g2);
857 for (j = 0; j < byte_run; j++) {
858 pixels[pixel_ptr++] = palette_idx1;
860 if (pixel_countdown < 0)
862 pixel_countdown, lines);
865 byte_run = -byte_run;
869 for (j = 0; j < byte_run; j++) {
870 palette_idx1 = bytestream2_get_byte(&g2);
871 pixels[pixel_ptr++] = palette_idx1;
873 if (pixel_countdown < 0)
875 pixel_countdown, lines);
887 pixel_countdown =
s->avctx->width;
888 while (pixel_countdown > 0) {
889 *((
signed short*)(&pixels[pixel_ptr])) =
AV_RL16(&buf[pixel_ptr]);
893 y_ptr +=
s->frame->linesize[0];
899 for (lines = 0; lines <
s->avctx->height; lines++) {
904 pixel_countdown =
s->avctx->width;
906 while (pixel_countdown > 0) {
909 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
911 pixel = bytestream2_get_le16(&g2);
913 for (j = 0; j < byte_run; j++) {
914 *((
signed short*)(&pixels[pixel_ptr])) =
pixel;
917 if (pixel_countdown < 0)
922 byte_run = -byte_run;
926 for (j = 0; j < byte_run; j++) {
927 *((
signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
930 if (pixel_countdown < 0)
937 y_ptr +=
s->frame->linesize[0];
944 if (chunk_size - 6 > (
unsigned int)(
FFALIGN(
s->avctx->width, 2) *
s->avctx->height)*2) {
946 "bigger than image, skipping chunk\n", chunk_size - 6);
952 for (y_ptr = 0;
check_pixel_ptr(y_ptr, 2*
s->avctx->width, pixel_limit, direction) == 0;
953 y_ptr +=
s->frame->linesize[0]) {
955 pixel_countdown =
s->avctx->width;
957 while (pixel_countdown > 0) {
958 *((
signed short*)(&pixels[y_ptr + pixel_ptr])) = bytestream2_get_le16(&g2);
962 if (
s->avctx->width & 1)
1004 AVFrame *rframe,
int *got_frame,
1005 const uint8_t *buf,
int buf_size)
1010 ptrdiff_t pixel_ptr;
1011 unsigned char palette_idx1;
1016 unsigned int chunk_size;
1019 int i, j,
ret, direction;
1022 int compressed_lines;
1027 int pixel_countdown;
1028 unsigned char *pixels;
1030 ptrdiff_t pixel_limit;
1037 direction =
s->frame->linesize[0] > 0;
1038 pixels =
s->frame->data[0];
1039 pixel_limit =
s->avctx->height *
s->frame->linesize[0];
1043 num_chunks = bytestream2_get_le16(&g2);
1053 while ((
frame_size > 0) && (num_chunks > 0) &&
1055 int stream_ptr_after_chunk;
1056 chunk_size = bytestream2_get_le32(&g2);
1059 "Invalid chunk_size = %u > frame_size = %u\n", chunk_size,
frame_size);
1064 chunk_type = bytestream2_get_le16(&g2);
1067 switch (chunk_type) {
1074 "Unexpected Palette chunk %d in non-palettized FLC\n",
1082 compressed_lines = bytestream2_get_le16(&g2);
1083 while (compressed_lines > 0) {
1087 line_packets =
sign_extend(bytestream2_get_le16(&g2), 16);
1088 if (line_packets < 0) {
1089 line_packets = -line_packets;
1090 if (line_packets >
s->avctx->height)
1092 y_ptr += line_packets *
s->frame->linesize[0];
1097 pixel_countdown =
s->avctx->width;
1098 for (
i = 0;
i < line_packets;
i++) {
1102 pixel_skip = bytestream2_get_byte(&g2);
1103 pixel_ptr += (pixel_skip*3);
1104 pixel_countdown -= pixel_skip;
1105 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
1107 byte_run = -byte_run;
1108 pixel = bytestream2_get_le24(&g2);
1110 for (j = 0; j < byte_run; j++, pixel_countdown -= 1) {
1118 for (j = 0; j < byte_run; j++, pixel_countdown--) {
1119 pixel = bytestream2_get_le24(&g2);
1126 y_ptr +=
s->frame->linesize[0];
1138 for (
int y = 0; y <
s->avctx->height; y++)
1139 memset(pixels + y *
s->frame->linesize[0], 0,
s->avctx->width * 3);
1144 for (lines = 0; lines <
s->avctx->height; lines++) {
1149 pixel_countdown = (
s->avctx->width * 3);
1151 while (pixel_countdown > 0) {
1154 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
1156 palette_idx1 = bytestream2_get_byte(&g2);
1158 for (j = 0; j < byte_run; j++) {
1159 pixels[pixel_ptr++] = palette_idx1;
1161 if (pixel_countdown < 0)
1163 pixel_countdown, lines);
1166 byte_run = -byte_run;
1170 for (j = 0; j < byte_run; j++) {
1171 palette_idx1 = bytestream2_get_byte(&g2);
1172 pixels[pixel_ptr++] = palette_idx1;
1174 if (pixel_countdown < 0)
1176 pixel_countdown, lines);
1181 y_ptr +=
s->frame->linesize[0];
1187 for (lines = 0; lines <
s->avctx->height; lines++) {
1192 pixel_countdown =
s->avctx->width;
1194 while (pixel_countdown > 0) {
1197 byte_run =
sign_extend(bytestream2_get_byte(&g2), 8);
1199 pixel = bytestream2_get_le24(&g2);
1201 for (j = 0; j < byte_run; j++) {
1205 if (pixel_countdown < 0)
1210 byte_run = -byte_run;
1214 for (j = 0; j < byte_run; j++) {
1215 pixel = bytestream2_get_le24(&g2);
1219 if (pixel_countdown < 0)
1226 y_ptr +=
s->frame->linesize[0];
1233 if (chunk_size - 6 > (
unsigned int)(
FFALIGN(
s->avctx->width, 2) *
s->avctx->height)*3) {
1235 "bigger than image, skipping chunk\n", chunk_size - 6);
1238 for (y_ptr = 0;
check_pixel_ptr(y_ptr, 3*
s->avctx->width, pixel_limit, direction) == 0;
1239 y_ptr +=
s->frame->linesize[0]) {
1242 if (
s->avctx->width & 1)
1286 const uint8_t *buf = avpkt->
data;
1287 int buf_size = avpkt->
size;
1307 av_log(avctx,
AV_LOG_ERROR,
"Unknown FLC format, my science cannot explain how this happened.\n");