00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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,
00034 CIN_PRE_BMP = 1,
00035 CIN_INT_BMP = 2
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
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
00166
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
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
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
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 };