• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

libavcodec/dsicinav.c

Go to the documentation of this file.
00001 /*
00002  * Delphine Software International CIN Audio/Video Decoders
00003  * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net)
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00027 #include "avcodec.h"
00028 #include "bytestream.h"
00029 
00030 
00031 typedef enum CinVideoBitmapIndex {
00032     CIN_CUR_BMP = 0, /* current */
00033     CIN_PRE_BMP = 1, /* previous */
00034     CIN_INT_BMP = 2  /* intermediate */
00035 } CinVideoBitmapIndex;
00036 
00037 typedef struct CinVideoContext {
00038     AVCodecContext *avctx;
00039     AVFrame frame;
00040     unsigned int bitmap_size;
00041     uint32_t palette[256];
00042     uint8_t *bitmap_table[3];
00043 } CinVideoContext;
00044 
00045 typedef struct CinAudioContext {
00046     AVCodecContext *avctx;
00047     int initial_decode_frame;
00048     int delta;
00049 } CinAudioContext;
00050 
00051 
00052 /* table defining a geometric sequence with multiplier = 32767 ^ (1 / 128) */
00053 static const int16_t cinaudio_delta16_table[256] = {
00054          0,      0,      0,      0,      0,      0,      0,      0,
00055          0,      0,      0,      0,      0,      0,      0,      0,
00056          0,      0,      0, -30210, -27853, -25680, -23677, -21829,
00057     -20126, -18556, -17108, -15774, -14543, -13408, -12362, -11398,
00058     -10508,  -9689,  -8933,  -8236,  -7593,  -7001,  -6455,  -5951,
00059      -5487,  -5059,  -4664,  -4300,  -3964,  -3655,  -3370,  -3107,
00060      -2865,  -2641,  -2435,  -2245,  -2070,  -1908,  -1759,  -1622,
00061      -1495,  -1379,  -1271,  -1172,  -1080,   -996,   -918,   -847,
00062       -781,   -720,   -663,   -612,   -564,   -520,   -479,   -442,
00063       -407,   -376,   -346,   -319,   -294,   -271,   -250,   -230,
00064       -212,   -196,   -181,   -166,   -153,   -141,   -130,   -120,
00065       -111,   -102,    -94,    -87,    -80,    -74,    -68,    -62,
00066        -58,    -53,    -49,    -45,    -41,    -38,    -35,    -32,
00067        -30,    -27,    -25,    -23,    -21,    -20,    -18,    -17,
00068        -15,    -14,    -13,    -12,    -11,    -10,     -9,     -8,
00069         -7,     -6,     -5,     -4,     -3,     -2,     -1,      0,
00070          0,      1,      2,      3,      4,      5,      6,      7,
00071          8,      9,     10,     11,     12,     13,     14,     15,
00072         17,     18,     20,     21,     23,     25,     27,     30,
00073         32,     35,     38,     41,     45,     49,     53,     58,
00074         62,     68,     74,     80,     87,     94,    102,    111,
00075        120,    130,    141,    153,    166,    181,    196,    212,
00076        230,    250,    271,    294,    319,    346,    376,    407,
00077        442,    479,    520,    564,    612,    663,    720,    781,
00078        847,    918,    996,   1080,   1172,   1271,   1379,   1495,
00079       1622,   1759,   1908,   2070,   2245,   2435,   2641,   2865,
00080       3107,   3370,   3655,   3964,   4300,   4664,   5059,   5487,
00081       5951,   6455,   7001,   7593,   8236,   8933,   9689,  10508,
00082      11398,  12362,  13408,  14543,  15774,  17108,  18556,  20126,
00083      21829,  23677,  25680,  27853,  30210,      0,      0,      0,
00084          0,      0,      0,      0,      0,      0,      0,      0,
00085          0,      0,      0,      0,      0,      0,      0,      0
00086 };
00087 
00088 
00089 static av_cold int cinvideo_decode_init(AVCodecContext *avctx)
00090 {
00091     CinVideoContext *cin = avctx->priv_data;
00092     unsigned int i;
00093 
00094     cin->avctx = avctx;
00095     avctx->pix_fmt = PIX_FMT_PAL8;
00096 
00097     avcodec_get_frame_defaults(&cin->frame);
00098     cin->frame.data[0] = NULL;
00099 
00100     cin->bitmap_size = avctx->width * avctx->height;
00101     for (i = 0; i < 3; ++i) {
00102         cin->bitmap_table[i] = av_mallocz(cin->bitmap_size);
00103         if (!cin->bitmap_table[i])
00104             av_log(avctx, AV_LOG_ERROR, "Can't allocate bitmap buffers.\n");
00105     }
00106 
00107     return 0;
00108 }
00109 
00110 static void cin_apply_delta_data(const unsigned char *src, unsigned char *dst, int size)
00111 {
00112     while (size--)
00113         *dst++ += *src++;
00114 }
00115 
00116 static int cin_decode_huffman(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
00117 {
00118     int b, huff_code = 0;
00119     unsigned char huff_code_table[15];
00120     unsigned char *dst_cur = dst;
00121     unsigned char *dst_end = dst + dst_size;
00122     const unsigned char *src_end = src + src_size;
00123 
00124     memcpy(huff_code_table, src, 15); src += 15; src_size -= 15;
00125 
00126     while (src < src_end) {
00127         huff_code = *src++;
00128         if ((huff_code >> 4) == 15) {
00129             b = huff_code << 4;
00130             huff_code = *src++;
00131             *dst_cur++ = b | (huff_code >> 4);
00132         } else
00133             *dst_cur++ = huff_code_table[huff_code >> 4];
00134         if (dst_cur >= dst_end)
00135             break;
00136 
00137         huff_code &= 15;
00138         if (huff_code == 15) {
00139             *dst_cur++ = *src++;
00140         } else
00141             *dst_cur++ = huff_code_table[huff_code];
00142         if (dst_cur >= dst_end)
00143             break;
00144     }
00145 
00146     return dst_cur - dst;
00147 }
00148 
00149 static int cin_decode_lzss(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
00150 {
00151     uint16_t cmd;
00152     int i, sz, offset, code;
00153     unsigned char *dst_end = dst + dst_size, *dst_start = dst;
00154     const unsigned char *src_end = src + src_size;
00155 
00156     while (src < src_end && dst < dst_end) {
00157         code = *src++;
00158         for (i = 0; i < 8 && src < src_end && dst < dst_end; ++i) {
00159             if (code & (1 << i)) {
00160                 *dst++ = *src++;
00161             } else {
00162                 cmd = AV_RL16(src); src += 2;
00163                 offset = cmd >> 4;
00164                 if ((int) (dst - dst_start) < offset + 1)
00165                     return AVERROR_INVALIDDATA;
00166                 sz = (cmd & 0xF) + 2;
00167                 /* don't use memcpy/memmove here as the decoding routine (ab)uses */
00168                 /* buffer overlappings to repeat bytes in the destination */
00169                 sz = FFMIN(sz, dst_end - dst);
00170                 while (sz--) {
00171                     *dst = *(dst - offset - 1);
00172                     ++dst;
00173                 }
00174             }
00175         }
00176     }
00177 
00178     return 0;
00179 }
00180 
00181 static void cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
00182 {
00183     int len, code;
00184     unsigned char *dst_end = dst + dst_size;
00185     const unsigned char *src_end = src + src_size;
00186 
00187     while (src < src_end && dst < dst_end) {
00188         code = *src++;
00189         if (code & 0x80) {
00190             len = code - 0x7F;
00191             memset(dst, *src++, FFMIN(len, dst_end - dst));
00192         } else {
00193             len = code + 1;
00194             memcpy(dst, src, FFMIN(len, dst_end - dst));
00195             src += len;
00196         }
00197         dst += len;
00198     }
00199 }
00200 
00201 static int cinvideo_decode_frame(AVCodecContext *avctx,
00202                                  void *data, int *data_size,
00203                                  AVPacket *avpkt)
00204 {
00205     const uint8_t *buf = avpkt->data;
00206     int buf_size = avpkt->size;
00207     CinVideoContext *cin = avctx->priv_data;
00208     int i, y, palette_type, palette_colors_count, bitmap_frame_type, bitmap_frame_size, res = 0;
00209 
00210     palette_type = buf[0];
00211     palette_colors_count = AV_RL16(buf+1);
00212     bitmap_frame_type = buf[3];
00213     buf += 4;
00214 
00215     bitmap_frame_size = buf_size - 4;
00216 
00217     /* handle palette */
00218     if (bitmap_frame_size < palette_colors_count * (3 + (palette_type != 0)))
00219         return AVERROR_INVALIDDATA;
00220     if (palette_type == 0) {
00221         if (palette_colors_count > 256)
00222             return AVERROR_INVALIDDATA;
00223         for (i = 0; i < palette_colors_count; ++i) {
00224             cin->palette[i] = bytestream_get_le24(&buf);
00225             bitmap_frame_size -= 3;
00226         }
00227     } else {
00228         for (i = 0; i < palette_colors_count; ++i) {
00229             cin->palette[buf[0]] = AV_RL24(buf+1);
00230             buf += 4;
00231             bitmap_frame_size -= 4;
00232         }
00233     }
00234 
00235     /* note: the decoding routines below assumes that surface.width = surface.pitch */
00236     switch (bitmap_frame_type) {
00237     case 9:
00238         cin_decode_rle(buf, bitmap_frame_size,
00239           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00240         break;
00241     case 34:
00242         cin_decode_rle(buf, bitmap_frame_size,
00243           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00244         cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
00245           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00246         break;
00247     case 35:
00248         cin_decode_huffman(buf, bitmap_frame_size,
00249           cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
00250         cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
00251           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00252         break;
00253     case 36:
00254         bitmap_frame_size = cin_decode_huffman(buf, bitmap_frame_size,
00255           cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
00256         cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
00257           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00258         cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
00259           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00260         break;
00261     case 37:
00262         cin_decode_huffman(buf, bitmap_frame_size,
00263           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00264         break;
00265     case 38:
00266         res = cin_decode_lzss(buf, bitmap_frame_size,
00267                               cin->bitmap_table[CIN_CUR_BMP],
00268                               cin->bitmap_size);
00269         if (res < 0)
00270             return res;
00271         break;
00272     case 39:
00273         res = cin_decode_lzss(buf, bitmap_frame_size,
00274                               cin->bitmap_table[CIN_CUR_BMP],
00275                               cin->bitmap_size);
00276         if (res < 0)
00277             return res;
00278         cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
00279           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00280         break;
00281     }
00282 
00283     cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
00284     if (avctx->reget_buffer(avctx, &cin->frame)) {
00285         av_log(cin->avctx, AV_LOG_ERROR, "delphinecinvideo: reget_buffer() failed to allocate a frame\n");
00286         return -1;
00287     }
00288 
00289     memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette));
00290     cin->frame.palette_has_changed = 1;
00291     for (y = 0; y < cin->avctx->height; ++y)
00292         memcpy(cin->frame.data[0] + (cin->avctx->height - 1 - y) * cin->frame.linesize[0],
00293           cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width,
00294           cin->avctx->width);
00295 
00296     FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_table[CIN_PRE_BMP]);
00297 
00298     *data_size = sizeof(AVFrame);
00299     *(AVFrame *)data = cin->frame;
00300 
00301     return buf_size;
00302 }
00303 
00304 static av_cold int cinvideo_decode_end(AVCodecContext *avctx)
00305 {
00306     CinVideoContext *cin = avctx->priv_data;
00307     int i;
00308 
00309     if (cin->frame.data[0])
00310         avctx->release_buffer(avctx, &cin->frame);
00311 
00312     for (i = 0; i < 3; ++i)
00313         av_free(cin->bitmap_table[i]);
00314 
00315     return 0;
00316 }
00317 
00318 static av_cold int cinaudio_decode_init(AVCodecContext *avctx)
00319 {
00320     CinAudioContext *cin = avctx->priv_data;
00321 
00322     cin->avctx = avctx;
00323     if (avctx->channels != 1) {
00324         av_log_ask_for_sample(avctx, "Number of channels is not supported\n");
00325         return AVERROR_PATCHWELCOME;
00326     }
00327 
00328     cin->initial_decode_frame = 1;
00329     cin->delta = 0;
00330     avctx->sample_fmt = AV_SAMPLE_FMT_S16;
00331 
00332     return 0;
00333 }
00334 
00335 static int cinaudio_decode_frame(AVCodecContext *avctx,
00336                                  void *data, int *data_size,
00337                                  AVPacket *avpkt)
00338 {
00339     const uint8_t *buf = avpkt->data;
00340     int buf_size = avpkt->size;
00341     CinAudioContext *cin = avctx->priv_data;
00342     const uint8_t *src = buf;
00343     int16_t *samples = (int16_t *)data;
00344 
00345     buf_size = FFMIN(buf_size, *data_size/2);
00346 
00347     if (cin->initial_decode_frame) {
00348         cin->initial_decode_frame = 0;
00349         cin->delta = (int16_t)AV_RL16(src); src += 2;
00350         *samples++ = cin->delta;
00351         buf_size -= 2;
00352     }
00353     while (buf_size > 0) {
00354         cin->delta += cinaudio_delta16_table[*src++];
00355         cin->delta = av_clip_int16(cin->delta);
00356         *samples++ = cin->delta;
00357         --buf_size;
00358     }
00359 
00360     *data_size = (uint8_t *)samples - (uint8_t *)data;
00361 
00362     return src - buf;
00363 }
00364 
00365 
00366 AVCodec ff_dsicinvideo_decoder = {
00367     "dsicinvideo",
00368     AVMEDIA_TYPE_VIDEO,
00369     CODEC_ID_DSICINVIDEO,
00370     sizeof(CinVideoContext),
00371     cinvideo_decode_init,
00372     NULL,
00373     cinvideo_decode_end,
00374     cinvideo_decode_frame,
00375     CODEC_CAP_DR1,
00376     .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN video"),
00377 };
00378 
00379 AVCodec ff_dsicinaudio_decoder = {
00380     "dsicinaudio",
00381     AVMEDIA_TYPE_AUDIO,
00382     CODEC_ID_DSICINAUDIO,
00383     sizeof(CinAudioContext),
00384     cinaudio_decode_init,
00385     NULL,
00386     NULL,
00387     cinaudio_decode_frame,
00388     .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN audio"),
00389 };

Generated on Fri Feb 22 2013 07:24:26 for FFmpeg by  doxygen 1.7.1