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 unsigned 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 pixel_ptr= y_ptr + s->frame.linesize[0] - 1;
00257 CHECK_PIXEL_PTR(0);
00258 pixels[pixel_ptr] = line_packets & 0xff;
00259 } else {
00260 compressed_lines--;
00261 pixel_ptr = y_ptr;
00262 CHECK_PIXEL_PTR(0);
00263 pixel_countdown = s->avctx->width;
00264 for (i = 0; i < line_packets; i++) {
00265
00266 pixel_skip = buf[stream_ptr++];
00267 pixel_ptr += pixel_skip;
00268 pixel_countdown -= pixel_skip;
00269 byte_run = (signed char)(buf[stream_ptr++]);
00270 if (byte_run < 0) {
00271 byte_run = -byte_run;
00272 palette_idx1 = buf[stream_ptr++];
00273 palette_idx2 = buf[stream_ptr++];
00274 CHECK_PIXEL_PTR(byte_run * 2);
00275 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
00276 pixels[pixel_ptr++] = palette_idx1;
00277 pixels[pixel_ptr++] = palette_idx2;
00278 }
00279 } else {
00280 CHECK_PIXEL_PTR(byte_run * 2);
00281 for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
00282 palette_idx1 = buf[stream_ptr++];
00283 pixels[pixel_ptr++] = palette_idx1;
00284 }
00285 }
00286 }
00287
00288 y_ptr += s->frame.linesize[0];
00289 }
00290 }
00291 break;
00292
00293 case FLI_LC:
00294
00295 starting_line = AV_RL16(&buf[stream_ptr]);
00296 stream_ptr += 2;
00297 y_ptr = 0;
00298 y_ptr += starting_line * s->frame.linesize[0];
00299
00300 compressed_lines = AV_RL16(&buf[stream_ptr]);
00301 stream_ptr += 2;
00302 while (compressed_lines > 0) {
00303 pixel_ptr = y_ptr;
00304 CHECK_PIXEL_PTR(0);
00305 pixel_countdown = s->avctx->width;
00306 line_packets = buf[stream_ptr++];
00307 if (line_packets > 0) {
00308 for (i = 0; i < line_packets; i++) {
00309
00310 pixel_skip = buf[stream_ptr++];
00311 pixel_ptr += pixel_skip;
00312 pixel_countdown -= pixel_skip;
00313 byte_run = (signed char)(buf[stream_ptr++]);
00314 if (byte_run > 0) {
00315 CHECK_PIXEL_PTR(byte_run);
00316 for (j = 0; j < byte_run; j++, pixel_countdown--) {
00317 palette_idx1 = buf[stream_ptr++];
00318 pixels[pixel_ptr++] = palette_idx1;
00319 }
00320 } else if (byte_run < 0) {
00321 byte_run = -byte_run;
00322 palette_idx1 = buf[stream_ptr++];
00323 CHECK_PIXEL_PTR(byte_run);
00324 for (j = 0; j < byte_run; j++, pixel_countdown--) {
00325 pixels[pixel_ptr++] = palette_idx1;
00326 }
00327 }
00328 }
00329 }
00330
00331 y_ptr += s->frame.linesize[0];
00332 compressed_lines--;
00333 }
00334 break;
00335
00336 case FLI_BLACK:
00337
00338 memset(pixels, 0,
00339 s->frame.linesize[0] * s->avctx->height);
00340 break;
00341
00342 case FLI_BRUN:
00343
00344
00345 y_ptr = 0;
00346 for (lines = 0; lines < s->avctx->height; lines++) {
00347 pixel_ptr = y_ptr;
00348
00349
00350 stream_ptr++;
00351 pixel_countdown = s->avctx->width;
00352 while (pixel_countdown > 0) {
00353 byte_run = (signed char)(buf[stream_ptr++]);
00354 if (byte_run > 0) {
00355 palette_idx1 = buf[stream_ptr++];
00356 CHECK_PIXEL_PTR(byte_run);
00357 for (j = 0; j < byte_run; j++) {
00358 pixels[pixel_ptr++] = palette_idx1;
00359 pixel_countdown--;
00360 if (pixel_countdown < 0)
00361 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
00362 pixel_countdown, lines);
00363 }
00364 } else {
00365 byte_run = -byte_run;
00366 CHECK_PIXEL_PTR(byte_run);
00367 for (j = 0; j < byte_run; j++) {
00368 palette_idx1 = buf[stream_ptr++];
00369 pixels[pixel_ptr++] = palette_idx1;
00370 pixel_countdown--;
00371 if (pixel_countdown < 0)
00372 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
00373 pixel_countdown, lines);
00374 }
00375 }
00376 }
00377
00378 y_ptr += s->frame.linesize[0];
00379 }
00380 break;
00381
00382 case FLI_COPY:
00383
00384 if (chunk_size - 6 > s->avctx->width * s->avctx->height) {
00385 av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
00386 "bigger than image, skipping chunk\n", chunk_size - 6);
00387 stream_ptr += chunk_size - 6;
00388 } else {
00389 for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
00390 y_ptr += s->frame.linesize[0]) {
00391 memcpy(&pixels[y_ptr], &buf[stream_ptr],
00392 s->avctx->width);
00393 stream_ptr += s->avctx->width;
00394 }
00395 }
00396 break;
00397
00398 case FLI_MINI:
00399
00400 stream_ptr += chunk_size - 6;
00401 break;
00402
00403 default:
00404 av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
00405 break;
00406 }
00407
00408 frame_size -= chunk_size;
00409 num_chunks--;
00410 }
00411
00412
00413
00414 if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1))
00415 av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
00416 "and final chunk ptr = %d\n", buf_size, stream_ptr);
00417
00418
00419 memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
00420 if (s->new_palette) {
00421 s->frame.palette_has_changed = 1;
00422 s->new_palette = 0;
00423 }
00424
00425 *data_size=sizeof(AVFrame);
00426 *(AVFrame*)data = s->frame;
00427
00428 return buf_size;
00429 }
00430
00431 static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
00432 void *data, int *data_size,
00433 const uint8_t *buf, int buf_size)
00434 {
00435
00436
00437 FlicDecodeContext *s = avctx->priv_data;
00438
00439 int stream_ptr = 0;
00440 int pixel_ptr;
00441 unsigned char palette_idx1;
00442
00443 unsigned int frame_size;
00444 int num_chunks;
00445
00446 unsigned int chunk_size;
00447 int chunk_type;
00448
00449 int i, j;
00450
00451 int lines;
00452 int compressed_lines;
00453 signed short line_packets;
00454 int y_ptr;
00455 int byte_run;
00456 int pixel_skip;
00457 int pixel_countdown;
00458 unsigned char *pixels;
00459 int pixel;
00460 unsigned int pixel_limit;
00461
00462 s->frame.reference = 1;
00463 s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
00464 if (avctx->reget_buffer(avctx, &s->frame) < 0) {
00465 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00466 return -1;
00467 }
00468
00469 pixels = s->frame.data[0];
00470 pixel_limit = s->avctx->height * s->frame.linesize[0];
00471
00472 frame_size = AV_RL32(&buf[stream_ptr]);
00473 stream_ptr += 6;
00474 num_chunks = AV_RL16(&buf[stream_ptr]);
00475 stream_ptr += 10;
00476
00477 frame_size -= 16;
00478
00479
00480 while ((frame_size > 0) && (num_chunks > 0)) {
00481 chunk_size = AV_RL32(&buf[stream_ptr]);
00482 stream_ptr += 4;
00483 chunk_type = AV_RL16(&buf[stream_ptr]);
00484 stream_ptr += 2;
00485
00486 switch (chunk_type) {
00487 case FLI_256_COLOR:
00488 case FLI_COLOR:
00489
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 #if HAVE_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 AVPacket *avpkt)
00709 {
00710 const uint8_t *buf = avpkt->data;
00711 int buf_size = avpkt->size;
00712 if (avctx->pix_fmt == PIX_FMT_PAL8) {
00713 return flic_decode_frame_8BPP(avctx, data, data_size,
00714 buf, buf_size);
00715 }
00716 else if ((avctx->pix_fmt == PIX_FMT_RGB555) ||
00717 (avctx->pix_fmt == PIX_FMT_RGB565)) {
00718 return flic_decode_frame_15_16BPP(avctx, data, data_size,
00719 buf, buf_size);
00720 }
00721 else if (avctx->pix_fmt == PIX_FMT_BGR24) {
00722 return flic_decode_frame_24BPP(avctx, data, data_size,
00723 buf, buf_size);
00724 }
00725
00726
00727
00728
00729
00730 av_log(avctx, AV_LOG_ERROR, "Unknown FLC format, my science cannot explain how this happened.\n");
00731 return -1;
00732 }
00733
00734
00735 static av_cold int flic_decode_end(AVCodecContext *avctx)
00736 {
00737 FlicDecodeContext *s = avctx->priv_data;
00738
00739 if (s->frame.data[0])
00740 avctx->release_buffer(avctx, &s->frame);
00741
00742 return 0;
00743 }
00744
00745 AVCodec flic_decoder = {
00746 "flic",
00747 AVMEDIA_TYPE_VIDEO,
00748 CODEC_ID_FLIC,
00749 sizeof(FlicDecodeContext),
00750 flic_decode_init,
00751 NULL,
00752 flic_decode_end,
00753 flic_decode_frame,
00754 CODEC_CAP_DR1,
00755 NULL,
00756 NULL,
00757 NULL,
00758 NULL,
00759 .long_name = NULL_IF_CONFIG_SMALL("Autodesk Animator Flic video"),
00760 };