• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • 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 #include "mathops.h"
00030 
00031 
00032 typedef enum CinVideoBitmapIndex {
00033     CIN_CUR_BMP = 0, /* current */
00034     CIN_PRE_BMP = 1, /* previous */
00035     CIN_INT_BMP = 2  /* intermediate */
00036 } CinVideoBitmapIndex;
00037 
00038 typedef struct CinVideoContext {
00039     AVCodecContext *avctx;
00040     AVFrame frame;
00041     unsigned int bitmap_size;
00042     uint32_t palette[256];
00043     uint8_t *bitmap_table[3];
00044 } CinVideoContext;
00045 
00046 typedef struct CinAudioContext {
00047     AVFrame frame;
00048     int initial_decode_frame;
00049     int delta;
00050 } CinAudioContext;
00051 
00052 
00053 /* table defining a geometric sequence with multiplier = 32767 ^ (1 / 128) */
00054 static const int16_t cinaudio_delta16_table[256] = {
00055          0,      0,      0,      0,      0,      0,      0,      0,
00056          0,      0,      0,      0,      0,      0,      0,      0,
00057          0,      0,      0, -30210, -27853, -25680, -23677, -21829,
00058     -20126, -18556, -17108, -15774, -14543, -13408, -12362, -11398,
00059     -10508,  -9689,  -8933,  -8236,  -7593,  -7001,  -6455,  -5951,
00060      -5487,  -5059,  -4664,  -4300,  -3964,  -3655,  -3370,  -3107,
00061      -2865,  -2641,  -2435,  -2245,  -2070,  -1908,  -1759,  -1622,
00062      -1495,  -1379,  -1271,  -1172,  -1080,   -996,   -918,   -847,
00063       -781,   -720,   -663,   -612,   -564,   -520,   -479,   -442,
00064       -407,   -376,   -346,   -319,   -294,   -271,   -250,   -230,
00065       -212,   -196,   -181,   -166,   -153,   -141,   -130,   -120,
00066       -111,   -102,    -94,    -87,    -80,    -74,    -68,    -62,
00067        -58,    -53,    -49,    -45,    -41,    -38,    -35,    -32,
00068        -30,    -27,    -25,    -23,    -21,    -20,    -18,    -17,
00069        -15,    -14,    -13,    -12,    -11,    -10,     -9,     -8,
00070         -7,     -6,     -5,     -4,     -3,     -2,     -1,      0,
00071          0,      1,      2,      3,      4,      5,      6,      7,
00072          8,      9,     10,     11,     12,     13,     14,     15,
00073         17,     18,     20,     21,     23,     25,     27,     30,
00074         32,     35,     38,     41,     45,     49,     53,     58,
00075         62,     68,     74,     80,     87,     94,    102,    111,
00076        120,    130,    141,    153,    166,    181,    196,    212,
00077        230,    250,    271,    294,    319,    346,    376,    407,
00078        442,    479,    520,    564,    612,    663,    720,    781,
00079        847,    918,    996,   1080,   1172,   1271,   1379,   1495,
00080       1622,   1759,   1908,   2070,   2245,   2435,   2641,   2865,
00081       3107,   3370,   3655,   3964,   4300,   4664,   5059,   5487,
00082       5951,   6455,   7001,   7593,   8236,   8933,   9689,  10508,
00083      11398,  12362,  13408,  14543,  15774,  17108,  18556,  20126,
00084      21829,  23677,  25680,  27853,  30210,      0,      0,      0,
00085          0,      0,      0,      0,      0,      0,      0,      0,
00086          0,      0,      0,      0,      0,      0,      0,      0
00087 };
00088 
00089 
00090 static av_cold int cinvideo_decode_init(AVCodecContext *avctx)
00091 {
00092     CinVideoContext *cin = avctx->priv_data;
00093     unsigned int i;
00094 
00095     cin->avctx = avctx;
00096     avctx->pix_fmt = PIX_FMT_PAL8;
00097 
00098     avcodec_get_frame_defaults(&cin->frame);
00099     cin->frame.data[0] = NULL;
00100 
00101     cin->bitmap_size = avctx->width * avctx->height;
00102     for (i = 0; i < 3; ++i) {
00103         cin->bitmap_table[i] = av_mallocz(cin->bitmap_size);
00104         if (!cin->bitmap_table[i])
00105             av_log(avctx, AV_LOG_ERROR, "Can't allocate bitmap buffers.\n");
00106     }
00107 
00108     return 0;
00109 }
00110 
00111 static void cin_apply_delta_data(const unsigned char *src, unsigned char *dst, int size)
00112 {
00113     while (size--)
00114         *dst++ += *src++;
00115 }
00116 
00117 static int cin_decode_huffman(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
00118 {
00119     int b, huff_code = 0;
00120     unsigned char huff_code_table[15];
00121     unsigned char *dst_cur = dst;
00122     unsigned char *dst_end = dst + dst_size;
00123     const unsigned char *src_end = src + src_size;
00124 
00125     memcpy(huff_code_table, src, 15); src += 15; src_size -= 15;
00126 
00127     while (src < src_end) {
00128         huff_code = *src++;
00129         if ((huff_code >> 4) == 15) {
00130             b = huff_code << 4;
00131             huff_code = *src++;
00132             *dst_cur++ = b | (huff_code >> 4);
00133         } else
00134             *dst_cur++ = huff_code_table[huff_code >> 4];
00135         if (dst_cur >= dst_end)
00136             break;
00137 
00138         huff_code &= 15;
00139         if (huff_code == 15) {
00140             *dst_cur++ = *src++;
00141         } else
00142             *dst_cur++ = huff_code_table[huff_code];
00143         if (dst_cur >= dst_end)
00144             break;
00145     }
00146 
00147     return dst_cur - dst;
00148 }
00149 
00150 static int cin_decode_lzss(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
00151 {
00152     uint16_t cmd;
00153     int i, sz, offset, code;
00154     unsigned char *dst_end = dst + dst_size, *dst_start = dst;
00155     const unsigned char *src_end = src + src_size;
00156 
00157     while (src < src_end && dst < dst_end) {
00158         code = *src++;
00159         for (i = 0; i < 8 && src < src_end && dst < dst_end; ++i) {
00160             if (code & (1 << i)) {
00161                 *dst++ = *src++;
00162             } else {
00163                 cmd = AV_RL16(src); src += 2;
00164                 offset = cmd >> 4;
00165                 if ((int) (dst - dst_start) < offset + 1)
00166                     return AVERROR_INVALIDDATA;
00167                 sz = (cmd & 0xF) + 2;
00168                 /* don't use memcpy/memmove here as the decoding routine (ab)uses */
00169                 /* buffer overlappings to repeat bytes in the destination */
00170                 sz = FFMIN(sz, dst_end - dst);
00171                 while (sz--) {
00172                     *dst = *(dst - offset - 1);
00173                     ++dst;
00174                 }
00175             }
00176         }
00177     }
00178 
00179     return 0;
00180 }
00181 
00182 static void cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
00183 {
00184     int len, code;
00185     unsigned char *dst_end = dst + dst_size;
00186     const unsigned char *src_end = src + src_size;
00187 
00188     while (src < src_end && dst < dst_end) {
00189         code = *src++;
00190         if (code & 0x80) {
00191             len = code - 0x7F;
00192             memset(dst, *src++, FFMIN(len, dst_end - dst));
00193         } else {
00194             len = code + 1;
00195             memcpy(dst, src, FFMIN(len, dst_end - dst));
00196             src += len;
00197         }
00198         dst += len;
00199     }
00200 }
00201 
00202 static int cinvideo_decode_frame(AVCodecContext *avctx,
00203                                  void *data, int *data_size,
00204                                  AVPacket *avpkt)
00205 {
00206     const uint8_t *buf = avpkt->data;
00207     int buf_size = avpkt->size;
00208     CinVideoContext *cin = avctx->priv_data;
00209     int i, y, palette_type, palette_colors_count, bitmap_frame_type, bitmap_frame_size, res = 0;
00210 
00211     palette_type = buf[0];
00212     palette_colors_count = AV_RL16(buf+1);
00213     bitmap_frame_type = buf[3];
00214     buf += 4;
00215 
00216     bitmap_frame_size = buf_size - 4;
00217 
00218     /* handle palette */
00219     if (bitmap_frame_size < palette_colors_count * (3 + (palette_type != 0)))
00220         return AVERROR_INVALIDDATA;
00221     if (palette_type == 0) {
00222         if (palette_colors_count > 256)
00223             return AVERROR_INVALIDDATA;
00224         for (i = 0; i < palette_colors_count; ++i) {
00225             cin->palette[i] = 0xFF << 24 | bytestream_get_le24(&buf);
00226             bitmap_frame_size -= 3;
00227         }
00228     } else {
00229         for (i = 0; i < palette_colors_count; ++i) {
00230             cin->palette[buf[0]] = 0xFF << 24 | AV_RL24(buf+1);
00231             buf += 4;
00232             bitmap_frame_size -= 4;
00233         }
00234     }
00235 
00236     /* note: the decoding routines below assumes that surface.width = surface.pitch */
00237     switch (bitmap_frame_type) {
00238     case 9:
00239         cin_decode_rle(buf, bitmap_frame_size,
00240           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00241         break;
00242     case 34:
00243         cin_decode_rle(buf, bitmap_frame_size,
00244           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00245         cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
00246           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00247         break;
00248     case 35:
00249         cin_decode_huffman(buf, bitmap_frame_size,
00250           cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
00251         cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
00252           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00253         break;
00254     case 36:
00255         bitmap_frame_size = cin_decode_huffman(buf, bitmap_frame_size,
00256           cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
00257         cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
00258           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00259         cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
00260           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00261         break;
00262     case 37:
00263         cin_decode_huffman(buf, bitmap_frame_size,
00264           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00265         break;
00266     case 38:
00267         res = cin_decode_lzss(buf, bitmap_frame_size,
00268                               cin->bitmap_table[CIN_CUR_BMP],
00269                               cin->bitmap_size);
00270         if (res < 0)
00271             return res;
00272         break;
00273     case 39:
00274         res = cin_decode_lzss(buf, bitmap_frame_size,
00275                               cin->bitmap_table[CIN_CUR_BMP],
00276                               cin->bitmap_size);
00277         if (res < 0)
00278             return res;
00279         cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
00280           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00281         break;
00282     }
00283 
00284     cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
00285     if (avctx->reget_buffer(avctx, &cin->frame)) {
00286         av_log(cin->avctx, AV_LOG_ERROR, "delphinecinvideo: reget_buffer() failed to allocate a frame\n");
00287         return -1;
00288     }
00289 
00290     memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette));
00291     cin->frame.palette_has_changed = 1;
00292     for (y = 0; y < cin->avctx->height; ++y)
00293         memcpy(cin->frame.data[0] + (cin->avctx->height - 1 - y) * cin->frame.linesize[0],
00294           cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width,
00295           cin->avctx->width);
00296 
00297     FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_table[CIN_PRE_BMP]);
00298 
00299     *data_size = sizeof(AVFrame);
00300     *(AVFrame *)data = cin->frame;
00301 
00302     return buf_size;
00303 }
00304 
00305 static av_cold int cinvideo_decode_end(AVCodecContext *avctx)
00306 {
00307     CinVideoContext *cin = avctx->priv_data;
00308     int i;
00309 
00310     if (cin->frame.data[0])
00311         avctx->release_buffer(avctx, &cin->frame);
00312 
00313     for (i = 0; i < 3; ++i)
00314         av_free(cin->bitmap_table[i]);
00315 
00316     return 0;
00317 }
00318 
00319 static av_cold int cinaudio_decode_init(AVCodecContext *avctx)
00320 {
00321     CinAudioContext *cin = avctx->priv_data;
00322 
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     avcodec_get_frame_defaults(&cin->frame);
00333     avctx->coded_frame = &cin->frame;
00334 
00335     return 0;
00336 }
00337 
00338 static int cinaudio_decode_frame(AVCodecContext *avctx, void *data,
00339                                  int *got_frame_ptr, AVPacket *avpkt)
00340 {
00341     const uint8_t *buf = avpkt->data;
00342     CinAudioContext *cin = avctx->priv_data;
00343     const uint8_t *buf_end = buf + avpkt->size;
00344     int16_t *samples;
00345     int delta, ret;
00346 
00347     /* get output buffer */
00348     cin->frame.nb_samples = avpkt->size - cin->initial_decode_frame;
00349     if ((ret = avctx->get_buffer(avctx, &cin->frame)) < 0) {
00350         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00351         return ret;
00352     }
00353     samples = (int16_t *)cin->frame.data[0];
00354 
00355     delta = cin->delta;
00356     if (cin->initial_decode_frame) {
00357         cin->initial_decode_frame = 0;
00358         delta = sign_extend(AV_RL16(buf), 16);
00359         buf += 2;
00360         *samples++ = delta;
00361     }
00362     while (buf < buf_end) {
00363         delta += cinaudio_delta16_table[*buf++];
00364         delta = av_clip_int16(delta);
00365         *samples++ = delta;
00366     }
00367     cin->delta = delta;
00368 
00369     *got_frame_ptr   = 1;
00370     *(AVFrame *)data = cin->frame;
00371 
00372     return avpkt->size;
00373 }
00374 
00375 
00376 AVCodec ff_dsicinvideo_decoder = {
00377     .name           = "dsicinvideo",
00378     .type           = AVMEDIA_TYPE_VIDEO,
00379     .id             = CODEC_ID_DSICINVIDEO,
00380     .priv_data_size = sizeof(CinVideoContext),
00381     .init           = cinvideo_decode_init,
00382     .close          = cinvideo_decode_end,
00383     .decode         = cinvideo_decode_frame,
00384     .capabilities   = CODEC_CAP_DR1,
00385     .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN video"),
00386 };
00387 
00388 AVCodec ff_dsicinaudio_decoder = {
00389     .name           = "dsicinaudio",
00390     .type           = AVMEDIA_TYPE_AUDIO,
00391     .id             = CODEC_ID_DSICINAUDIO,
00392     .priv_data_size = sizeof(CinAudioContext),
00393     .init           = cinaudio_decode_init,
00394     .decode         = cinaudio_decode_frame,
00395     .capabilities   = CODEC_CAP_DR1,
00396     .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN audio"),
00397 };
Generated on Fri Feb 1 2013 14:34:32 for FFmpeg by doxygen 1.7.1