81
83
unsigned char *fli_header = (unsigned char *)avctx->extradata;
86
if (avctx->extradata_size != 12 &&
87
avctx->extradata_size != 128) {
88
av_log(avctx, AV_LOG_ERROR, "Expected extradata of 12 or 128 bytes\n");
89
return AVERROR_INVALIDDATA;
86
94
s->fli_type = AV_RL16(&fli_header[4]); /* Might be overridden if a Magic Carpet FLC */
90
98
/* special case for magic carpet FLIs */
91
99
s->fli_type = FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE;
93
} else if (s->avctx->extradata_size != 128) {
94
av_log(avctx, AV_LOG_ERROR, "Expected extradata of 12 or 128 bytes\n");
97
102
depth = AV_RL16(&fli_header[12]);
112
117
case 24 : avctx->pix_fmt = PIX_FMT_BGR24; /* Supposedly BGR, but havent any files to test with */
113
118
av_log(avctx, AV_LOG_ERROR, "24Bpp FLC/FLX is unsupported due to no test files.\n");
117
121
av_log(avctx, AV_LOG_ERROR, "Unknown FLC/FLX depth of %d Bpp is unsupported.\n",depth);
161
165
unsigned char *pixels;
162
166
unsigned int pixel_limit;
168
bytestream2_init(&g2, buf, buf_size);
164
170
s->frame.reference = 1;
165
171
s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
166
172
if (avctx->reget_buffer(avctx, &s->frame) < 0) {
171
177
pixels = s->frame.data[0];
172
178
pixel_limit = s->avctx->height * s->frame.linesize[0];
174
frame_size = AV_RL32(&buf[stream_ptr]);
175
stream_ptr += 6; /* skip the magic number */
176
num_chunks = AV_RL16(&buf[stream_ptr]);
177
stream_ptr += 10; /* skip padding */
179
frame_size = bytestream2_get_le32(&g2);
180
bytestream2_skip(&g2, 2); /* skip the magic number */
181
num_chunks = bytestream2_get_le16(&g2);
182
bytestream2_skip(&g2, 8); /* skip padding */
179
184
frame_size -= 16;
181
186
/* iterate through the chunks */
182
187
while ((frame_size > 0) && (num_chunks > 0)) {
183
chunk_size = AV_RL32(&buf[stream_ptr]);
185
chunk_type = AV_RL16(&buf[stream_ptr]);
188
chunk_size = bytestream2_get_le32(&g2);
189
chunk_type = bytestream2_get_le16(&g2);
188
191
switch (chunk_type) {
189
192
case FLI_256_COLOR:
191
stream_ptr_after_color_chunk = stream_ptr + chunk_size - 6;
194
stream_ptr_after_color_chunk = bytestream2_tell(&g2) + chunk_size - 6;
193
196
/* check special case: If this file is from the Magic Carpet
194
197
* game and uses 6-bit colors even though it reports 256-color
201
204
/* set up the palette */
202
color_packets = AV_RL16(&buf[stream_ptr]);
205
color_packets = bytestream2_get_le16(&g2);
205
207
for (i = 0; i < color_packets; i++) {
206
208
/* first byte is how many colors to skip */
207
palette_ptr += buf[stream_ptr++];
209
palette_ptr += bytestream2_get_byte(&g2);
209
211
/* next byte indicates how many entries to change */
210
color_changes = buf[stream_ptr++];
212
color_changes = bytestream2_get_byte(&g2);
212
214
/* if there are 0 color changes, there are actually 256 */
213
215
if (color_changes == 0)
220
222
if ((unsigned)palette_ptr >= 256)
223
r = buf[stream_ptr++] << color_shift;
224
g = buf[stream_ptr++] << color_shift;
225
b = buf[stream_ptr++] << color_shift;
225
r = bytestream2_get_byte(&g2) << color_shift;
226
g = bytestream2_get_byte(&g2) << color_shift;
227
b = bytestream2_get_byte(&g2) << color_shift;
226
228
entry = (r << 16) | (g << 8) | b;
227
229
if (s->palette[palette_ptr] != entry)
228
230
s->new_palette = 1;
233
235
/* color chunks sometimes have weird 16-bit alignment issues;
234
* therefore, take the hardline approach and set the stream_ptr
236
* therefore, take the hardline approach and skip
235
237
* to the value calculated w.r.t. the size specified by the color
236
238
* chunk header */
237
stream_ptr = stream_ptr_after_color_chunk;
239
if (stream_ptr_after_color_chunk - bytestream2_tell(&g2) > 0)
240
bytestream2_skip(&g2, stream_ptr_after_color_chunk - bytestream2_tell(&g2));
243
compressed_lines = AV_RL16(&buf[stream_ptr]);
246
compressed_lines = bytestream2_get_le16(&g2);
245
247
while (compressed_lines > 0) {
246
line_packets = AV_RL16(&buf[stream_ptr]);
248
line_packets = bytestream2_get_le16(&g2);
248
249
if ((line_packets & 0xC000) == 0xC000) {
249
250
// line skip opcode
250
251
line_packets = -line_packets;
263
264
pixel_countdown = s->avctx->width;
264
265
for (i = 0; i < line_packets; i++) {
265
266
/* account for the skip bytes */
266
pixel_skip = buf[stream_ptr++];
267
pixel_skip = bytestream2_get_byte(&g2);
267
268
pixel_ptr += pixel_skip;
268
269
pixel_countdown -= pixel_skip;
269
byte_run = (signed char)(buf[stream_ptr++]);
270
byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
270
271
if (byte_run < 0) {
271
272
byte_run = -byte_run;
272
palette_idx1 = buf[stream_ptr++];
273
palette_idx2 = buf[stream_ptr++];
273
palette_idx1 = bytestream2_get_byte(&g2);
274
palette_idx2 = bytestream2_get_byte(&g2);
274
275
CHECK_PIXEL_PTR(byte_run * 2);
275
276
for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
276
277
pixels[pixel_ptr++] = palette_idx1;
280
281
CHECK_PIXEL_PTR(byte_run * 2);
281
282
for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
282
palette_idx1 = buf[stream_ptr++];
283
pixels[pixel_ptr++] = palette_idx1;
283
pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
294
294
/* line compressed */
295
starting_line = AV_RL16(&buf[stream_ptr]);
295
starting_line = bytestream2_get_le16(&g2);
298
297
y_ptr += starting_line * s->frame.linesize[0];
300
compressed_lines = AV_RL16(&buf[stream_ptr]);
299
compressed_lines = bytestream2_get_le16(&g2);
302
300
while (compressed_lines > 0) {
303
301
pixel_ptr = y_ptr;
304
302
CHECK_PIXEL_PTR(0);
305
303
pixel_countdown = s->avctx->width;
306
line_packets = buf[stream_ptr++];
304
line_packets = bytestream2_get_byte(&g2);
307
305
if (line_packets > 0) {
308
306
for (i = 0; i < line_packets; i++) {
309
307
/* account for the skip bytes */
310
pixel_skip = buf[stream_ptr++];
308
pixel_skip = bytestream2_get_byte(&g2);
311
309
pixel_ptr += pixel_skip;
312
310
pixel_countdown -= pixel_skip;
313
byte_run = (signed char)(buf[stream_ptr++]);
311
byte_run = sign_extend(bytestream2_get_byte(&g2),8);
314
312
if (byte_run > 0) {
315
313
CHECK_PIXEL_PTR(byte_run);
316
314
for (j = 0; j < byte_run; j++, pixel_countdown--) {
317
palette_idx1 = buf[stream_ptr++];
318
pixels[pixel_ptr++] = palette_idx1;
315
pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
320
317
} else if (byte_run < 0) {
321
318
byte_run = -byte_run;
322
palette_idx1 = buf[stream_ptr++];
319
palette_idx1 = bytestream2_get_byte(&g2);
323
320
CHECK_PIXEL_PTR(byte_run);
324
321
for (j = 0; j < byte_run; j++, pixel_countdown--) {
325
322
pixels[pixel_ptr++] = palette_idx1;
347
344
pixel_ptr = y_ptr;
348
345
/* disregard the line packets; instead, iterate through all
349
346
* pixels on a row */
347
bytestream2_skip(&g2, 1);
351
348
pixel_countdown = s->avctx->width;
352
349
while (pixel_countdown > 0) {
353
byte_run = (signed char)(buf[stream_ptr++]);
350
byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
354
351
if (byte_run > 0) {
355
palette_idx1 = buf[stream_ptr++];
352
palette_idx1 = bytestream2_get_byte(&g2);
356
353
CHECK_PIXEL_PTR(byte_run);
357
354
for (j = 0; j < byte_run; j++) {
358
355
pixels[pixel_ptr++] = palette_idx1;
365
362
byte_run = -byte_run;
366
363
CHECK_PIXEL_PTR(byte_run);
367
364
for (j = 0; j < byte_run; j++) {
368
palette_idx1 = buf[stream_ptr++];
369
pixels[pixel_ptr++] = palette_idx1;
365
pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
370
366
pixel_countdown--;
371
367
if (pixel_countdown < 0)
372
368
av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
384
380
if (chunk_size - 6 > s->avctx->width * s->avctx->height) {
385
381
av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
386
382
"bigger than image, skipping chunk\n", chunk_size - 6);
387
stream_ptr += chunk_size - 6;
383
bytestream2_skip(&g2, chunk_size - 6);
389
385
for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
390
386
y_ptr += s->frame.linesize[0]) {
391
memcpy(&pixels[y_ptr], &buf[stream_ptr],
393
stream_ptr += s->avctx->width;
387
bytestream2_get_buffer(&g2, &pixels[y_ptr],
399
394
/* some sort of a thumbnail? disregard this chunk... */
400
stream_ptr += chunk_size - 6;
395
bytestream2_skip(&g2, chunk_size - 6);
412
407
/* by the end of the chunk, the stream ptr should equal the frame
413
408
* size (minus 1, possibly); if it doesn't, issue a warning */
414
if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1))
409
if ((bytestream2_get_bytes_left(&g2) != 0) &&
410
(bytestream2_get_bytes_left(&g2) != 1))
415
411
av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
416
"and final chunk ptr = %d\n", buf_size, stream_ptr);
412
"and final chunk ptr = %d\n", buf_size,
413
buf_size - bytestream2_get_bytes_left(&g2));
418
415
/* make the palette available on the way out */
419
416
memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
460
457
unsigned int pixel_limit;
459
bytestream2_init(&g2, buf, buf_size);
462
461
s->frame.reference = 1;
463
462
s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
464
463
if (avctx->reget_buffer(avctx, &s->frame) < 0) {
469
468
pixels = s->frame.data[0];
470
469
pixel_limit = s->avctx->height * s->frame.linesize[0];
472
frame_size = AV_RL32(&buf[stream_ptr]);
473
stream_ptr += 6; /* skip the magic number */
474
num_chunks = AV_RL16(&buf[stream_ptr]);
475
stream_ptr += 10; /* skip padding */
471
frame_size = bytestream2_get_le32(&g2);
472
bytestream2_skip(&g2, 2); /* skip the magic number */
473
num_chunks = bytestream2_get_le16(&g2);
474
bytestream2_skip(&g2, 8); /* skip padding */
477
476
frame_size -= 16;
479
478
/* iterate through the chunks */
480
479
while ((frame_size > 0) && (num_chunks > 0)) {
481
chunk_size = AV_RL32(&buf[stream_ptr]);
483
chunk_type = AV_RL16(&buf[stream_ptr]);
480
chunk_size = bytestream2_get_le32(&g2);
481
chunk_type = bytestream2_get_le16(&g2);
486
483
switch (chunk_type) {
487
484
case FLI_256_COLOR:
490
487
* include one of these chunks in their first frame.
491
488
* Why I do not know, it seems rather extraneous. */
492
489
/* av_log(avctx, AV_LOG_ERROR, "Unexpected Palette chunk %d in non-paletised FLC\n",chunk_type);*/
493
stream_ptr = stream_ptr + chunk_size - 6;
490
bytestream2_skip(&g2, chunk_size - 6);
499
compressed_lines = AV_RL16(&buf[stream_ptr]);
496
compressed_lines = bytestream2_get_le16(&g2);
501
497
while (compressed_lines > 0) {
502
line_packets = AV_RL16(&buf[stream_ptr]);
498
line_packets = bytestream2_get_le16(&g2);
504
499
if (line_packets < 0) {
505
500
line_packets = -line_packets;
506
501
y_ptr += line_packets * s->frame.linesize[0];
511
506
pixel_countdown = s->avctx->width;
512
507
for (i = 0; i < line_packets; i++) {
513
508
/* account for the skip bytes */
514
pixel_skip = buf[stream_ptr++];
509
pixel_skip = bytestream2_get_byte(&g2);
515
510
pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */
516
511
pixel_countdown -= pixel_skip;
517
byte_run = (signed char)(buf[stream_ptr++]);
512
byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
518
513
if (byte_run < 0) {
519
514
byte_run = -byte_run;
520
pixel = AV_RL16(&buf[stream_ptr]);
515
pixel = bytestream2_get_le16(&g2);
522
516
CHECK_PIXEL_PTR(2 * byte_run);
523
517
for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
524
518
*((signed short*)(&pixels[pixel_ptr])) = pixel;
528
522
CHECK_PIXEL_PTR(2 * byte_run);
529
523
for (j = 0; j < byte_run; j++, pixel_countdown--) {
530
*((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[stream_ptr]);
524
*((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
543
536
av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-paletised FLC\n");
544
stream_ptr = stream_ptr + chunk_size - 6;
537
bytestream2_skip(&g2, chunk_size - 6);
556
549
pixel_ptr = y_ptr;
557
550
/* disregard the line packets; instead, iterate through all
558
551
* pixels on a row */
552
bytestream2_skip(&g2, 1);
560
553
pixel_countdown = (s->avctx->width * 2);
562
555
while (pixel_countdown > 0) {
563
byte_run = (signed char)(buf[stream_ptr++]);
556
byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
564
557
if (byte_run > 0) {
565
palette_idx1 = buf[stream_ptr++];
558
palette_idx1 = bytestream2_get_byte(&g2);
566
559
CHECK_PIXEL_PTR(byte_run);
567
560
for (j = 0; j < byte_run; j++) {
568
561
pixels[pixel_ptr++] = palette_idx1;
575
568
byte_run = -byte_run;
576
569
CHECK_PIXEL_PTR(byte_run);
577
570
for (j = 0; j < byte_run; j++) {
578
palette_idx1 = buf[stream_ptr++];
571
palette_idx1 = bytestream2_get_byte(&g2);
579
572
pixels[pixel_ptr++] = palette_idx1;
580
573
pixel_countdown--;
581
574
if (pixel_countdown < 0)
608
601
pixel_ptr = y_ptr;
609
602
/* disregard the line packets; instead, iterate through all
610
603
* pixels on a row */
604
bytestream2_skip(&g2, 1);
612
605
pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */
614
607
while (pixel_countdown > 0) {
615
byte_run = (signed char)(buf[stream_ptr++]);
608
byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
616
609
if (byte_run > 0) {
617
pixel = AV_RL16(&buf[stream_ptr]);
610
pixel = bytestream2_get_le16(&g2);
619
611
CHECK_PIXEL_PTR(2 * byte_run);
620
612
for (j = 0; j < byte_run; j++) {
621
613
*((signed short*)(&pixels[pixel_ptr])) = pixel;
650
641
if (chunk_size - 6 > (unsigned int)(s->avctx->width * s->avctx->height)*2) {
651
642
av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
652
643
"bigger than image, skipping chunk\n", chunk_size - 6);
653
stream_ptr += chunk_size - 6;
644
bytestream2_skip(&g2, chunk_size - 6);
656
647
for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
659
650
pixel_countdown = s->avctx->width;
661
652
while (pixel_countdown > 0) {
662
*((signed short*)(&pixels[y_ptr + pixel_ptr])) = AV_RL16(&buf[stream_ptr+pixel_ptr]);
653
*((signed short*)(&pixels[y_ptr + pixel_ptr])) = bytestream2_get_le16(&g2);
664
655
pixel_countdown--;
666
stream_ptr += s->avctx->width*2;
672
662
/* some sort of a thumbnail? disregard this chunk... */
673
stream_ptr += chunk_size - 6;
663
bytestream2_skip(&g2, chunk_size - 6);
685
675
/* by the end of the chunk, the stream ptr should equal the frame
686
676
* size (minus 1, possibly); if it doesn't, issue a warning */
687
if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1))
677
if ((bytestream2_get_bytes_left(&g2) != 0) && (bytestream2_get_bytes_left(&g2) != 1))
688
678
av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
689
"and final chunk ptr = %d\n", buf_size, stream_ptr);
679
"and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2));
692
682
*data_size=sizeof(AVFrame);
745
735
AVCodec ff_flic_decoder = {
749
sizeof(FlicDecodeContext),
737
.type = AVMEDIA_TYPE_VIDEO,
739
.priv_data_size = sizeof(FlicDecodeContext),
740
.init = flic_decode_init,
741
.close = flic_decode_end,
742
.decode = flic_decode_frame,
743
.capabilities = CODEC_CAP_DR1,
759
744
.long_name = NULL_IF_CONFIG_SMALL("Autodesk Animator Flic video"),