00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include <string.h>
00041
00042 #include "libavutil/intreadwrite.h"
00043 #include "avcodec.h"
00044
00045 #define FLI_256_COLOR 4
00046 #define FLI_DELTA 7
00047 #define FLI_COLOR 11
00048 #define FLI_LC 12
00049 #define FLI_BLACK 13
00050 #define FLI_BRUN 15
00051 #define FLI_COPY 16
00052 #define FLI_MINI 18
00053 #define FLI_DTA_BRUN 25
00054 #define FLI_DTA_COPY 26
00055 #define FLI_DTA_LC 27
00056
00057 #define FLI_TYPE_CODE (0xAF11)
00058 #define FLC_FLX_TYPE_CODE (0xAF12)
00059 #define FLC_DTA_TYPE_CODE (0xAF44)
00060 #define FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE (0xAF13)
00061
00062 #define CHECK_PIXEL_PTR(n) \
00063 if (pixel_ptr + n > pixel_limit) { \
00064 av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr >= pixel_limit (%d >= %d)\n", \
00065 pixel_ptr + n, pixel_limit); \
00066 return -1; \
00067 } \
00068
00069 typedef struct FlicDecodeContext {
00070 AVCodecContext *avctx;
00071 AVFrame frame;
00072
00073 unsigned int palette[256];
00074 int new_palette;
00075 int fli_type;
00076 } FlicDecodeContext;
00077
00078 static av_cold int flic_decode_init(AVCodecContext *avctx)
00079 {
00080 FlicDecodeContext *s = avctx->priv_data;
00081 unsigned char *fli_header = (unsigned char *)avctx->extradata;
00082 int depth;
00083
00084 s->avctx = avctx;
00085
00086 s->fli_type = AV_RL16(&fli_header[4]);
00087
00088 depth = 0;
00089 if (s->avctx->extradata_size == 12) {
00090
00091 s->fli_type = FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE;
00092 depth = 8;
00093 } else if (s->avctx->extradata_size != 128) {
00094 av_log(avctx, AV_LOG_ERROR, "Expected extradata of 12 or 128 bytes\n");
00095 return -1;
00096 } else {
00097 depth = AV_RL16(&fli_header[12]);
00098 }
00099
00100 if (depth == 0) {
00101 depth = 8;
00102 }
00103
00104 if ((s->fli_type == FLC_FLX_TYPE_CODE) && (depth == 16)) {
00105 depth = 15;
00106 }
00107
00108 switch (depth) {
00109 case 8 : avctx->pix_fmt = PIX_FMT_PAL8; break;
00110 case 15 : avctx->pix_fmt = PIX_FMT_RGB555; break;
00111 case 16 : avctx->pix_fmt = PIX_FMT_RGB565; break;
00112 case 24 : avctx->pix_fmt = PIX_FMT_BGR24;
00113 av_log(avctx, AV_LOG_ERROR, "24Bpp FLC/FLX is unsupported due to no test files.\n");
00114 return -1;
00115 break;
00116 default :
00117 av_log(avctx, AV_LOG_ERROR, "Unknown FLC/FLX depth of %d Bpp is unsupported.\n",depth);
00118 return -1;
00119 }
00120
00121 s->frame.data[0] = NULL;
00122 s->new_palette = 0;
00123
00124 return 0;
00125 }
00126
00127 static int flic_decode_frame_8BPP(AVCodecContext *avctx,
00128 void *data, int *data_size,
00129 const uint8_t *buf, int buf_size)
00130 {
00131 FlicDecodeContext *s = avctx->priv_data;
00132
00133 int stream_ptr = 0;
00134 int stream_ptr_after_color_chunk;
00135 int pixel_ptr;
00136 int palette_ptr;
00137 unsigned char palette_idx1;
00138 unsigned char palette_idx2;
00139
00140 unsigned int frame_size;
00141 int num_chunks;
00142
00143 unsigned int chunk_size;
00144 int chunk_type;
00145
00146 int i, j;
00147
00148 int color_packets;
00149 int color_changes;
00150 int color_shift;
00151 unsigned char r, g, b;
00152
00153 int lines;
00154 int compressed_lines;
00155 int starting_line;
00156 signed short line_packets;
00157 int y_ptr;
00158 int byte_run;
00159 int pixel_skip;
00160 int pixel_countdown;
00161 unsigned char *pixels;
00162 int pixel_limit;
00163
00164 s->frame.reference = 1;
00165 s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
00166 if (avctx->reget_buffer(avctx, &s->frame) < 0) {
00167 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00168 return -1;
00169 }
00170
00171 pixels = s->frame.data[0];
00172 pixel_limit = s->avctx->height * s->frame.linesize[0];
00173
00174 frame_size = AV_RL32(&buf[stream_ptr]);
00175 stream_ptr += 6;
00176 num_chunks = AV_RL16(&buf[stream_ptr]);
00177 stream_ptr += 10;
00178
00179 frame_size -= 16;
00180
00181
00182 while ((frame_size > 0) && (num_chunks > 0)) {
00183 chunk_size = AV_RL32(&buf[stream_ptr]);
00184 stream_ptr += 4;
00185 chunk_type = AV_RL16(&buf[stream_ptr]);
00186 stream_ptr += 2;
00187
00188 switch (chunk_type) {
00189 case FLI_256_COLOR:
00190 case FLI_COLOR:
00191 stream_ptr_after_color_chunk = stream_ptr + chunk_size - 6;
00192
00193
00194
00195
00196
00197 if ((chunk_type == FLI_256_COLOR) && (s->fli_type != FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE))
00198 color_shift = 0;
00199 else
00200 color_shift = 2;
00201
00202 color_packets = AV_RL16(&buf[stream_ptr]);
00203 stream_ptr += 2;
00204 palette_ptr = 0;
00205 for (i = 0; i < color_packets; i++) {
00206
00207 palette_ptr += buf[stream_ptr++];
00208
00209
00210 color_changes = buf[stream_ptr++];
00211
00212
00213 if (color_changes == 0)
00214 color_changes = 256;
00215
00216 for (j = 0; j < color_changes; j++) {
00217 unsigned int entry;
00218
00219
00220 if ((unsigned)palette_ptr >= 256)
00221 palette_ptr = 0;
00222
00223 r = buf[stream_ptr++] << color_shift;
00224 g = buf[stream_ptr++] << color_shift;
00225 b = buf[stream_ptr++] << color_shift;
00226 entry = (r << 16) | (g << 8) | b;
00227 if (s->palette[palette_ptr] != entry)
00228 s->new_palette = 1;
00229 s->palette[palette_ptr++] = entry;
00230 }
00231 }
00232
00233
00234
00235
00236
00237 stream_ptr = stream_ptr_after_color_chunk;
00238
00239 break;
00240
00241 case FLI_DELTA:
00242 y_ptr = 0;
00243 compressed_lines = AV_RL16(&buf[stream_ptr]);
00244 stream_ptr += 2;
00245 while (compressed_lines > 0) {
00246 line_packets = AV_RL16(&buf[stream_ptr]);
00247 stream_ptr += 2;
00248 if ((line_packets & 0xC000) == 0xC000) {
00249
00250 line_packets = -line_packets;
00251 y_ptr += line_packets * s->frame.linesize[0];
00252 } else if ((line_packets & 0xC000) == 0x4000) {
00253 av_log(avctx, AV_LOG_ERROR, "Undefined opcode (%x) in DELTA_FLI\n", line_packets);
00254 } else if ((line_packets & 0xC000) == 0x8000) {
00255
00256 pixels[y_ptr + s->frame.linesize[0] - 1] = line_packets & 0xff;
00257 } else {
00258 compressed_lines--;
00259 pixel_ptr = y_ptr;
00260 pixel_countdown = s->avctx->width;
00261 for (i = 0; i < line_packets; i++) {
00262
00263 pixel_skip = buf[stream_ptr++];
00264 pixel_ptr += pixel_skip;
00265 pixel_countdown -= pixel_skip;
00266 byte_run = (signed char)(buf[stream_ptr++]);
00267 if (byte_run < 0) {
00268 byte_run = -byte_run;
00269 palette_idx1 = buf[stream_ptr++];
00270 palette_idx2 = buf[stream_ptr++];
00271 CHECK_PIXEL_PTR(byte_run);
00272 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
00273 pixels[pixel_ptr++] = palette_idx1;
00274 pixels[pixel_ptr++] = palette_idx2;
00275 }
00276 } else {
00277 CHECK_PIXEL_PTR(byte_run * 2);
00278 for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
00279 palette_idx1 = buf[stream_ptr++];
00280 pixels[pixel_ptr++] = palette_idx1;
00281 }
00282 }
00283 }
00284
00285 y_ptr += s->frame.linesize[0];
00286 }
00287 }
00288 break;
00289
00290 case FLI_LC:
00291
00292 starting_line = AV_RL16(&buf[stream_ptr]);
00293 stream_ptr += 2;
00294 y_ptr = 0;
00295 y_ptr += starting_line * s->frame.linesize[0];
00296
00297 compressed_lines = AV_RL16(&buf[stream_ptr]);
00298 stream_ptr += 2;
00299 while (compressed_lines > 0) {
00300 pixel_ptr = y_ptr;
00301 pixel_countdown = s->avctx->width;
00302 line_packets = buf[stream_ptr++];
00303 if (line_packets > 0) {
00304 for (i = 0; i < line_packets; i++) {
00305
00306 pixel_skip = buf[stream_ptr++];
00307 pixel_ptr += pixel_skip;
00308 pixel_countdown -= pixel_skip;
00309 byte_run = (signed char)(buf[stream_ptr++]);
00310 if (byte_run > 0) {
00311 CHECK_PIXEL_PTR(byte_run);
00312 for (j = 0; j < byte_run; j++, pixel_countdown--) {
00313 palette_idx1 = buf[stream_ptr++];
00314 pixels[pixel_ptr++] = palette_idx1;
00315 }
00316 } else if (byte_run < 0) {
00317 byte_run = -byte_run;
00318 palette_idx1 = buf[stream_ptr++];
00319 CHECK_PIXEL_PTR(byte_run);
00320 for (j = 0; j < byte_run; j++, pixel_countdown--) {
00321 pixels[pixel_ptr++] = palette_idx1;
00322 }
00323 }
00324 }
00325 }
00326
00327 y_ptr += s->frame.linesize[0];
00328 compressed_lines--;
00329 }
00330 break;
00331
00332 case FLI_BLACK:
00333
00334 memset(pixels, 0,
00335 s->frame.linesize[0] * s->avctx->height);
00336 break;
00337
00338 case FLI_BRUN:
00339
00340
00341 y_ptr = 0;
00342 for (lines = 0; lines < s->avctx->height; lines++) {
00343 pixel_ptr = y_ptr;
00344
00345
00346 stream_ptr++;
00347 pixel_countdown = s->avctx->width;
00348 while (pixel_countdown > 0) {
00349 byte_run = (signed char)(buf[stream_ptr++]);
00350 if (byte_run > 0) {
00351 palette_idx1 = buf[stream_ptr++];
00352 CHECK_PIXEL_PTR(byte_run);
00353 for (j = 0; j < byte_run; j++) {
00354 pixels[pixel_ptr++] = palette_idx1;
00355 pixel_countdown--;
00356 if (pixel_countdown < 0)
00357 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
00358 pixel_countdown, lines);
00359 }
00360 } else {
00361 byte_run = -byte_run;
00362 CHECK_PIXEL_PTR(byte_run);
00363 for (j = 0; j < byte_run; j++) {
00364 palette_idx1 = buf[stream_ptr++];
00365 pixels[pixel_ptr++] = palette_idx1;
00366 pixel_countdown--;
00367 if (pixel_countdown < 0)
00368 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
00369 pixel_countdown, lines);
00370 }
00371 }
00372 }
00373
00374 y_ptr += s->frame.linesize[0];
00375 }
00376 break;
00377
00378 case FLI_COPY:
00379
00380 if (chunk_size - 6 > s->avctx->width * s->avctx->height) {
00381 av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
00382 "bigger than image, skipping chunk\n", chunk_size - 6);
00383 stream_ptr += chunk_size - 6;
00384 } else {
00385 for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
00386 y_ptr += s->frame.linesize[0]) {
00387 memcpy(&pixels[y_ptr], &buf[stream_ptr],
00388 s->avctx->width);
00389 stream_ptr += s->avctx->width;
00390 }
00391 }
00392 break;
00393
00394 case FLI_MINI:
00395
00396 stream_ptr += chunk_size - 6;
00397 break;
00398
00399 default:
00400 av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
00401 break;
00402 }
00403
00404 frame_size -= chunk_size;
00405 num_chunks--;
00406 }
00407
00408
00409
00410 if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1))
00411 av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
00412 "and final chunk ptr = %d\n", buf_size, stream_ptr);
00413
00414
00415 memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
00416 if (s->new_palette) {
00417 s->frame.palette_has_changed = 1;
00418 s->new_palette = 0;
00419 }
00420
00421 *data_size=sizeof(AVFrame);
00422 *(AVFrame*)data = s->frame;
00423
00424 return buf_size;
00425 }
00426
00427 static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
00428 void *data, int *data_size,
00429 const uint8_t *buf, int buf_size)
00430 {
00431
00432
00433 FlicDecodeContext *s = avctx->priv_data;
00434
00435 int stream_ptr = 0;
00436 int pixel_ptr;
00437 unsigned char palette_idx1;
00438
00439 unsigned int frame_size;
00440 int num_chunks;
00441
00442 unsigned int chunk_size;
00443 int chunk_type;
00444
00445 int i, j;
00446
00447 int lines;
00448 int compressed_lines;
00449 signed short line_packets;
00450 int y_ptr;
00451 int byte_run;
00452 int pixel_skip;
00453 int pixel_countdown;
00454 unsigned char *pixels;
00455 int pixel;
00456 int pixel_limit;
00457
00458 s->frame.reference = 1;
00459 s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
00460 if (avctx->reget_buffer(avctx, &s->frame) < 0) {
00461 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00462 return -1;
00463 }
00464
00465 pixels = s->frame.data[0];
00466 pixel_limit = s->avctx->height * s->frame.linesize[0];
00467
00468 frame_size = AV_RL32(&buf[stream_ptr]);
00469 stream_ptr += 6;
00470 num_chunks = AV_RL16(&buf[stream_ptr]);
00471 stream_ptr += 10;
00472
00473 frame_size -= 16;
00474
00475
00476 while ((frame_size > 0) && (num_chunks > 0)) {
00477 chunk_size = AV_RL32(&buf[stream_ptr]);
00478 stream_ptr += 4;
00479 chunk_type = AV_RL16(&buf[stream_ptr]);
00480 stream_ptr += 2;
00481
00482 switch (chunk_type) {
00483 case FLI_256_COLOR:
00484 case FLI_COLOR:
00485
00486
00487
00488
00489 stream_ptr = stream_ptr + chunk_size - 6;
00490 break;
00491
00492 case FLI_DELTA:
00493 case FLI_DTA_LC:
00494 y_ptr = 0;
00495 compressed_lines = AV_RL16(&buf[stream_ptr]);
00496 stream_ptr += 2;
00497 while (compressed_lines > 0) {
00498 line_packets = AV_RL16(&buf[stream_ptr]);
00499 stream_ptr += 2;
00500 if (line_packets < 0) {
00501 line_packets = -line_packets;
00502 y_ptr += line_packets * s->frame.linesize[0];
00503 } else {
00504 compressed_lines--;
00505 pixel_ptr = y_ptr;
00506 pixel_countdown = s->avctx->width;
00507 for (i = 0; i < line_packets; i++) {
00508
00509 pixel_skip = buf[stream_ptr++];
00510 pixel_ptr += (pixel_skip*2);
00511 pixel_countdown -= pixel_skip;
00512 byte_run = (signed char)(buf[stream_ptr++]);
00513 if (byte_run < 0) {
00514 byte_run = -byte_run;
00515 pixel = AV_RL16(&buf[stream_ptr]);
00516 stream_ptr += 2;
00517 CHECK_PIXEL_PTR(byte_run);
00518 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
00519 *((signed short*)(&pixels[pixel_ptr])) = pixel;
00520 pixel_ptr += 2;
00521 }
00522 } else {
00523 CHECK_PIXEL_PTR(byte_run);
00524 for (j = 0; j < byte_run; j++, pixel_countdown--) {
00525 *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[stream_ptr]);
00526 stream_ptr += 2;
00527 pixel_ptr += 2;
00528 }
00529 }
00530 }
00531
00532 y_ptr += s->frame.linesize[0];
00533 }
00534 }
00535 break;
00536
00537 case FLI_LC:
00538 av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-paletised FLC\n");
00539 stream_ptr = stream_ptr + chunk_size - 6;
00540 break;
00541
00542 case FLI_BLACK:
00543
00544 memset(pixels, 0x0000,
00545 s->frame.linesize[0] * s->avctx->height);
00546 break;
00547
00548 case FLI_BRUN:
00549 y_ptr = 0;
00550 for (lines = 0; lines < s->avctx->height; lines++) {
00551 pixel_ptr = y_ptr;
00552
00553
00554 stream_ptr++;
00555 pixel_countdown = (s->avctx->width * 2);
00556
00557 while (pixel_countdown > 0) {
00558 byte_run = (signed char)(buf[stream_ptr++]);
00559 if (byte_run > 0) {
00560 palette_idx1 = buf[stream_ptr++];
00561 CHECK_PIXEL_PTR(byte_run);
00562 for (j = 0; j < byte_run; j++) {
00563 pixels[pixel_ptr++] = palette_idx1;
00564 pixel_countdown--;
00565 if (pixel_countdown < 0)
00566 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) (linea%d)\n",
00567 pixel_countdown, lines);
00568 }
00569 } else {
00570 byte_run = -byte_run;
00571 CHECK_PIXEL_PTR(byte_run);
00572 for (j = 0; j < byte_run; j++) {
00573 palette_idx1 = buf[stream_ptr++];
00574 pixels[pixel_ptr++] = palette_idx1;
00575 pixel_countdown--;
00576 if (pixel_countdown < 0)
00577 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
00578 pixel_countdown, lines);
00579 }
00580 }
00581 }
00582
00583
00584
00585
00586
00587
00588 #if HAVE_BIGENDIAN
00589 pixel_ptr = y_ptr;
00590 pixel_countdown = s->avctx->width;
00591 while (pixel_countdown > 0) {
00592 *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[pixel_ptr]);
00593 pixel_ptr += 2;
00594 }
00595 #endif
00596 y_ptr += s->frame.linesize[0];
00597 }
00598 break;
00599
00600 case FLI_DTA_BRUN:
00601 y_ptr = 0;
00602 for (lines = 0; lines < s->avctx->height; lines++) {
00603 pixel_ptr = y_ptr;
00604
00605
00606 stream_ptr++;
00607 pixel_countdown = s->avctx->width;
00608
00609 while (pixel_countdown > 0) {
00610 byte_run = (signed char)(buf[stream_ptr++]);
00611 if (byte_run > 0) {
00612 pixel = AV_RL16(&buf[stream_ptr]);
00613 stream_ptr += 2;
00614 CHECK_PIXEL_PTR(byte_run);
00615 for (j = 0; j < byte_run; j++) {
00616 *((signed short*)(&pixels[pixel_ptr])) = pixel;
00617 pixel_ptr += 2;
00618 pixel_countdown--;
00619 if (pixel_countdown < 0)
00620 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
00621 pixel_countdown);
00622 }
00623 } else {
00624 byte_run = -byte_run;
00625 CHECK_PIXEL_PTR(byte_run);
00626 for (j = 0; j < byte_run; j++) {
00627 *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[stream_ptr]);
00628 stream_ptr += 2;
00629 pixel_ptr += 2;
00630 pixel_countdown--;
00631 if (pixel_countdown < 0)
00632 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
00633 pixel_countdown);
00634 }
00635 }
00636 }
00637
00638 y_ptr += s->frame.linesize[0];
00639 }
00640 break;
00641
00642 case FLI_COPY:
00643 case FLI_DTA_COPY:
00644
00645 if (chunk_size - 6 > (unsigned int)(s->avctx->width * s->avctx->height)*2) {
00646 av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
00647 "bigger than image, skipping chunk\n", chunk_size - 6);
00648 stream_ptr += chunk_size - 6;
00649 } else {
00650
00651 for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
00652 y_ptr += s->frame.linesize[0]) {
00653
00654 pixel_countdown = s->avctx->width;
00655 pixel_ptr = 0;
00656 while (pixel_countdown > 0) {
00657 *((signed short*)(&pixels[y_ptr + pixel_ptr])) = AV_RL16(&buf[stream_ptr+pixel_ptr]);
00658 pixel_ptr += 2;
00659 pixel_countdown--;
00660 }
00661 stream_ptr += s->avctx->width*2;
00662 }
00663 }
00664 break;
00665
00666 case FLI_MINI:
00667
00668 stream_ptr += chunk_size - 6;
00669 break;
00670
00671 default:
00672 av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
00673 break;
00674 }
00675
00676 frame_size -= chunk_size;
00677 num_chunks--;
00678 }
00679
00680
00681
00682 if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1))
00683 av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
00684 "and final chunk ptr = %d\n", buf_size, stream_ptr);
00685
00686
00687 *data_size=sizeof(AVFrame);
00688 *(AVFrame*)data = s->frame;
00689
00690 return buf_size;
00691 }
00692
00693 static int flic_decode_frame_24BPP(AVCodecContext *avctx,
00694 void *data, int *data_size,
00695 const uint8_t *buf, int buf_size)
00696 {
00697 av_log(avctx, AV_LOG_ERROR, "24Bpp FLC Unsupported due to lack of test files.\n");
00698 return -1;
00699 }
00700
00701 static int flic_decode_frame(AVCodecContext *avctx,
00702 void *data, int *data_size,
00703 AVPacket *avpkt)
00704 {
00705 const uint8_t *buf = avpkt->data;
00706 int buf_size = avpkt->size;
00707 if (avctx->pix_fmt == PIX_FMT_PAL8) {
00708 return flic_decode_frame_8BPP(avctx, data, data_size,
00709 buf, buf_size);
00710 }
00711 else if ((avctx->pix_fmt == PIX_FMT_RGB555) ||
00712 (avctx->pix_fmt == PIX_FMT_RGB565)) {
00713 return flic_decode_frame_15_16BPP(avctx, data, data_size,
00714 buf, buf_size);
00715 }
00716 else if (avctx->pix_fmt == PIX_FMT_BGR24) {
00717 return flic_decode_frame_24BPP(avctx, data, data_size,
00718 buf, buf_size);
00719 }
00720
00721
00722
00723
00724
00725 av_log(avctx, AV_LOG_ERROR, "Unknown FLC format, my science cannot explain how this happened.\n");
00726 return -1;
00727 }
00728
00729
00730 static av_cold int flic_decode_end(AVCodecContext *avctx)
00731 {
00732 FlicDecodeContext *s = avctx->priv_data;
00733
00734 if (s->frame.data[0])
00735 avctx->release_buffer(avctx, &s->frame);
00736
00737 return 0;
00738 }
00739
00740 AVCodec flic_decoder = {
00741 "flic",
00742 AVMEDIA_TYPE_VIDEO,
00743 CODEC_ID_FLIC,
00744 sizeof(FlicDecodeContext),
00745 flic_decode_init,
00746 NULL,
00747 flic_decode_end,
00748 flic_decode_frame,
00749 CODEC_CAP_DR1,
00750 NULL,
00751 NULL,
00752 NULL,
00753 NULL,
00754 .long_name = NULL_IF_CONFIG_SMALL("Autodesk Animator Flic video"),
00755 };