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,
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
00174
00175
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
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
00249
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
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 };