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 "avcodec.h"
00044 #include "bswap.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 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 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 #ifdef WORDS_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 const uint8_t *buf, int buf_size)
00704 {
00705 if (avctx->pix_fmt == PIX_FMT_PAL8) {
00706 return flic_decode_frame_8BPP(avctx, data, data_size,
00707 buf, buf_size);
00708 }
00709 else if ((avctx->pix_fmt == PIX_FMT_RGB555) ||
00710 (avctx->pix_fmt == PIX_FMT_RGB565)) {
00711 return flic_decode_frame_15_16BPP(avctx, data, data_size,
00712 buf, buf_size);
00713 }
00714 else if (avctx->pix_fmt == PIX_FMT_BGR24) {
00715 return flic_decode_frame_24BPP(avctx, data, data_size,
00716 buf, buf_size);
00717 }
00718
00719
00720
00721
00722
00723 av_log(avctx, AV_LOG_ERROR, "Unknown FLC format, my science cannot explain how this happened.\n");
00724 return -1;
00725 }
00726
00727
00728 static int flic_decode_end(AVCodecContext *avctx)
00729 {
00730 FlicDecodeContext *s = avctx->priv_data;
00731
00732 if (s->frame.data[0])
00733 avctx->release_buffer(avctx, &s->frame);
00734
00735 return 0;
00736 }
00737
00738 AVCodec flic_decoder = {
00739 "flic",
00740 CODEC_TYPE_VIDEO,
00741 CODEC_ID_FLIC,
00742 sizeof(FlicDecodeContext),
00743 flic_decode_init,
00744 NULL,
00745 flic_decode_end,
00746 flic_decode_frame,
00747 CODEC_CAP_DR1,
00748 NULL,
00749 NULL,
00750 NULL,
00751 NULL
00752 };