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