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 unsigned 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 pixel_ptr= y_ptr + s->frame.linesize[0] - 1;
00258 CHECK_PIXEL_PTR(0);
00259 pixels[pixel_ptr] = line_packets & 0xff;
00260 } else {
00261 compressed_lines--;
00262 pixel_ptr = y_ptr;
00263 CHECK_PIXEL_PTR(0);
00264 pixel_countdown = s->avctx->width;
00265 for (i = 0; i < line_packets; i++) {
00266
00267 pixel_skip = buf[stream_ptr++];
00268 pixel_ptr += pixel_skip;
00269 pixel_countdown -= pixel_skip;
00270 byte_run = (signed char)(buf[stream_ptr++]);
00271 if (byte_run < 0) {
00272 byte_run = -byte_run;
00273 palette_idx1 = buf[stream_ptr++];
00274 palette_idx2 = buf[stream_ptr++];
00275 CHECK_PIXEL_PTR(byte_run * 2);
00276 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
00277 pixels[pixel_ptr++] = palette_idx1;
00278 pixels[pixel_ptr++] = palette_idx2;
00279 }
00280 } else {
00281 CHECK_PIXEL_PTR(byte_run * 2);
00282 for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
00283 palette_idx1 = buf[stream_ptr++];
00284 pixels[pixel_ptr++] = palette_idx1;
00285 }
00286 }
00287 }
00288
00289 y_ptr += s->frame.linesize[0];
00290 }
00291 }
00292 break;
00293
00294 case FLI_LC:
00295
00296 starting_line = AV_RL16(&buf[stream_ptr]);
00297 stream_ptr += 2;
00298 y_ptr = 0;
00299 y_ptr += starting_line * s->frame.linesize[0];
00300
00301 compressed_lines = AV_RL16(&buf[stream_ptr]);
00302 stream_ptr += 2;
00303 while (compressed_lines > 0) {
00304 pixel_ptr = y_ptr;
00305 CHECK_PIXEL_PTR(0);
00306 pixel_countdown = s->avctx->width;
00307 line_packets = buf[stream_ptr++];
00308 if (line_packets > 0) {
00309 for (i = 0; i < line_packets; i++) {
00310
00311 pixel_skip = buf[stream_ptr++];
00312 pixel_ptr += pixel_skip;
00313 pixel_countdown -= pixel_skip;
00314 byte_run = (signed char)(buf[stream_ptr++]);
00315 if (byte_run > 0) {
00316 CHECK_PIXEL_PTR(byte_run);
00317 for (j = 0; j < byte_run; j++, pixel_countdown--) {
00318 palette_idx1 = buf[stream_ptr++];
00319 pixels[pixel_ptr++] = palette_idx1;
00320 }
00321 } else if (byte_run < 0) {
00322 byte_run = -byte_run;
00323 palette_idx1 = buf[stream_ptr++];
00324 CHECK_PIXEL_PTR(byte_run);
00325 for (j = 0; j < byte_run; j++, pixel_countdown--) {
00326 pixels[pixel_ptr++] = palette_idx1;
00327 }
00328 }
00329 }
00330 }
00331
00332 y_ptr += s->frame.linesize[0];
00333 compressed_lines--;
00334 }
00335 break;
00336
00337 case FLI_BLACK:
00338
00339 memset(pixels, 0,
00340 s->frame.linesize[0] * s->avctx->height);
00341 break;
00342
00343 case FLI_BRUN:
00344
00345
00346 y_ptr = 0;
00347 for (lines = 0; lines < s->avctx->height; lines++) {
00348 pixel_ptr = y_ptr;
00349
00350
00351 stream_ptr++;
00352 pixel_countdown = s->avctx->width;
00353 while (pixel_countdown > 0) {
00354 byte_run = (signed char)(buf[stream_ptr++]);
00355 if (byte_run > 0) {
00356 palette_idx1 = buf[stream_ptr++];
00357 CHECK_PIXEL_PTR(byte_run);
00358 for (j = 0; j < byte_run; j++) {
00359 pixels[pixel_ptr++] = palette_idx1;
00360 pixel_countdown--;
00361 if (pixel_countdown < 0)
00362 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
00363 pixel_countdown, lines);
00364 }
00365 } else {
00366 byte_run = -byte_run;
00367 CHECK_PIXEL_PTR(byte_run);
00368 for (j = 0; j < byte_run; j++) {
00369 palette_idx1 = buf[stream_ptr++];
00370 pixels[pixel_ptr++] = palette_idx1;
00371 pixel_countdown--;
00372 if (pixel_countdown < 0)
00373 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
00374 pixel_countdown, lines);
00375 }
00376 }
00377 }
00378
00379 y_ptr += s->frame.linesize[0];
00380 }
00381 break;
00382
00383 case FLI_COPY:
00384
00385 if (chunk_size - 6 > s->avctx->width * s->avctx->height) {
00386 av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
00387 "bigger than image, skipping chunk\n", chunk_size - 6);
00388 stream_ptr += chunk_size - 6;
00389 } else {
00390 for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
00391 y_ptr += s->frame.linesize[0]) {
00392 memcpy(&pixels[y_ptr], &buf[stream_ptr],
00393 s->avctx->width);
00394 stream_ptr += s->avctx->width;
00395 }
00396 }
00397 break;
00398
00399 case FLI_MINI:
00400
00401 stream_ptr += chunk_size - 6;
00402 break;
00403
00404 default:
00405 av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
00406 break;
00407 }
00408
00409 frame_size -= chunk_size;
00410 num_chunks--;
00411 }
00412
00413
00414
00415 if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1))
00416 av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
00417 "and final chunk ptr = %d\n", buf_size, stream_ptr);
00418
00419
00420 memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
00421 if (s->new_palette) {
00422 s->frame.palette_has_changed = 1;
00423 s->new_palette = 0;
00424 }
00425
00426 *data_size=sizeof(AVFrame);
00427 *(AVFrame*)data = s->frame;
00428
00429 return buf_size;
00430 }
00431
00432 static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
00433 void *data, int *data_size,
00434 const uint8_t *buf, int buf_size)
00435 {
00436
00437
00438 FlicDecodeContext *s = avctx->priv_data;
00439
00440 int stream_ptr = 0;
00441 int pixel_ptr;
00442 unsigned char palette_idx1;
00443
00444 unsigned int frame_size;
00445 int num_chunks;
00446
00447 unsigned int chunk_size;
00448 int chunk_type;
00449
00450 int i, j;
00451
00452 int lines;
00453 int compressed_lines;
00454 signed short line_packets;
00455 int y_ptr;
00456 int byte_run;
00457 int pixel_skip;
00458 int pixel_countdown;
00459 unsigned char *pixels;
00460 int pixel;
00461 unsigned int pixel_limit;
00462
00463 s->frame.reference = 1;
00464 s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
00465 if (avctx->reget_buffer(avctx, &s->frame) < 0) {
00466 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00467 return -1;
00468 }
00469
00470 pixels = s->frame.data[0];
00471 pixel_limit = s->avctx->height * s->frame.linesize[0];
00472
00473 frame_size = AV_RL32(&buf[stream_ptr]);
00474 stream_ptr += 6;
00475 num_chunks = AV_RL16(&buf[stream_ptr]);
00476 stream_ptr += 10;
00477
00478 frame_size -= 16;
00479
00480
00481 while ((frame_size > 0) && (num_chunks > 0)) {
00482 chunk_size = AV_RL32(&buf[stream_ptr]);
00483 stream_ptr += 4;
00484 chunk_type = AV_RL16(&buf[stream_ptr]);
00485 stream_ptr += 2;
00486
00487 switch (chunk_type) {
00488 case FLI_256_COLOR:
00489 case FLI_COLOR:
00490
00491
00492
00493 stream_ptr = stream_ptr + chunk_size - 6;
00494 break;
00495
00496 case FLI_DELTA:
00497 case FLI_DTA_LC:
00498 y_ptr = 0;
00499 compressed_lines = AV_RL16(&buf[stream_ptr]);
00500 stream_ptr += 2;
00501 while (compressed_lines > 0) {
00502 line_packets = AV_RL16(&buf[stream_ptr]);
00503 stream_ptr += 2;
00504 if (line_packets < 0) {
00505 line_packets = -line_packets;
00506 y_ptr += line_packets * s->frame.linesize[0];
00507 } else {
00508 compressed_lines--;
00509 pixel_ptr = y_ptr;
00510 CHECK_PIXEL_PTR(0);
00511 pixel_countdown = s->avctx->width;
00512 for (i = 0; i < line_packets; i++) {
00513
00514 pixel_skip = buf[stream_ptr++];
00515 pixel_ptr += (pixel_skip*2);
00516 pixel_countdown -= pixel_skip;
00517 byte_run = (signed char)(buf[stream_ptr++]);
00518 if (byte_run < 0) {
00519 byte_run = -byte_run;
00520 pixel = AV_RL16(&buf[stream_ptr]);
00521 stream_ptr += 2;
00522 CHECK_PIXEL_PTR(2 * byte_run);
00523 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
00524 *((signed short*)(&pixels[pixel_ptr])) = pixel;
00525 pixel_ptr += 2;
00526 }
00527 } else {
00528 CHECK_PIXEL_PTR(2 * byte_run);
00529 for (j = 0; j < byte_run; j++, pixel_countdown--) {
00530 *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[stream_ptr]);
00531 stream_ptr += 2;
00532 pixel_ptr += 2;
00533 }
00534 }
00535 }
00536
00537 y_ptr += s->frame.linesize[0];
00538 }
00539 }
00540 break;
00541
00542 case FLI_LC:
00543 av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-paletised FLC\n");
00544 stream_ptr = stream_ptr + chunk_size - 6;
00545 break;
00546
00547 case FLI_BLACK:
00548
00549 memset(pixels, 0x0000,
00550 s->frame.linesize[0] * s->avctx->height);
00551 break;
00552
00553 case FLI_BRUN:
00554 y_ptr = 0;
00555 for (lines = 0; lines < s->avctx->height; lines++) {
00556 pixel_ptr = y_ptr;
00557
00558
00559 stream_ptr++;
00560 pixel_countdown = (s->avctx->width * 2);
00561
00562 while (pixel_countdown > 0) {
00563 byte_run = (signed char)(buf[stream_ptr++]);
00564 if (byte_run > 0) {
00565 palette_idx1 = buf[stream_ptr++];
00566 CHECK_PIXEL_PTR(byte_run);
00567 for (j = 0; j < byte_run; j++) {
00568 pixels[pixel_ptr++] = palette_idx1;
00569 pixel_countdown--;
00570 if (pixel_countdown < 0)
00571 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) (linea%d)\n",
00572 pixel_countdown, lines);
00573 }
00574 } else {
00575 byte_run = -byte_run;
00576 CHECK_PIXEL_PTR(byte_run);
00577 for (j = 0; j < byte_run; j++) {
00578 palette_idx1 = buf[stream_ptr++];
00579 pixels[pixel_ptr++] = palette_idx1;
00580 pixel_countdown--;
00581 if (pixel_countdown < 0)
00582 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
00583 pixel_countdown, lines);
00584 }
00585 }
00586 }
00587
00588
00589
00590
00591
00592
00593 #ifdef WORDS_BIGENDIAN
00594 pixel_ptr = y_ptr;
00595 pixel_countdown = s->avctx->width;
00596 while (pixel_countdown > 0) {
00597 *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[pixel_ptr]);
00598 pixel_ptr += 2;
00599 }
00600 #endif
00601 y_ptr += s->frame.linesize[0];
00602 }
00603 break;
00604
00605 case FLI_DTA_BRUN:
00606 y_ptr = 0;
00607 for (lines = 0; lines < s->avctx->height; lines++) {
00608 pixel_ptr = y_ptr;
00609
00610
00611 stream_ptr++;
00612 pixel_countdown = s->avctx->width;
00613
00614 while (pixel_countdown > 0) {
00615 byte_run = (signed char)(buf[stream_ptr++]);
00616 if (byte_run > 0) {
00617 pixel = AV_RL16(&buf[stream_ptr]);
00618 stream_ptr += 2;
00619 CHECK_PIXEL_PTR(2 * byte_run);
00620 for (j = 0; j < byte_run; j++) {
00621 *((signed short*)(&pixels[pixel_ptr])) = pixel;
00622 pixel_ptr += 2;
00623 pixel_countdown--;
00624 if (pixel_countdown < 0)
00625 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
00626 pixel_countdown);
00627 }
00628 } else {
00629 byte_run = -byte_run;
00630 CHECK_PIXEL_PTR(2 * byte_run);
00631 for (j = 0; j < byte_run; j++) {
00632 *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[stream_ptr]);
00633 stream_ptr += 2;
00634 pixel_ptr += 2;
00635 pixel_countdown--;
00636 if (pixel_countdown < 0)
00637 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
00638 pixel_countdown);
00639 }
00640 }
00641 }
00642
00643 y_ptr += s->frame.linesize[0];
00644 }
00645 break;
00646
00647 case FLI_COPY:
00648 case FLI_DTA_COPY:
00649
00650 if (chunk_size - 6 > (unsigned int)(s->avctx->width * s->avctx->height)*2) {
00651 av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
00652 "bigger than image, skipping chunk\n", chunk_size - 6);
00653 stream_ptr += chunk_size - 6;
00654 } else {
00655
00656 for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
00657 y_ptr += s->frame.linesize[0]) {
00658
00659 pixel_countdown = s->avctx->width;
00660 pixel_ptr = 0;
00661 while (pixel_countdown > 0) {
00662 *((signed short*)(&pixels[y_ptr + pixel_ptr])) = AV_RL16(&buf[stream_ptr+pixel_ptr]);
00663 pixel_ptr += 2;
00664 pixel_countdown--;
00665 }
00666 stream_ptr += s->avctx->width*2;
00667 }
00668 }
00669 break;
00670
00671 case FLI_MINI:
00672
00673 stream_ptr += chunk_size - 6;
00674 break;
00675
00676 default:
00677 av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
00678 break;
00679 }
00680
00681 frame_size -= chunk_size;
00682 num_chunks--;
00683 }
00684
00685
00686
00687 if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1))
00688 av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
00689 "and final chunk ptr = %d\n", buf_size, stream_ptr);
00690
00691
00692 *data_size=sizeof(AVFrame);
00693 *(AVFrame*)data = s->frame;
00694
00695 return buf_size;
00696 }
00697
00698 static int flic_decode_frame_24BPP(AVCodecContext *avctx,
00699 void *data, int *data_size,
00700 const uint8_t *buf, int buf_size)
00701 {
00702 av_log(avctx, AV_LOG_ERROR, "24Bpp FLC Unsupported due to lack of test files.\n");
00703 return -1;
00704 }
00705
00706 static int flic_decode_frame(AVCodecContext *avctx,
00707 void *data, int *data_size,
00708 const uint8_t *buf, int buf_size)
00709 {
00710 if (avctx->pix_fmt == PIX_FMT_PAL8) {
00711 return flic_decode_frame_8BPP(avctx, data, data_size,
00712 buf, buf_size);
00713 }
00714 else if ((avctx->pix_fmt == PIX_FMT_RGB555) ||
00715 (avctx->pix_fmt == PIX_FMT_RGB565)) {
00716 return flic_decode_frame_15_16BPP(avctx, data, data_size,
00717 buf, buf_size);
00718 }
00719 else if (avctx->pix_fmt == PIX_FMT_BGR24) {
00720 return flic_decode_frame_24BPP(avctx, data, data_size,
00721 buf, buf_size);
00722 }
00723
00724
00725
00726
00727
00728 av_log(avctx, AV_LOG_ERROR, "Unknown FLC format, my science cannot explain how this happened.\n");
00729 return -1;
00730 }
00731
00732
00733 static int flic_decode_end(AVCodecContext *avctx)
00734 {
00735 FlicDecodeContext *s = avctx->priv_data;
00736
00737 if (s->frame.data[0])
00738 avctx->release_buffer(avctx, &s->frame);
00739
00740 return 0;
00741 }
00742
00743 AVCodec flic_decoder = {
00744 "flic",
00745 CODEC_TYPE_VIDEO,
00746 CODEC_ID_FLIC,
00747 sizeof(FlicDecodeContext),
00748 flic_decode_init,
00749 NULL,
00750 flic_decode_end,
00751 flic_decode_frame,
00752 CODEC_CAP_DR1,
00753 NULL,
00754 NULL,
00755 NULL,
00756 NULL
00757 };