• 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 Libav.
00006  *
00007  * Libav 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  * Libav 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 Libav; 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     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 void 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;
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                 sz = (cmd & 0xF) + 2;
00165                 /* don't use memcpy/memmove here as the decoding routine (ab)uses */
00166                 /* buffer overlappings to repeat bytes in the destination */
00167                 sz = FFMIN(sz, dst_end - dst);
00168                 while (sz--) {
00169                     *dst = *(dst - offset - 1);
00170                     ++dst;
00171                 }
00172             }
00173         }
00174     }
00175 }
00176 
00177 static void cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
00178 {
00179     int len, code;
00180     unsigned char *dst_end = dst + dst_size;
00181     const unsigned char *src_end = src + src_size;
00182 
00183     while (src < src_end && dst < dst_end) {
00184         code = *src++;
00185         if (code & 0x80) {
00186             len = code - 0x7F;
00187             memset(dst, *src++, FFMIN(len, dst_end - dst));
00188         } else {
00189             len = code + 1;
00190             memcpy(dst, src, FFMIN(len, dst_end - dst));
00191             src += len;
00192         }
00193         dst += len;
00194     }
00195 }
00196 
00197 static int cinvideo_decode_frame(AVCodecContext *avctx,
00198                                  void *data, int *data_size,
00199                                  AVPacket *avpkt)
00200 {
00201     const uint8_t *buf = avpkt->data;
00202     int buf_size = avpkt->size;
00203     CinVideoContext *cin = avctx->priv_data;
00204     int i, y, palette_type, palette_colors_count, bitmap_frame_type, bitmap_frame_size;
00205 
00206     cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
00207     if (avctx->reget_buffer(avctx, &cin->frame)) {
00208         av_log(cin->avctx, AV_LOG_ERROR, "delphinecinvideo: reget_buffer() failed to allocate a frame\n");
00209         return -1;
00210     }
00211 
00212     palette_type = buf[0];
00213     palette_colors_count = AV_RL16(buf+1);
00214     bitmap_frame_type = buf[3];
00215     buf += 4;
00216 
00217     bitmap_frame_size = buf_size - 4;
00218 
00219     /* handle palette */
00220     if (bitmap_frame_size < palette_colors_count * (3 + (palette_type != 0)))
00221         return AVERROR_INVALIDDATA;
00222     if (palette_type == 0) {
00223         if (palette_colors_count > 256)
00224             return AVERROR_INVALIDDATA;
00225         for (i = 0; i < palette_colors_count; ++i) {
00226             cin->palette[i] = bytestream_get_le24(&buf);
00227             bitmap_frame_size -= 3;
00228         }
00229     } else {
00230         for (i = 0; i < palette_colors_count; ++i) {
00231             cin->palette[buf[0]] = AV_RL24(buf+1);
00232             buf += 4;
00233             bitmap_frame_size -= 4;
00234         }
00235     }
00236     memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette));
00237     cin->frame.palette_has_changed = 1;
00238 
00239     /* note: the decoding routines below assumes that surface.width = surface.pitch */
00240     switch (bitmap_frame_type) {
00241     case 9:
00242         cin_decode_rle(buf, bitmap_frame_size,
00243           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00244         break;
00245     case 34:
00246         cin_decode_rle(buf, bitmap_frame_size,
00247           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00248         cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
00249           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00250         break;
00251     case 35:
00252         cin_decode_huffman(buf, bitmap_frame_size,
00253           cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
00254         cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
00255           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00256         break;
00257     case 36:
00258         bitmap_frame_size = cin_decode_huffman(buf, bitmap_frame_size,
00259           cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
00260         cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
00261           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00262         cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
00263           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00264         break;
00265     case 37:
00266         cin_decode_huffman(buf, bitmap_frame_size,
00267           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00268         break;
00269     case 38:
00270         cin_decode_lzss(buf, bitmap_frame_size,
00271           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00272         break;
00273     case 39:
00274         cin_decode_lzss(buf, bitmap_frame_size,
00275           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00276         cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
00277           cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00278         break;
00279     }
00280 
00281     for (y = 0; y < cin->avctx->height; ++y)
00282         memcpy(cin->frame.data[0] + (cin->avctx->height - 1 - y) * cin->frame.linesize[0],
00283           cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width,
00284           cin->avctx->width);
00285 
00286     FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_table[CIN_PRE_BMP]);
00287 
00288     *data_size = sizeof(AVFrame);
00289     *(AVFrame *)data = cin->frame;
00290 
00291     return buf_size;
00292 }
00293 
00294 static av_cold int cinvideo_decode_end(AVCodecContext *avctx)
00295 {
00296     CinVideoContext *cin = avctx->priv_data;
00297     int i;
00298 
00299     if (cin->frame.data[0])
00300         avctx->release_buffer(avctx, &cin->frame);
00301 
00302     for (i = 0; i < 3; ++i)
00303         av_free(cin->bitmap_table[i]);
00304 
00305     return 0;
00306 }
00307 
00308 static av_cold int cinaudio_decode_init(AVCodecContext *avctx)
00309 {
00310     CinAudioContext *cin = avctx->priv_data;
00311 
00312     if (avctx->channels != 1) {
00313         av_log_ask_for_sample(avctx, "Number of channels is not supported\n");
00314         return AVERROR_PATCHWELCOME;
00315     }
00316 
00317     cin->initial_decode_frame = 1;
00318     cin->delta = 0;
00319     avctx->sample_fmt = AV_SAMPLE_FMT_S16;
00320 
00321     avcodec_get_frame_defaults(&cin->frame);
00322     avctx->coded_frame = &cin->frame;
00323 
00324     return 0;
00325 }
00326 
00327 static int cinaudio_decode_frame(AVCodecContext *avctx, void *data,
00328                                  int *got_frame_ptr, AVPacket *avpkt)
00329 {
00330     const uint8_t *buf = avpkt->data;
00331     CinAudioContext *cin = avctx->priv_data;
00332     const uint8_t *buf_end = buf + avpkt->size;
00333     int16_t *samples;
00334     int delta, ret;
00335 
00336     /* get output buffer */
00337     cin->frame.nb_samples = avpkt->size - cin->initial_decode_frame;
00338     if ((ret = avctx->get_buffer(avctx, &cin->frame)) < 0) {
00339         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00340         return ret;
00341     }
00342     samples = (int16_t *)cin->frame.data[0];
00343 
00344     delta = cin->delta;
00345     if (cin->initial_decode_frame) {
00346         cin->initial_decode_frame = 0;
00347         delta = sign_extend(AV_RL16(buf), 16);
00348         buf += 2;
00349         *samples++ = delta;
00350     }
00351     while (buf < buf_end) {
00352         delta += cinaudio_delta16_table[*buf++];
00353         delta = av_clip_int16(delta);
00354         *samples++ = delta;
00355     }
00356     cin->delta = delta;
00357 
00358     *got_frame_ptr   = 1;
00359     *(AVFrame *)data = cin->frame;
00360 
00361     return avpkt->size;
00362 }
00363 
00364 
00365 AVCodec ff_dsicinvideo_decoder = {
00366     .name           = "dsicinvideo",
00367     .type           = AVMEDIA_TYPE_VIDEO,
00368     .id             = CODEC_ID_DSICINVIDEO,
00369     .priv_data_size = sizeof(CinVideoContext),
00370     .init           = cinvideo_decode_init,
00371     .close          = cinvideo_decode_end,
00372     .decode         = cinvideo_decode_frame,
00373     .capabilities   = CODEC_CAP_DR1,
00374     .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN video"),
00375 };
00376 
00377 AVCodec ff_dsicinaudio_decoder = {
00378     .name           = "dsicinaudio",
00379     .type           = AVMEDIA_TYPE_AUDIO,
00380     .id             = CODEC_ID_DSICINAUDIO,
00381     .priv_data_size = sizeof(CinAudioContext),
00382     .init           = cinaudio_decode_init,
00383     .decode         = cinaudio_decode_frame,
00384     .capabilities   = CODEC_CAP_DR1,
00385     .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN audio"),
00386 };
Generated on Sat Mar 17 2012 12:57:44 for Libav by doxygen 1.7.1