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