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