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