flicvideo.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:14k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*
  2.  * FLI/FLC Animation Video Decoder
  3.  * Copyright (C) 2003, 2004 the ffmpeg project
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Lesser General Public
  7.  * License as published by the Free Software Foundation; either
  8.  * version 2 of the License, or (at your option) any later version.
  9.  *
  10.  * This library is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Lesser General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU Lesser General Public
  16.  * License along with this library; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  *
  19.  */
  20. /**
  21.  * @file flic.c
  22.  * Autodesk Animator FLI/FLC Video Decoder
  23.  * by Mike Melanson (melanson@pcisys.net)
  24.  * for more information on the .fli/.flc file format and all of its many
  25.  * variations, visit:
  26.  *   http://www.compuphase.com/flic.htm
  27.  *
  28.  * This decoder outputs PAL8 colorspace data. To use this decoder, be
  29.  * sure that your demuxer sends the FLI file header to the decoder via
  30.  * the extradata chunk in AVCodecContext. The chunk should be 128 bytes
  31.  * large. The only exception is for FLI files from the game "Magic Carpet",
  32.  * in which the header is only 12 bytes.
  33.  */
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <unistd.h>
  38. #include "common.h"
  39. #include "avcodec.h"
  40. #include "bswap.h"
  41. #define FLI_256_COLOR 4
  42. #define FLI_DELTA     7
  43. #define FLI_COLOR     11
  44. #define FLI_LC        12
  45. #define FLI_BLACK     13
  46. #define FLI_BRUN      15
  47. #define FLI_COPY      16
  48. #define FLI_MINI      18
  49. #define CHECK_PIXEL_PTR(n) 
  50.     if (pixel_ptr + n > pixel_limit) { 
  51.         av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr >= pixel_limit (%d >= %d)n", 
  52.         pixel_ptr + n, pixel_limit); 
  53.         return -1; 
  54.     } 
  55. typedef struct FlicDecodeContext {
  56.     AVCodecContext *avctx;
  57.     AVFrame frame;
  58.     unsigned int palette[256];
  59.     int new_palette;
  60.     int fli_type;  /* either 0xAF11 or 0xAF12, affects palette resolution */
  61. } FlicDecodeContext;
  62. static int flic_decode_init(AVCodecContext *avctx)
  63. {
  64.     FlicDecodeContext *s = (FlicDecodeContext *)avctx->priv_data;
  65.     unsigned char *fli_header = (unsigned char *)avctx->extradata;
  66.     s->avctx = avctx;
  67.     avctx->pix_fmt = PIX_FMT_PAL8;
  68.     avctx->has_b_frames = 0;
  69.     if (s->avctx->extradata_size == 12) {
  70.         /* special case for magic carpet FLIs */
  71.         s->fli_type = 0xAF13;
  72.     } else if (s->avctx->extradata_size == 128) {
  73.         s->fli_type = LE_16(&fli_header[4]);
  74.     } else {
  75.         av_log(avctx, AV_LOG_ERROR, "Expected extradata of 12 or 128 bytesn");
  76.         return -1;
  77.     }
  78.     s->frame.data[0] = NULL;
  79.     s->new_palette = 0;
  80.     return 0;
  81. }
  82. static int flic_decode_frame(AVCodecContext *avctx,
  83.                              void *data, int *data_size,
  84.                              uint8_t *buf, int buf_size)
  85. {
  86.     FlicDecodeContext *s = (FlicDecodeContext *)avctx->priv_data;
  87.     int stream_ptr = 0;
  88.     int stream_ptr_after_color_chunk;
  89.     int pixel_ptr;
  90.     int palette_ptr;
  91.     unsigned char palette_idx1;
  92.     unsigned char palette_idx2;
  93.     unsigned int frame_size;
  94.     int num_chunks;
  95.     unsigned int chunk_size;
  96.     int chunk_type;
  97.     int i, j;
  98.     int color_packets;
  99.     int color_changes;
  100.     int color_shift;
  101.     unsigned char r, g, b;
  102.     int lines;
  103.     int compressed_lines;
  104.     int starting_line;
  105.     signed short line_packets;
  106.     int y_ptr;
  107.     signed char byte_run;
  108.     int pixel_skip;
  109.     int pixel_countdown;
  110.     unsigned char *pixels;
  111.     int pixel_limit;
  112.     s->frame.reference = 1;
  113.     s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
  114.     if (avctx->reget_buffer(avctx, &s->frame) < 0) {
  115.         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failedn");
  116.         return -1;
  117.     }
  118.     pixels = s->frame.data[0];
  119.     pixel_limit = s->avctx->height * s->frame.linesize[0];
  120.     frame_size = LE_32(&buf[stream_ptr]);
  121.     stream_ptr += 6;  /* skip the magic number */
  122.     num_chunks = LE_16(&buf[stream_ptr]);
  123.     stream_ptr += 10;  /* skip padding */
  124.     frame_size -= 16;
  125.     /* iterate through the chunks */
  126.     while ((frame_size > 0) && (num_chunks > 0)) {
  127.         chunk_size = LE_32(&buf[stream_ptr]);
  128.         stream_ptr += 4;
  129.         chunk_type = LE_16(&buf[stream_ptr]);
  130.         stream_ptr += 2;
  131.         switch (chunk_type) {
  132.         case FLI_256_COLOR:
  133.         case FLI_COLOR:
  134.             stream_ptr_after_color_chunk = stream_ptr + chunk_size - 6;
  135.             s->new_palette = 1;
  136.             /* check special case: If this file is from the Magic Carpet 
  137.              * game and uses 6-bit colors even though it reports 256-color 
  138.              * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during
  139.              * initialization) */
  140.             if ((chunk_type == FLI_256_COLOR) && (s->fli_type != 0xAF13))
  141.                 color_shift = 0;
  142.             else
  143.                 color_shift = 2;
  144.             /* set up the palette */
  145.             color_packets = LE_16(&buf[stream_ptr]);
  146.             stream_ptr += 2;
  147.             palette_ptr = 0;
  148.             for (i = 0; i < color_packets; i++) {
  149.                 /* first byte is how many colors to skip */
  150.                 palette_ptr += buf[stream_ptr++];
  151.                 /* next byte indicates how many entries to change */
  152.                 color_changes = buf[stream_ptr++];
  153.                 /* if there are 0 color changes, there are actually 256 */
  154.                 if (color_changes == 0)
  155.                     color_changes = 256;
  156.                 for (j = 0; j < color_changes; j++) {
  157.                     /* wrap around, for good measure */
  158.                     if ((unsigned)palette_ptr >= 256)
  159.                         palette_ptr = 0;
  160.                     r = buf[stream_ptr++] << color_shift;
  161.                     g = buf[stream_ptr++] << color_shift;
  162.                     b = buf[stream_ptr++] << color_shift;
  163.                     s->palette[palette_ptr++] = (r << 16) | (g << 8) | b;
  164.                 }
  165.             }
  166.             /* color chunks sometimes have weird 16-bit alignment issues;
  167.              * therefore, take the hardline approach and set the stream_ptr
  168.              * to the value calculated w.r.t. the size specified by the color
  169.              * chunk header */
  170.             stream_ptr = stream_ptr_after_color_chunk;
  171.             break;
  172.         case FLI_DELTA:
  173.             y_ptr = 0;
  174.             compressed_lines = LE_16(&buf[stream_ptr]);
  175.             stream_ptr += 2;
  176.             while (compressed_lines > 0) {
  177.                 line_packets = LE_16(&buf[stream_ptr]);
  178.                 stream_ptr += 2;
  179.                 if (line_packets < 0) {
  180.                     line_packets = -line_packets;
  181.                     y_ptr += line_packets * s->frame.linesize[0];
  182.                 } else {
  183.                     compressed_lines--;
  184.                     pixel_ptr = y_ptr;
  185.                     pixel_countdown = s->avctx->width;
  186.                     for (i = 0; i < line_packets; i++) {
  187.                         /* account for the skip bytes */
  188.                         pixel_skip = buf[stream_ptr++];
  189.                         pixel_ptr += pixel_skip;
  190.                         pixel_countdown -= pixel_skip;
  191.                         byte_run = buf[stream_ptr++];
  192.                         if (byte_run < 0) {
  193.                             byte_run = -byte_run;
  194.                             palette_idx1 = buf[stream_ptr++];
  195.                             palette_idx2 = buf[stream_ptr++];
  196.                             CHECK_PIXEL_PTR(byte_run);
  197.                             for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
  198.                                 pixels[pixel_ptr++] = palette_idx1;
  199.                                 pixels[pixel_ptr++] = palette_idx2;
  200.                             }
  201.                         } else {
  202.                             CHECK_PIXEL_PTR(byte_run * 2);
  203.                             for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
  204.                                 palette_idx1 = buf[stream_ptr++];
  205.                                 pixels[pixel_ptr++] = palette_idx1;
  206.                             }
  207.                         }
  208.                     }
  209.                     y_ptr += s->frame.linesize[0];
  210.                 }
  211.             }
  212.             break;
  213.         case FLI_LC:
  214.             /* line compressed */
  215.             starting_line = LE_16(&buf[stream_ptr]);
  216.             stream_ptr += 2;
  217.             y_ptr = 0;
  218.             y_ptr += starting_line * s->frame.linesize[0];
  219.             compressed_lines = LE_16(&buf[stream_ptr]);
  220.             stream_ptr += 2;
  221.             while (compressed_lines > 0) {
  222.                 pixel_ptr = y_ptr;
  223.                 pixel_countdown = s->avctx->width;
  224.                 line_packets = buf[stream_ptr++];
  225.                 if (line_packets > 0) {
  226.                     for (i = 0; i < line_packets; i++) {
  227.                         /* account for the skip bytes */
  228.                         pixel_skip = buf[stream_ptr++];
  229.                         pixel_ptr += pixel_skip;
  230.                         pixel_countdown -= pixel_skip;
  231.                         byte_run = buf[stream_ptr++];
  232.                         if (byte_run > 0) {
  233.                             CHECK_PIXEL_PTR(byte_run);
  234.                             for (j = 0; j < byte_run; j++, pixel_countdown--) {
  235.                                 palette_idx1 = buf[stream_ptr++];
  236.                                 pixels[pixel_ptr++] = palette_idx1;
  237.                             }
  238.                         } else {
  239.                             byte_run = -byte_run;
  240.                             palette_idx1 = buf[stream_ptr++];
  241.                             CHECK_PIXEL_PTR(byte_run);
  242.                             for (j = 0; j < byte_run; j++, pixel_countdown--) {
  243.                                 pixels[pixel_ptr++] = palette_idx1;
  244.                             }
  245.                         }
  246.                     }
  247.                 }
  248.                 y_ptr += s->frame.linesize[0];
  249.                 compressed_lines--;
  250.             }
  251.             break;
  252.         case FLI_BLACK:
  253.             /* set the whole frame to color 0 (which is usually black) */
  254.             memset(pixels, 0,
  255.                 s->frame.linesize[0] * s->avctx->height);
  256.             break;
  257.         case FLI_BRUN:
  258.             /* Byte run compression: This chunk type only occurs in the first
  259.              * FLI frame and it will update the entire frame. */
  260.             y_ptr = 0;
  261.             for (lines = 0; lines < s->avctx->height; lines++) {
  262.                 pixel_ptr = y_ptr;
  263.                 /* disregard the line packets; instead, iterate through all
  264.                  * pixels on a row */
  265.                 stream_ptr++;
  266.                 pixel_countdown = s->avctx->width;
  267.                 while (pixel_countdown > 0) {
  268.                     byte_run = buf[stream_ptr++];
  269.                     if (byte_run > 0) {
  270.                         palette_idx1 = buf[stream_ptr++];
  271.                         CHECK_PIXEL_PTR(byte_run);
  272.                         for (j = 0; j < byte_run; j++) {
  273.                             pixels[pixel_ptr++] = palette_idx1;
  274.                             pixel_countdown--;
  275.                             if (pixel_countdown < 0)
  276.                                 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)n",
  277.                                        pixel_countdown);
  278.                         }
  279.                     } else {  /* copy bytes if byte_run < 0 */
  280.                         byte_run = -byte_run;
  281.                         CHECK_PIXEL_PTR(byte_run);
  282.                         for (j = 0; j < byte_run; j++) {
  283.                             palette_idx1 = buf[stream_ptr++];
  284.                             pixels[pixel_ptr++] = palette_idx1;
  285.                             pixel_countdown--;
  286.                             if (pixel_countdown < 0)
  287.                                 av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)n",
  288.                                        pixel_countdown);
  289.                         }
  290.                     }
  291.                 }
  292.                 y_ptr += s->frame.linesize[0];
  293.             }
  294.             break;
  295.         case FLI_COPY:
  296.             /* copy the chunk (uncompressed frame) */
  297.             if (chunk_size - 6 > s->avctx->width * s->avctx->height) {
  298.                 av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " 
  299.                        "bigger than image, skipping chunkn", chunk_size - 6);
  300.                 stream_ptr += chunk_size - 6;
  301.             } else {
  302.                 for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
  303.                      y_ptr += s->frame.linesize[0]) {
  304.                     memcpy(&pixels[y_ptr], &buf[stream_ptr],
  305.                         s->avctx->width);
  306.                     stream_ptr += s->avctx->width;
  307.                 }
  308.             }
  309.             break;
  310.         case FLI_MINI:
  311.             /* some sort of a thumbnail? disregard this chunk... */
  312.             stream_ptr += chunk_size - 6;
  313.             break;
  314.         default:
  315.             av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %dn", chunk_type);
  316.             break;
  317.         }
  318.         frame_size -= chunk_size;
  319.         num_chunks--;
  320.     }
  321.     /* by the end of the chunk, the stream ptr should equal the frame
  322.      * size (minus 1, possibly); if it doesn't, issue a warning */
  323.     if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1))
  324.         av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " 
  325.                "and final chunk ptr = %dn", buf_size, stream_ptr);
  326.     /* make the palette available on the way out */
  327. //    if (s->new_palette) {
  328.     if (1) {
  329.         memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
  330.         s->frame.palette_has_changed = 1;
  331.         s->new_palette = 0;
  332.     }
  333.     *data_size=sizeof(AVFrame);
  334.     *(AVFrame*)data = s->frame;
  335.     return buf_size;
  336. }
  337. static int flic_decode_end(AVCodecContext *avctx)
  338. {
  339.     FlicDecodeContext *s = avctx->priv_data;
  340.     if (s->frame.data[0])
  341.         avctx->release_buffer(avctx, &s->frame);
  342.     return 0;
  343. }
  344. AVCodec flic_decoder = {
  345.     "flic",
  346.     CODEC_TYPE_VIDEO,
  347.     CODEC_ID_FLIC,
  348.     sizeof(FlicDecodeContext),
  349.     flic_decode_init,
  350.     NULL,
  351.     flic_decode_end,
  352.     flic_decode_frame,
  353.     CODEC_CAP_DR1,
  354.     NULL
  355. };