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,
00111                                  int size)
00112 {
00113     while (size--)
00114         *dst++ += *src++;
00115 }
00116 
00117 static int cin_decode_huffman(const unsigned char *src, int src_size,
00118                               unsigned char *dst, int dst_size)
00119 {
00120     int b, huff_code = 0;
00121     unsigned char huff_code_table[15];
00122     unsigned char *dst_cur       = dst;
00123     unsigned char *dst_end       = dst + dst_size;
00124     const unsigned char *src_end = src + src_size;
00125 
00126     memcpy(huff_code_table, src, 15);
00127     src += 15;
00128     src_size -= 15;
00129 
00130     while (src < src_end) {
00131         huff_code = *src++;
00132         if ((huff_code >> 4) == 15) {
00133             b          = huff_code << 4;
00134             huff_code  = *src++;
00135             *dst_cur++ = b | (huff_code >> 4);
00136         } else
00137             *dst_cur++ = huff_code_table[huff_code >> 4];
00138         if (dst_cur >= dst_end)
00139             break;
00140 
00141         huff_code &= 15;
00142         if (huff_code == 15) {
00143             *dst_cur++ = *src++;
00144         } else
00145             *dst_cur++ = huff_code_table[huff_code];
00146         if (dst_cur >= dst_end)
00147             break;
00148     }
00149 
00150     return dst_cur - dst;
00151 }
00152 
00153 static int cin_decode_lzss(const unsigned char *src, int src_size,
00154                            unsigned char *dst, int dst_size)
00155 {
00156     uint16_t cmd;
00157     int i, sz, offset, code;
00158     unsigned char *dst_end       = dst + dst_size, *dst_start = dst;
00159     const unsigned char *src_end = src + src_size;
00160 
00161     while (src < src_end && dst < dst_end) {
00162         code = *src++;
00163         for (i = 0; i < 8 && src < src_end && dst < dst_end; ++i) {
00164             if (code & (1 << i)) {
00165                 *dst++ = *src++;
00166             } else {
00167                 cmd  = AV_RL16(src);
00168                 src += 2;
00169                 offset = cmd >> 4;
00170                 if ((int)(dst - dst_start) < offset + 1)
00171                     return AVERROR_INVALIDDATA;
00172                 sz = (cmd & 0xF) + 2;
00173                 /* don't use memcpy/memmove here as the decoding routine
00174                  * (ab)uses buffer overlappings to repeat bytes in the
00175                  * destination */
00176                 sz = FFMIN(sz, dst_end - dst);
00177                 while (sz--) {
00178                     *dst = *(dst - offset - 1);
00179                     ++dst;
00180                 }
00181             }
00182         }
00183     }
00184 
00185     return 0;
00186 }
00187 
00188 static void cin_decode_rle(const unsigned char *src, int src_size,
00189                            unsigned char *dst, int dst_size)
00190 {
00191     int len, code;
00192     unsigned char *dst_end       = dst + dst_size;
00193     const unsigned char *src_end = src + src_size;
00194 
00195     while (src < src_end && dst < dst_end) {
00196         code = *src++;
00197         if (code & 0x80) {
00198             if (src >= src_end)
00199                 break;
00200             len = code - 0x7F;
00201             memset(dst, *src++, FFMIN(len, dst_end - dst));
00202         } else {
00203             len = code + 1;
00204             memcpy(dst, src, FFMIN3(len, dst_end - dst, src_end - src));
00205             src += len;
00206         }
00207         dst += len;
00208     }
00209 }
00210 
00211 static int cinvideo_decode_frame(AVCodecContext *avctx,
00212                                  void *data, int *data_size,
00213                                  AVPacket *avpkt)
00214 {
00215     const uint8_t *buf   = avpkt->data;
00216     int buf_size         = avpkt->size;
00217     CinVideoContext *cin = avctx->priv_data;
00218     int i, y, palette_type, palette_colors_count,
00219         bitmap_frame_type, bitmap_frame_size, res = 0;
00220 
00221     palette_type         = buf[0];
00222     palette_colors_count = AV_RL16(buf+1);
00223     bitmap_frame_type    = buf[3];
00224     buf                 += 4;
00225 
00226     bitmap_frame_size = buf_size - 4;
00227 
00228     /* handle palette */
00229     if (bitmap_frame_size < palette_colors_count * (3 + (palette_type != 0)))
00230         return AVERROR_INVALIDDATA;
00231     if (palette_type == 0) {
00232         if (palette_colors_count > 256)
00233             return AVERROR_INVALIDDATA;
00234         for (i = 0; i < palette_colors_count; ++i) {
00235             cin->palette[i]    = bytestream_get_le24(&buf);
00236             bitmap_frame_size -= 3;
00237         }
00238     } else {
00239         for (i = 0; i < palette_colors_count; ++i) {
00240             cin->palette[buf[0]] = AV_RL24(buf + 1);
00241             buf                 += 4;
00242             bitmap_frame_size   -= 4;
00243         }
00244     }
00245 
00246     bitmap_frame_size = FFMIN(cin->bitmap_size, bitmap_frame_size);
00247 
00248     /* note: the decoding routines below assumes that
00249      * surface.width = surface.pitch */
00250     switch (bitmap_frame_type) {
00251     case 9:
00252         cin_decode_rle(buf, bitmap_frame_size,
00253                        cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00254         break;
00255     case 34:
00256         cin_decode_rle(buf, 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 35:
00262         cin_decode_huffman(buf, bitmap_frame_size,
00263                            cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
00264         cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
00265                        cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00266         break;
00267     case 36:
00268         bitmap_frame_size = cin_decode_huffman(buf, bitmap_frame_size,
00269                                                cin->bitmap_table[CIN_INT_BMP],
00270                                                cin->bitmap_size);
00271         cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
00272                        cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00273         cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
00274                              cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00275         break;
00276     case 37:
00277         cin_decode_huffman(buf, bitmap_frame_size,
00278                            cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00279         break;
00280     case 38:
00281         res = cin_decode_lzss(buf, bitmap_frame_size,
00282                               cin->bitmap_table[CIN_CUR_BMP],
00283                               cin->bitmap_size);
00284         if (res < 0)
00285             return res;
00286         break;
00287     case 39:
00288         res = cin_decode_lzss(buf, bitmap_frame_size,
00289                               cin->bitmap_table[CIN_CUR_BMP],
00290                               cin->bitmap_size);
00291         if (res < 0)
00292             return res;
00293         cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
00294                              cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00295         break;
00296     }
00297 
00298     cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
00299     if ((res = avctx->reget_buffer(avctx, &cin->frame)) < 0) {
00300         av_log(cin->avctx, AV_LOG_ERROR,
00301                "delphinecinvideo: reget_buffer() failed to allocate a frame\n");
00302         return res;
00303     }
00304 
00305     memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette));
00306     cin->frame.palette_has_changed = 1;
00307     for (y = 0; y < cin->avctx->height; ++y)
00308         memcpy(cin->frame.data[0] + (cin->avctx->height - 1 - y) * cin->frame.linesize[0],
00309                cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width,
00310                cin->avctx->width);
00311 
00312     FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP],
00313                       cin->bitmap_table[CIN_PRE_BMP]);
00314 
00315     *data_size = sizeof(AVFrame);
00316     *(AVFrame *)data = cin->frame;
00317 
00318     return buf_size;
00319 }
00320 
00321 static av_cold int cinvideo_decode_end(AVCodecContext *avctx)
00322 {
00323     CinVideoContext *cin = avctx->priv_data;
00324     int i;
00325 
00326     if (cin->frame.data[0])
00327         avctx->release_buffer(avctx, &cin->frame);
00328 
00329     for (i = 0; i < 3; ++i)
00330         av_free(cin->bitmap_table[i]);
00331 
00332     return 0;
00333 }
00334 
00335 static av_cold int cinaudio_decode_init(AVCodecContext *avctx)
00336 {
00337     CinAudioContext *cin = avctx->priv_data;
00338 
00339     if (avctx->channels != 1) {
00340         av_log_ask_for_sample(avctx, "Number of channels is not supported\n");
00341         return AVERROR_PATCHWELCOME;
00342     }
00343 
00344     cin->initial_decode_frame = 1;
00345     cin->delta = 0;
00346     avctx->sample_fmt = AV_SAMPLE_FMT_S16;
00347 
00348     avcodec_get_frame_defaults(&cin->frame);
00349     avctx->coded_frame = &cin->frame;
00350 
00351     return 0;
00352 }
00353 
00354 static int cinaudio_decode_frame(AVCodecContext *avctx, void *data,
00355                                  int *got_frame_ptr, AVPacket *avpkt)
00356 {
00357     const uint8_t *buf     = avpkt->data;
00358     CinAudioContext *cin   = avctx->priv_data;
00359     const uint8_t *buf_end = buf + avpkt->size;
00360     int16_t *samples;
00361     int delta, ret;
00362 
00363     /* get output buffer */
00364     cin->frame.nb_samples = avpkt->size - cin->initial_decode_frame;
00365     if ((ret = avctx->get_buffer(avctx, &cin->frame)) < 0) {
00366         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00367         return ret;
00368     }
00369     samples = (int16_t *)cin->frame.data[0];
00370 
00371     delta = cin->delta;
00372     if (cin->initial_decode_frame) {
00373         cin->initial_decode_frame = 0;
00374         delta                     = sign_extend(AV_RL16(buf), 16);
00375         buf                      += 2;
00376         *samples++                = delta;
00377     }
00378     while (buf < buf_end) {
00379         delta     += cinaudio_delta16_table[*buf++];
00380         delta      = av_clip_int16(delta);
00381         *samples++ = delta;
00382     }
00383     cin->delta = delta;
00384 
00385     *got_frame_ptr   = 1;
00386     *(AVFrame *)data = cin->frame;
00387 
00388     return avpkt->size;
00389 }
00390 
00391 
00392 AVCodec ff_dsicinvideo_decoder = {
00393     .name           = "dsicinvideo",
00394     .type           = AVMEDIA_TYPE_VIDEO,
00395     .id             = CODEC_ID_DSICINVIDEO,
00396     .priv_data_size = sizeof(CinVideoContext),
00397     .init           = cinvideo_decode_init,
00398     .close          = cinvideo_decode_end,
00399     .decode         = cinvideo_decode_frame,
00400     .capabilities   = CODEC_CAP_DR1,
00401     .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN video"),
00402 };
00403 
00404 AVCodec ff_dsicinaudio_decoder = {
00405     .name           = "dsicinaudio",
00406     .type           = AVMEDIA_TYPE_AUDIO,
00407     .id             = CODEC_ID_DSICINAUDIO,
00408     .priv_data_size = sizeof(CinAudioContext),
00409     .init           = cinaudio_decode_init,
00410     .decode         = cinaudio_decode_frame,
00411     .capabilities   = CODEC_CAP_DR1,
00412     .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN audio"),
00413 };