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 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
00494 stream_ptr = stream_ptr + chunk_size - 6;
00495 break;
00496
00497 case FLI_DELTA:
00498 case FLI_DTA_LC:
00499 y_ptr = 0;
00500 compressed_lines = AV_RL16(&buf[stream_ptr]);
00501 stream_ptr += 2;
00502 while (compressed_lines > 0) {
00503 line_packets = AV_RL16(&buf[stream_ptr]);
00504 stream_ptr += 2;
00505 if (line_packets < 0) {
00506 line_packets = -line_packets;
00507 y_ptr += line_packets * s->frame.linesize[0];
00508 } else {
00509 compressed_lines--;
00510 pixel_ptr = y_ptr;
00511 CHECK_PIXEL_PTR(0);
00512 pixel_countdown = s->avctx->width;
00513 for (i = 0; i < line_packets; i++) {
00514
00515 pixel_skip = buf[stream_ptr++];
00516 pixel_ptr += (pixel_skip*2);
00517 pixel_countdown -= pixel_skip;
00518 byte_run = (signed char)(buf[stream_ptr++]);
00519 if (byte_run < 0) {
00520 byte_run = -byte_run;
00521 pixel = AV_RL16(&buf[stream_ptr]);
00522 stream_ptr += 2;
00523 CHECK_PIXEL_PTR(2 * byte_run);
00524 for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
00525 *((signed short*)(&pixels[pixel_ptr])) = pixel;
00526 pixel_ptr += 2;
00527 }
00528 } else {
00529 CHECK_PIXEL_PTR(2 * byte_run);
00530 for (j = 0; j < byte_run; j++, pixel_countdown--) {
00531 *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[stream_ptr]);
00532 stream_ptr += 2;
00533 pixel_ptr += 2;
00534 }
00535 }
00536 }
00537
00538 y_ptr += s->frame.linesize[0];
00539 }
00540 }
00541 break;
00542
00543 case FLI_LC:
00544 av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-paletised FLC\n");
00545 stream_ptr = stream_ptr + chunk_size - 6;
00546 break;
00547
00548 case FLI_BLACK:
00549
00550 memset(pixels, 0x0000,
00551 s->frame.linesize[0] * s->avctx->height);
00552 break;
00553
00554 case FLI_BRUN:
00555 y_ptr = 0;
00556 for (lines = 0; lines < s->avctx->height; lines++) {
00557 pixel_ptr = y_ptr;
00558
00559
00560 stream_ptr++;
00561 pixel_countdown = (s->avctx->width * 2);
00562
00563 while (pixel_countdown > 0) {
00564 byte_run = (signed char)(buf[stream_ptr++]);
00565 if (byte_run > 0) {
00566 palette_idx1 = buf[stream_ptr++];
00567 CHECK_PIXEL_PTR(byte_run);
00568 for (j = 0; j < byte_run; j++) {
00569 pixels[pixel_ptr++] = palette_idx1;
00570 pixel_countdown--;
00571 if (pixel_countdown < 0)
00572 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) (linea%d)\n",
00573 pixel_countdown, lines);
00574 }
00575 } else {
00576 byte_run = -byte_run;
00577 CHECK_PIXEL_PTR(byte_run);
00578 for (j = 0; j < byte_run; j++) {
00579 palette_idx1 = buf[stream_ptr++];
00580 pixels[pixel_ptr++] = palette_idx1;
00581 pixel_countdown--;
00582 if (pixel_countdown < 0)
00583 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
00584 pixel_countdown, lines);
00585 }
00586 }
00587 }
00588
00589
00590
00591
00592
00593
00594 #ifdef WORDS_BIGENDIAN
00595 pixel_ptr = y_ptr;
00596 pixel_countdown = s->avctx->width;
00597 while (pixel_countdown > 0) {
00598 *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[pixel_ptr]);
00599 pixel_ptr += 2;
00600 }
00601 #endif
00602 y_ptr += s->frame.linesize[0];
00603 }
00604 break;
00605
00606 case FLI_DTA_BRUN:
00607 y_ptr = 0;
00608 for (lines = 0; lines < s->avctx->height; lines++) {
00609 pixel_ptr = y_ptr;
00610
00611
00612 stream_ptr++;
00613 pixel_countdown = s->avctx->width;
00614
00615 while (pixel_countdown > 0) {
00616 byte_run = (signed char)(buf[stream_ptr++]);
00617 if (byte_run > 0) {
00618 pixel = AV_RL16(&buf[stream_ptr]);
00619 stream_ptr += 2;
00620 CHECK_PIXEL_PTR(2 * byte_run);
00621 for (j = 0; j < byte_run; j++) {
00622 *((signed short*)(&pixels[pixel_ptr])) = pixel;
00623 pixel_ptr += 2;
00624 pixel_countdown--;
00625 if (pixel_countdown < 0)
00626 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
00627 pixel_countdown);
00628 }
00629 } else {
00630 byte_run = -byte_run;
00631 CHECK_PIXEL_PTR(2 * byte_run);
00632 for (j = 0; j < byte_run; j++) {
00633 *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[stream_ptr]);
00634 stream_ptr += 2;
00635 pixel_ptr += 2;
00636 pixel_countdown--;
00637 if (pixel_countdown < 0)
00638 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
00639 pixel_countdown);
00640 }
00641 }
00642 }
00643
00644 y_ptr += s->frame.linesize[0];
00645 }
00646 break;
00647
00648 case FLI_COPY:
00649 case FLI_DTA_COPY:
00650
00651 if (chunk_size - 6 > (unsigned int)(s->avctx->width * s->avctx->height)*2) {
00652 av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
00653 "bigger than image, skipping chunk\n", chunk_size - 6);
00654 stream_ptr += chunk_size - 6;
00655 } else {
00656
00657 for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
00658 y_ptr += s->frame.linesize[0]) {
00659
00660 pixel_countdown = s->avctx->width;
00661 pixel_ptr = 0;
00662 while (pixel_countdown > 0) {
00663 *((signed short*)(&pixels[y_ptr + pixel_ptr])) = AV_RL16(&buf[stream_ptr+pixel_ptr]);
00664 pixel_ptr += 2;
00665 pixel_countdown--;
00666 }
00667 stream_ptr += s->avctx->width*2;
00668 }
00669 }
00670 break;
00671
00672 case FLI_MINI:
00673
00674 stream_ptr += chunk_size - 6;
00675 break;
00676
00677 default:
00678 av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
00679 break;
00680 }
00681
00682 frame_size -= chunk_size;
00683 num_chunks--;
00684 }
00685
00686
00687
00688 if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1))
00689 av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
00690 "and final chunk ptr = %d\n", buf_size, stream_ptr);
00691
00692
00693 *data_size=sizeof(AVFrame);
00694 *(AVFrame*)data = s->frame;
00695
00696 return buf_size;
00697 }
00698
00699 static int flic_decode_frame_24BPP(AVCodecContext *avctx,
00700 void *data, int *data_size,
00701 const uint8_t *buf, int buf_size)
00702 {
00703 av_log(avctx, AV_LOG_ERROR, "24Bpp FLC Unsupported due to lack of test files.\n");
00704 return -1;
00705 }
00706
00707 static int flic_decode_frame(AVCodecContext *avctx,
00708 void *data, int *data_size,
00709 const uint8_t *buf, int buf_size)
00710 {
00711 if (avctx->pix_fmt == PIX_FMT_PAL8) {
00712 return flic_decode_frame_8BPP(avctx, data, data_size,
00713 buf, buf_size);
00714 }
00715 else if ((avctx->pix_fmt == PIX_FMT_RGB555) ||
00716 (avctx->pix_fmt == PIX_FMT_RGB565)) {
00717 return flic_decode_frame_15_16BPP(avctx, data, data_size,
00718 buf, buf_size);
00719 }
00720 else if (avctx->pix_fmt == PIX_FMT_BGR24) {
00721 return flic_decode_frame_24BPP(avctx, data, data_size,
00722 buf, buf_size);
00723 }
00724
00725
00726
00727
00728
00729 av_log(avctx, AV_LOG_ERROR, "Unknown FLC format, my science cannot explain how this happened.\n");
00730 return -1;
00731 }
00732
00733
00734 static av_cold int flic_decode_end(AVCodecContext *avctx)
00735 {
00736 FlicDecodeContext *s = avctx->priv_data;
00737
00738 if (s->frame.data[0])
00739 avctx->release_buffer(avctx, &s->frame);
00740
00741 return 0;
00742 }
00743
00744 AVCodec flic_decoder = {
00745 "flic",
00746 CODEC_TYPE_VIDEO,
00747 CODEC_ID_FLIC,
00748 sizeof(FlicDecodeContext),
00749 flic_decode_init,
00750 NULL,
00751 flic_decode_end,
00752 flic_decode_frame,
00753 CODEC_CAP_DR1,
00754 NULL,
00755 NULL,
00756 NULL,
00757 NULL,
00758 .long_name = NULL_IF_CONFIG_SMALL("Autodesk Animator Flic video"),
00759 };