1/* 2 * FLI/FLC Animation Video Decoder 3 * Copyright (C) 2003, 2004 the ffmpeg project 4 * 5 * This file is part of Libav. 6 * 7 * Libav 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 * Libav 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 Libav; 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 and maybe one day RGB24 31 * colorspace data, depending on the FLC. To use this decoder, be 32 * sure that your demuxer sends the FLI file header to the decoder via 33 * the extradata chunk in AVCodecContext. The chunk should be 128 bytes 34 * large. The only exception is for FLI files from the game "Magic Carpet", 35 * in which the header is only 12 bytes. 36 */ 37 38#include <stdio.h> 39#include <stdlib.h> 40#include <string.h> 41 42#include "libavutil/intreadwrite.h" 43#include "avcodec.h" 44#include "bytestream.h" 45#include "mathops.h" 46 47#define FLI_256_COLOR 4 48#define FLI_DELTA 7 49#define FLI_COLOR 11 50#define FLI_LC 12 51#define FLI_BLACK 13 52#define FLI_BRUN 15 53#define FLI_COPY 16 54#define FLI_MINI 18 55#define FLI_DTA_BRUN 25 56#define FLI_DTA_COPY 26 57#define FLI_DTA_LC 27 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_INFO, "Problem: pixel_ptr >= pixel_limit (%d >= %d)\n", \ 67 pixel_ptr + n, pixel_limit); \ 68 return -1; \ 69 } \ 70 71typedef struct FlicDecodeContext { 72 AVCodecContext *avctx; 73 AVFrame frame; 74 75 unsigned int palette[256]; 76 int new_palette; 77 int fli_type; /* either 0xAF11 or 0xAF12, affects palette resolution */ 78} FlicDecodeContext; 79 80static av_cold int flic_decode_init(AVCodecContext *avctx) 81{ 82 FlicDecodeContext *s = avctx->priv_data; 83 unsigned char *fli_header = (unsigned char *)avctx->extradata; 84 int depth; 85 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; 90 } 91 92 s->avctx = avctx; 93 94 s->fli_type = AV_RL16(&fli_header[4]); /* Might be overridden if a Magic Carpet FLC */ 95 96 depth = 0; 97 if (s->avctx->extradata_size == 12) { 98 /* special case for magic carpet FLIs */ 99 s->fli_type = FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE; 100 depth = 8; 101 } else { 102 depth = AV_RL16(&fli_header[12]); 103 } 104 105 if (depth == 0) { 106 depth = 8; /* Some FLC generators set depth to zero, when they mean 8Bpp. Fix up here */ 107 } 108 109 if ((s->fli_type == FLC_FLX_TYPE_CODE) && (depth == 16)) { 110 depth = 15; /* Original Autodesk FLX's say the depth is 16Bpp when it is really 15Bpp */ 111 } 112 113 switch (depth) { 114 case 8 : avctx->pix_fmt = PIX_FMT_PAL8; break; 115 case 15 : avctx->pix_fmt = PIX_FMT_RGB555; break; 116 case 16 : avctx->pix_fmt = PIX_FMT_RGB565; break; 117 case 24 : avctx->pix_fmt = PIX_FMT_BGR24; /* Supposedly BGR, but havent any files to test with */ 118 av_log(avctx, AV_LOG_ERROR, "24Bpp FLC/FLX is unsupported due to no test files.\n"); 119 return -1; 120 default : 121 av_log(avctx, AV_LOG_ERROR, "Unknown FLC/FLX depth of %d Bpp is unsupported.\n",depth); 122 return -1; 123 } 124 125 s->frame.data[0] = NULL; 126 s->new_palette = 0; 127 128 return 0; 129} 130 131static int flic_decode_frame_8BPP(AVCodecContext *avctx, 132 void *data, int *data_size, 133 const uint8_t *buf, int buf_size) 134{ 135 FlicDecodeContext *s = avctx->priv_data; 136 137 GetByteContext g2; 138 int stream_ptr_after_color_chunk; 139 int pixel_ptr; 140 int palette_ptr; 141 unsigned char palette_idx1; 142 unsigned char palette_idx2; 143 144 unsigned int frame_size; 145 int num_chunks; 146 147 unsigned int chunk_size; 148 int chunk_type; 149 150 int i, j; 151 152 int color_packets; 153 int color_changes; 154 int color_shift; 155 unsigned char r, g, b; 156 157 int lines; 158 int compressed_lines; 159 int starting_line; 160 signed short line_packets; 161 int y_ptr; 162 int byte_run; 163 int pixel_skip; 164 int pixel_countdown; 165 unsigned char *pixels; 166 unsigned int pixel_limit; 167 168 bytestream2_init(&g2, buf, buf_size); 169 170 s->frame.reference = 1; 171 s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; 172 if (avctx->reget_buffer(avctx, &s->frame) < 0) { 173 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); 174 return -1; 175 } 176 177 pixels = s->frame.data[0]; 178 pixel_limit = s->avctx->height * s->frame.linesize[0]; 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 */ 183 184 frame_size -= 16; 185 186 /* iterate through the chunks */ 187 while ((frame_size > 0) && (num_chunks > 0)) { 188 chunk_size = bytestream2_get_le32(&g2); 189 chunk_type = bytestream2_get_le16(&g2); 190 191 switch (chunk_type) { 192 case FLI_256_COLOR: 193 case FLI_COLOR: 194 stream_ptr_after_color_chunk = bytestream2_tell(&g2) + chunk_size - 6; 195 196 /* check special case: If this file is from the Magic Carpet 197 * game and uses 6-bit colors even though it reports 256-color 198 * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during 199 * initialization) */ 200 if ((chunk_type == FLI_256_COLOR) && (s->fli_type != FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE)) 201 color_shift = 0; 202 else 203 color_shift = 2; 204 /* set up the palette */ 205 color_packets = bytestream2_get_le16(&g2); 206 palette_ptr = 0; 207 for (i = 0; i < color_packets; i++) { 208 /* first byte is how many colors to skip */ 209 palette_ptr += bytestream2_get_byte(&g2); 210 211 /* next byte indicates how many entries to change */ 212 color_changes = bytestream2_get_byte(&g2); 213 214 /* if there are 0 color changes, there are actually 256 */ 215 if (color_changes == 0) 216 color_changes = 256; 217 218 for (j = 0; j < color_changes; j++) { 219 unsigned int entry; 220 221 /* wrap around, for good measure */ 222 if ((unsigned)palette_ptr >= 256) 223 palette_ptr = 0; 224 225 r = bytestream2_get_byte(&g2) << color_shift; 226 g = bytestream2_get_byte(&g2) << color_shift; 227 b = bytestream2_get_byte(&g2) << color_shift; 228 entry = (r << 16) | (g << 8) | b; 229 if (s->palette[palette_ptr] != entry) 230 s->new_palette = 1; 231 s->palette[palette_ptr++] = entry; 232 } 233 } 234 235 /* color chunks sometimes have weird 16-bit alignment issues; 236 * therefore, take the hardline approach and skip 237 * to the value calculated w.r.t. the size specified by the color 238 * chunk header */ 239 if (stream_ptr_after_color_chunk - bytestream2_tell(&g2) > 0) 240 bytestream2_skip(&g2, stream_ptr_after_color_chunk - bytestream2_tell(&g2)); 241 242 break; 243 244 case FLI_DELTA: 245 y_ptr = 0; 246 compressed_lines = bytestream2_get_le16(&g2); 247 while (compressed_lines > 0) { 248 line_packets = bytestream2_get_le16(&g2); 249 if ((line_packets & 0xC000) == 0xC000) { 250 // line skip opcode 251 line_packets = -line_packets; 252 y_ptr += line_packets * s->frame.linesize[0]; 253 } else if ((line_packets & 0xC000) == 0x4000) { 254 av_log(avctx, AV_LOG_ERROR, "Undefined opcode (%x) in DELTA_FLI\n", line_packets); 255 } else if ((line_packets & 0xC000) == 0x8000) { 256 // "last byte" opcode 257 pixel_ptr= y_ptr + s->frame.linesize[0] - 1; 258 CHECK_PIXEL_PTR(0); 259 pixels[pixel_ptr] = line_packets & 0xff; 260 } else { 261 compressed_lines--; 262 pixel_ptr = y_ptr; 263 CHECK_PIXEL_PTR(0); 264 pixel_countdown = s->avctx->width; 265 for (i = 0; i < line_packets; i++) { 266 /* account for the skip bytes */ 267 pixel_skip = bytestream2_get_byte(&g2); 268 pixel_ptr += pixel_skip; 269 pixel_countdown -= pixel_skip; 270 byte_run = sign_extend(bytestream2_get_byte(&g2), 8); 271 if (byte_run < 0) { 272 byte_run = -byte_run; 273 palette_idx1 = bytestream2_get_byte(&g2); 274 palette_idx2 = bytestream2_get_byte(&g2); 275 CHECK_PIXEL_PTR(byte_run * 2); 276 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) { 277 pixels[pixel_ptr++] = palette_idx1; 278 pixels[pixel_ptr++] = palette_idx2; 279 } 280 } else { 281 CHECK_PIXEL_PTR(byte_run * 2); 282 for (j = 0; j < byte_run * 2; j++, pixel_countdown--) { 283 pixels[pixel_ptr++] = bytestream2_get_byte(&g2); 284 } 285 } 286 } 287 288 y_ptr += s->frame.linesize[0]; 289 } 290 } 291 break; 292 293 case FLI_LC: 294 /* line compressed */ 295 starting_line = bytestream2_get_le16(&g2); 296 y_ptr = 0; 297 y_ptr += starting_line * s->frame.linesize[0]; 298 299 compressed_lines = bytestream2_get_le16(&g2); 300 while (compressed_lines > 0) { 301 pixel_ptr = y_ptr; 302 CHECK_PIXEL_PTR(0); 303 pixel_countdown = s->avctx->width; 304 line_packets = bytestream2_get_byte(&g2); 305 if (line_packets > 0) { 306 for (i = 0; i < line_packets; i++) { 307 /* account for the skip bytes */ 308 pixel_skip = bytestream2_get_byte(&g2); 309 pixel_ptr += pixel_skip; 310 pixel_countdown -= pixel_skip; 311 byte_run = sign_extend(bytestream2_get_byte(&g2),8); 312 if (byte_run > 0) { 313 CHECK_PIXEL_PTR(byte_run); 314 for (j = 0; j < byte_run; j++, pixel_countdown--) { 315 pixels[pixel_ptr++] = bytestream2_get_byte(&g2); 316 } 317 } else if (byte_run < 0) { 318 byte_run = -byte_run; 319 palette_idx1 = bytestream2_get_byte(&g2); 320 CHECK_PIXEL_PTR(byte_run); 321 for (j = 0; j < byte_run; j++, pixel_countdown--) { 322 pixels[pixel_ptr++] = palette_idx1; 323 } 324 } 325 } 326 } 327 328 y_ptr += s->frame.linesize[0]; 329 compressed_lines--; 330 } 331 break; 332 333 case FLI_BLACK: 334 /* set the whole frame to color 0 (which is usually black) */ 335 memset(pixels, 0, 336 s->frame.linesize[0] * s->avctx->height); 337 break; 338 339 case FLI_BRUN: 340 /* Byte run compression: This chunk type only occurs in the first 341 * FLI frame and it will update the entire frame. */ 342 y_ptr = 0; 343 for (lines = 0; lines < s->avctx->height; lines++) { 344 pixel_ptr = y_ptr; 345 /* disregard the line packets; instead, iterate through all 346 * pixels on a row */ 347 bytestream2_skip(&g2, 1); 348 pixel_countdown = s->avctx->width; 349 while (pixel_countdown > 0) { 350 byte_run = sign_extend(bytestream2_get_byte(&g2), 8); 351 if (byte_run > 0) { 352 palette_idx1 = bytestream2_get_byte(&g2); 353 CHECK_PIXEL_PTR(byte_run); 354 for (j = 0; j < byte_run; j++) { 355 pixels[pixel_ptr++] = palette_idx1; 356 pixel_countdown--; 357 if (pixel_countdown < 0) 358 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n", 359 pixel_countdown, lines); 360 } 361 } else { /* copy bytes if byte_run < 0 */ 362 byte_run = -byte_run; 363 CHECK_PIXEL_PTR(byte_run); 364 for (j = 0; j < byte_run; j++) { 365 pixels[pixel_ptr++] = bytestream2_get_byte(&g2); 366 pixel_countdown--; 367 if (pixel_countdown < 0) 368 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n", 369 pixel_countdown, lines); 370 } 371 } 372 } 373 374 y_ptr += s->frame.linesize[0]; 375 } 376 break; 377 378 case FLI_COPY: 379 /* copy the chunk (uncompressed frame) */ 380 if (chunk_size - 6 > s->avctx->width * s->avctx->height) { 381 av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \ 382 "bigger than image, skipping chunk\n", chunk_size - 6); 383 bytestream2_skip(&g2, chunk_size - 6); 384 } else { 385 for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height; 386 y_ptr += s->frame.linesize[0]) { 387 bytestream2_get_buffer(&g2, &pixels[y_ptr], 388 s->avctx->width); 389 } 390 } 391 break; 392 393 case FLI_MINI: 394 /* some sort of a thumbnail? disregard this chunk... */ 395 bytestream2_skip(&g2, chunk_size - 6); 396 break; 397 398 default: 399 av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type); 400 break; 401 } 402 403 frame_size -= chunk_size; 404 num_chunks--; 405 } 406 407 /* by the end of the chunk, the stream ptr should equal the frame 408 * size (minus 1, possibly); if it doesn't, issue a warning */ 409 if ((bytestream2_get_bytes_left(&g2) != 0) && 410 (bytestream2_get_bytes_left(&g2) != 1)) 411 av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \ 412 "and final chunk ptr = %d\n", buf_size, 413 buf_size - bytestream2_get_bytes_left(&g2)); 414 415 /* make the palette available on the way out */ 416 memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); 417 if (s->new_palette) { 418 s->frame.palette_has_changed = 1; 419 s->new_palette = 0; 420 } 421 422 *data_size=sizeof(AVFrame); 423 *(AVFrame*)data = s->frame; 424 425 return buf_size; 426} 427 428static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, 429 void *data, int *data_size, 430 const uint8_t *buf, int buf_size) 431{ 432 /* Note, the only difference between the 15Bpp and 16Bpp */ 433 /* Format is the pixel format, the packets are processed the same. */ 434 FlicDecodeContext *s = avctx->priv_data; 435 436 GetByteContext g2; 437 int pixel_ptr; 438 unsigned char palette_idx1; 439 440 unsigned int frame_size; 441 int num_chunks; 442 443 unsigned int chunk_size; 444 int chunk_type; 445 446 int i, j; 447 448 int lines; 449 int compressed_lines; 450 signed short line_packets; 451 int y_ptr; 452 int byte_run; 453 int pixel_skip; 454 int pixel_countdown; 455 unsigned char *pixels; 456 int pixel; 457 unsigned int pixel_limit; 458 459 bytestream2_init(&g2, buf, buf_size); 460 461 s->frame.reference = 1; 462 s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; 463 if (avctx->reget_buffer(avctx, &s->frame) < 0) { 464 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); 465 return -1; 466 } 467 468 pixels = s->frame.data[0]; 469 pixel_limit = s->avctx->height * s->frame.linesize[0]; 470 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 */ 475 476 frame_size -= 16; 477 478 /* iterate through the chunks */ 479 while ((frame_size > 0) && (num_chunks > 0)) { 480 chunk_size = bytestream2_get_le32(&g2); 481 chunk_type = bytestream2_get_le16(&g2); 482 483 switch (chunk_type) { 484 case FLI_256_COLOR: 485 case FLI_COLOR: 486 /* For some reason, it seems that non-palettized flics do 487 * include one of these chunks in their first frame. 488 * Why I do not know, it seems rather extraneous. */ 489/* av_log(avctx, AV_LOG_ERROR, "Unexpected Palette chunk %d in non-paletised FLC\n",chunk_type);*/ 490 bytestream2_skip(&g2, chunk_size - 6); 491 break; 492 493 case FLI_DELTA: 494 case FLI_DTA_LC: 495 y_ptr = 0; 496 compressed_lines = bytestream2_get_le16(&g2); 497 while (compressed_lines > 0) { 498 line_packets = bytestream2_get_le16(&g2); 499 if (line_packets < 0) { 500 line_packets = -line_packets; 501 y_ptr += line_packets * s->frame.linesize[0]; 502 } else { 503 compressed_lines--; 504 pixel_ptr = y_ptr; 505 CHECK_PIXEL_PTR(0); 506 pixel_countdown = s->avctx->width; 507 for (i = 0; i < line_packets; i++) { 508 /* account for the skip bytes */ 509 pixel_skip = bytestream2_get_byte(&g2); 510 pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */ 511 pixel_countdown -= pixel_skip; 512 byte_run = sign_extend(bytestream2_get_byte(&g2), 8); 513 if (byte_run < 0) { 514 byte_run = -byte_run; 515 pixel = bytestream2_get_le16(&g2); 516 CHECK_PIXEL_PTR(2 * byte_run); 517 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) { 518 *((signed short*)(&pixels[pixel_ptr])) = pixel; 519 pixel_ptr += 2; 520 } 521 } else { 522 CHECK_PIXEL_PTR(2 * byte_run); 523 for (j = 0; j < byte_run; j++, pixel_countdown--) { 524 *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2); 525 pixel_ptr += 2; 526 } 527 } 528 } 529 530 y_ptr += s->frame.linesize[0]; 531 } 532 } 533 break; 534 535 case FLI_LC: 536 av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-paletised FLC\n"); 537 bytestream2_skip(&g2, chunk_size - 6); 538 break; 539 540 case FLI_BLACK: 541 /* set the whole frame to 0x0000 which is black in both 15Bpp and 16Bpp modes. */ 542 memset(pixels, 0x0000, 543 s->frame.linesize[0] * s->avctx->height); 544 break; 545 546 case FLI_BRUN: 547 y_ptr = 0; 548 for (lines = 0; lines < s->avctx->height; lines++) { 549 pixel_ptr = y_ptr; 550 /* disregard the line packets; instead, iterate through all 551 * pixels on a row */ 552 bytestream2_skip(&g2, 1); 553 pixel_countdown = (s->avctx->width * 2); 554 555 while (pixel_countdown > 0) { 556 byte_run = sign_extend(bytestream2_get_byte(&g2), 8); 557 if (byte_run > 0) { 558 palette_idx1 = bytestream2_get_byte(&g2); 559 CHECK_PIXEL_PTR(byte_run); 560 for (j = 0; j < byte_run; j++) { 561 pixels[pixel_ptr++] = palette_idx1; 562 pixel_countdown--; 563 if (pixel_countdown < 0) 564 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) (linea%d)\n", 565 pixel_countdown, lines); 566 } 567 } else { /* copy bytes if byte_run < 0 */ 568 byte_run = -byte_run; 569 CHECK_PIXEL_PTR(byte_run); 570 for (j = 0; j < byte_run; j++) { 571 palette_idx1 = bytestream2_get_byte(&g2); 572 pixels[pixel_ptr++] = palette_idx1; 573 pixel_countdown--; 574 if (pixel_countdown < 0) 575 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n", 576 pixel_countdown, lines); 577 } 578 } 579 } 580 581 /* Now FLX is strange, in that it is "byte" as opposed to "pixel" run length compressed. 582 * This does not give us any good oportunity to perform word endian conversion 583 * during decompression. So if it is required (i.e., this is not a LE target, we do 584 * a second pass over the line here, swapping the bytes. 585 */ 586#if HAVE_BIGENDIAN 587 pixel_ptr = y_ptr; 588 pixel_countdown = s->avctx->width; 589 while (pixel_countdown > 0) { 590 *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[pixel_ptr]); 591 pixel_ptr += 2; 592 } 593#endif 594 y_ptr += s->frame.linesize[0]; 595 } 596 break; 597 598 case FLI_DTA_BRUN: 599 y_ptr = 0; 600 for (lines = 0; lines < s->avctx->height; lines++) { 601 pixel_ptr = y_ptr; 602 /* disregard the line packets; instead, iterate through all 603 * pixels on a row */ 604 bytestream2_skip(&g2, 1); 605 pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */ 606 607 while (pixel_countdown > 0) { 608 byte_run = sign_extend(bytestream2_get_byte(&g2), 8); 609 if (byte_run > 0) { 610 pixel = bytestream2_get_le16(&g2); 611 CHECK_PIXEL_PTR(2 * byte_run); 612 for (j = 0; j < byte_run; j++) { 613 *((signed short*)(&pixels[pixel_ptr])) = pixel; 614 pixel_ptr += 2; 615 pixel_countdown--; 616 if (pixel_countdown < 0) 617 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n", 618 pixel_countdown); 619 } 620 } else { /* copy pixels if byte_run < 0 */ 621 byte_run = -byte_run; 622 CHECK_PIXEL_PTR(2 * byte_run); 623 for (j = 0; j < byte_run; j++) { 624 *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2); 625 pixel_ptr += 2; 626 pixel_countdown--; 627 if (pixel_countdown < 0) 628 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n", 629 pixel_countdown); 630 } 631 } 632 } 633 634 y_ptr += s->frame.linesize[0]; 635 } 636 break; 637 638 case FLI_COPY: 639 case FLI_DTA_COPY: 640 /* copy the chunk (uncompressed frame) */ 641 if (chunk_size - 6 > (unsigned int)(s->avctx->width * s->avctx->height)*2) { 642 av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \ 643 "bigger than image, skipping chunk\n", chunk_size - 6); 644 bytestream2_skip(&g2, chunk_size - 6); 645 } else { 646 647 for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height; 648 y_ptr += s->frame.linesize[0]) { 649 650 pixel_countdown = s->avctx->width; 651 pixel_ptr = 0; 652 while (pixel_countdown > 0) { 653 *((signed short*)(&pixels[y_ptr + pixel_ptr])) = bytestream2_get_le16(&g2); 654 pixel_ptr += 2; 655 pixel_countdown--; 656 } 657 } 658 } 659 break; 660 661 case FLI_MINI: 662 /* some sort of a thumbnail? disregard this chunk... */ 663 bytestream2_skip(&g2, chunk_size - 6); 664 break; 665 666 default: 667 av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type); 668 break; 669 } 670 671 frame_size -= chunk_size; 672 num_chunks--; 673 } 674 675 /* by the end of the chunk, the stream ptr should equal the frame 676 * size (minus 1, possibly); if it doesn't, issue a warning */ 677 if ((bytestream2_get_bytes_left(&g2) != 0) && (bytestream2_get_bytes_left(&g2) != 1)) 678 av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \ 679 "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2)); 680 681 682 *data_size=sizeof(AVFrame); 683 *(AVFrame*)data = s->frame; 684 685 return buf_size; 686} 687 688static int flic_decode_frame_24BPP(AVCodecContext *avctx, 689 void *data, int *data_size, 690 const uint8_t *buf, int buf_size) 691{ 692 av_log(avctx, AV_LOG_ERROR, "24Bpp FLC Unsupported due to lack of test files.\n"); 693 return -1; 694} 695 696static int flic_decode_frame(AVCodecContext *avctx, 697 void *data, int *data_size, 698 AVPacket *avpkt) 699{ 700 const uint8_t *buf = avpkt->data; 701 int buf_size = avpkt->size; 702 if (avctx->pix_fmt == PIX_FMT_PAL8) { 703 return flic_decode_frame_8BPP(avctx, data, data_size, 704 buf, buf_size); 705 } 706 else if ((avctx->pix_fmt == PIX_FMT_RGB555) || 707 (avctx->pix_fmt == PIX_FMT_RGB565)) { 708 return flic_decode_frame_15_16BPP(avctx, data, data_size, 709 buf, buf_size); 710 } 711 else if (avctx->pix_fmt == PIX_FMT_BGR24) { 712 return flic_decode_frame_24BPP(avctx, data, data_size, 713 buf, buf_size); 714 } 715 716 /* Should not get here, ever as the pix_fmt is processed */ 717 /* in flic_decode_init and the above if should deal with */ 718 /* the finite set of possibilites allowable by here. */ 719 /* But in case we do, just error out. */ 720 av_log(avctx, AV_LOG_ERROR, "Unknown FLC format, my science cannot explain how this happened.\n"); 721 return -1; 722} 723 724 725static av_cold int flic_decode_end(AVCodecContext *avctx) 726{ 727 FlicDecodeContext *s = avctx->priv_data; 728 729 if (s->frame.data[0]) 730 avctx->release_buffer(avctx, &s->frame); 731 732 return 0; 733} 734 735AVCodec ff_flic_decoder = { 736 .name = "flic", 737 .type = AVMEDIA_TYPE_VIDEO, 738 .id = CODEC_ID_FLIC, 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, 744 .long_name = NULL_IF_CONFIG_SMALL("Autodesk Animator Flic video"), 745}; 746