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