00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include "libavutil/channel_layout.h"
00028 #include "avcodec.h"
00029 #include "bytestream.h"
00030 #include "internal.h"
00031 #include "mathops.h"
00032
00033
00034 typedef enum CinVideoBitmapIndex {
00035 CIN_CUR_BMP = 0,
00036 CIN_PRE_BMP = 1,
00037 CIN_INT_BMP = 2
00038 } CinVideoBitmapIndex;
00039
00040 typedef struct CinVideoContext {
00041 AVCodecContext *avctx;
00042 AVFrame frame;
00043 unsigned int bitmap_size;
00044 uint32_t palette[256];
00045 uint8_t *bitmap_table[3];
00046 } CinVideoContext;
00047
00048 typedef struct CinAudioContext {
00049 AVFrame frame;
00050 int initial_decode_frame;
00051 int delta;
00052 } CinAudioContext;
00053
00054
00055
00056 static const int16_t cinaudio_delta16_table[256] = {
00057 0, 0, 0, 0, 0, 0, 0, 0,
00058 0, 0, 0, 0, 0, 0, 0, 0,
00059 0, 0, 0, -30210, -27853, -25680, -23677, -21829,
00060 -20126, -18556, -17108, -15774, -14543, -13408, -12362, -11398,
00061 -10508, -9689, -8933, -8236, -7593, -7001, -6455, -5951,
00062 -5487, -5059, -4664, -4300, -3964, -3655, -3370, -3107,
00063 -2865, -2641, -2435, -2245, -2070, -1908, -1759, -1622,
00064 -1495, -1379, -1271, -1172, -1080, -996, -918, -847,
00065 -781, -720, -663, -612, -564, -520, -479, -442,
00066 -407, -376, -346, -319, -294, -271, -250, -230,
00067 -212, -196, -181, -166, -153, -141, -130, -120,
00068 -111, -102, -94, -87, -80, -74, -68, -62,
00069 -58, -53, -49, -45, -41, -38, -35, -32,
00070 -30, -27, -25, -23, -21, -20, -18, -17,
00071 -15, -14, -13, -12, -11, -10, -9, -8,
00072 -7, -6, -5, -4, -3, -2, -1, 0,
00073 0, 1, 2, 3, 4, 5, 6, 7,
00074 8, 9, 10, 11, 12, 13, 14, 15,
00075 17, 18, 20, 21, 23, 25, 27, 30,
00076 32, 35, 38, 41, 45, 49, 53, 58,
00077 62, 68, 74, 80, 87, 94, 102, 111,
00078 120, 130, 141, 153, 166, 181, 196, 212,
00079 230, 250, 271, 294, 319, 346, 376, 407,
00080 442, 479, 520, 564, 612, 663, 720, 781,
00081 847, 918, 996, 1080, 1172, 1271, 1379, 1495,
00082 1622, 1759, 1908, 2070, 2245, 2435, 2641, 2865,
00083 3107, 3370, 3655, 3964, 4300, 4664, 5059, 5487,
00084 5951, 6455, 7001, 7593, 8236, 8933, 9689, 10508,
00085 11398, 12362, 13408, 14543, 15774, 17108, 18556, 20126,
00086 21829, 23677, 25680, 27853, 30210, 0, 0, 0,
00087 0, 0, 0, 0, 0, 0, 0, 0,
00088 0, 0, 0, 0, 0, 0, 0, 0
00089 };
00090
00091 static av_cold void destroy_buffers(CinVideoContext *cin)
00092 {
00093 int i;
00094
00095 for (i = 0; i < 3; ++i)
00096 av_freep(&cin->bitmap_table[i]);
00097 }
00098
00099 static av_cold int allocate_buffers(CinVideoContext *cin)
00100 {
00101 int i;
00102
00103 for (i = 0; i < 3; ++i) {
00104 cin->bitmap_table[i] = av_mallocz(cin->bitmap_size);
00105 if (!cin->bitmap_table[i]) {
00106 av_log(cin->avctx, AV_LOG_ERROR, "Can't allocate bitmap buffers.\n");
00107 destroy_buffers(cin);
00108 return AVERROR(ENOMEM);
00109 }
00110 }
00111
00112 return 0;
00113 }
00114
00115 static av_cold int cinvideo_decode_init(AVCodecContext *avctx)
00116 {
00117 CinVideoContext *cin = avctx->priv_data;
00118
00119 cin->avctx = avctx;
00120 avctx->pix_fmt = AV_PIX_FMT_PAL8;
00121
00122 avcodec_get_frame_defaults(&cin->frame);
00123
00124 cin->bitmap_size = avctx->width * avctx->height;
00125 if (allocate_buffers(cin))
00126 return AVERROR(ENOMEM);
00127
00128 return 0;
00129 }
00130
00131 static void cin_apply_delta_data(const unsigned char *src, unsigned char *dst, int size)
00132 {
00133 while (size--)
00134 *dst++ += *src++;
00135 }
00136
00137 static int cin_decode_huffman(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
00138 {
00139 int b, huff_code = 0;
00140 unsigned char huff_code_table[15];
00141 unsigned char *dst_cur = dst;
00142 unsigned char *dst_end = dst + dst_size;
00143 const unsigned char *src_end = src + src_size;
00144
00145 memcpy(huff_code_table, src, 15); src += 15;
00146
00147 while (src < src_end) {
00148 huff_code = *src++;
00149 if ((huff_code >> 4) == 15) {
00150 b = huff_code << 4;
00151 huff_code = *src++;
00152 *dst_cur++ = b | (huff_code >> 4);
00153 } else
00154 *dst_cur++ = huff_code_table[huff_code >> 4];
00155 if (dst_cur >= dst_end)
00156 break;
00157
00158 huff_code &= 15;
00159 if (huff_code == 15) {
00160 *dst_cur++ = *src++;
00161 } else
00162 *dst_cur++ = huff_code_table[huff_code];
00163 if (dst_cur >= dst_end)
00164 break;
00165 }
00166
00167 return dst_cur - dst;
00168 }
00169
00170 static int cin_decode_lzss(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
00171 {
00172 uint16_t cmd;
00173 int i, sz, offset, code;
00174 unsigned char *dst_end = dst + dst_size, *dst_start = dst;
00175 const unsigned char *src_end = src + src_size;
00176
00177 while (src < src_end && dst < dst_end) {
00178 code = *src++;
00179 for (i = 0; i < 8 && src < src_end && dst < dst_end; ++i) {
00180 if (code & (1 << i)) {
00181 *dst++ = *src++;
00182 } else {
00183 cmd = AV_RL16(src); src += 2;
00184 offset = cmd >> 4;
00185 if ((int) (dst - dst_start) < offset + 1)
00186 return AVERROR_INVALIDDATA;
00187 sz = (cmd & 0xF) + 2;
00188
00189
00190 sz = FFMIN(sz, dst_end - dst);
00191 while (sz--) {
00192 *dst = *(dst - offset - 1);
00193 ++dst;
00194 }
00195 }
00196 }
00197 }
00198
00199 return 0;
00200 }
00201
00202 static int cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
00203 {
00204 int len, code;
00205 unsigned char *dst_end = dst + dst_size;
00206 const unsigned char *src_end = src + src_size;
00207
00208 while (src + 1 < src_end && dst < dst_end) {
00209 code = *src++;
00210 if (code & 0x80) {
00211 len = code - 0x7F;
00212 memset(dst, *src++, FFMIN(len, dst_end - dst));
00213 } else {
00214 len = code + 1;
00215 if (len > src_end-src) {
00216 av_log(NULL, AV_LOG_ERROR, "RLE overread\n");
00217 return AVERROR_INVALIDDATA;
00218 }
00219 memcpy(dst, src, FFMIN(len, dst_end - dst));
00220 src += len;
00221 }
00222 dst += len;
00223 }
00224 return 0;
00225 }
00226
00227 static int cinvideo_decode_frame(AVCodecContext *avctx,
00228 void *data, int *got_frame,
00229 AVPacket *avpkt)
00230 {
00231 const uint8_t *buf = avpkt->data;
00232 int buf_size = avpkt->size;
00233 CinVideoContext *cin = avctx->priv_data;
00234 int i, y, palette_type, palette_colors_count, bitmap_frame_type, bitmap_frame_size, res = 0;
00235
00236 palette_type = buf[0];
00237 palette_colors_count = AV_RL16(buf+1);
00238 bitmap_frame_type = buf[3];
00239 buf += 4;
00240
00241 bitmap_frame_size = buf_size - 4;
00242
00243
00244 if (bitmap_frame_size < palette_colors_count * (3 + (palette_type != 0)))
00245 return AVERROR_INVALIDDATA;
00246 if (palette_type == 0) {
00247 if (palette_colors_count > 256)
00248 return AVERROR_INVALIDDATA;
00249 for (i = 0; i < palette_colors_count; ++i) {
00250 cin->palette[i] = 0xFFU << 24 | bytestream_get_le24(&buf);
00251 bitmap_frame_size -= 3;
00252 }
00253 } else {
00254 for (i = 0; i < palette_colors_count; ++i) {
00255 cin->palette[buf[0]] = 0xFFU << 24 | AV_RL24(buf+1);
00256 buf += 4;
00257 bitmap_frame_size -= 4;
00258 }
00259 }
00260
00261
00262 switch (bitmap_frame_type) {
00263 case 9:
00264 cin_decode_rle(buf, bitmap_frame_size,
00265 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00266 break;
00267 case 34:
00268 cin_decode_rle(buf, bitmap_frame_size,
00269 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00270 cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
00271 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00272 break;
00273 case 35:
00274 bitmap_frame_size = cin_decode_huffman(buf, bitmap_frame_size,
00275 cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
00276 cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
00277 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00278 break;
00279 case 36:
00280 bitmap_frame_size = cin_decode_huffman(buf, bitmap_frame_size,
00281 cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
00282 cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
00283 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00284 cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
00285 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00286 break;
00287 case 37:
00288 cin_decode_huffman(buf, bitmap_frame_size,
00289 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00290 break;
00291 case 38:
00292 res = cin_decode_lzss(buf, bitmap_frame_size,
00293 cin->bitmap_table[CIN_CUR_BMP],
00294 cin->bitmap_size);
00295 if (res < 0)
00296 return res;
00297 break;
00298 case 39:
00299 res = cin_decode_lzss(buf, bitmap_frame_size,
00300 cin->bitmap_table[CIN_CUR_BMP],
00301 cin->bitmap_size);
00302 if (res < 0)
00303 return res;
00304 cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
00305 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00306 break;
00307 }
00308
00309 cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
00310 if ((res = avctx->reget_buffer(avctx, &cin->frame))) {
00311 av_log(cin->avctx, AV_LOG_ERROR, "failed to allocate a frame\n");
00312 return res;
00313 }
00314
00315 memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette));
00316 cin->frame.palette_has_changed = 1;
00317 for (y = 0; y < cin->avctx->height; ++y)
00318 memcpy(cin->frame.data[0] + (cin->avctx->height - 1 - y) * cin->frame.linesize[0],
00319 cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width,
00320 cin->avctx->width);
00321
00322 FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_table[CIN_PRE_BMP]);
00323
00324 *got_frame = 1;
00325 *(AVFrame *)data = cin->frame;
00326
00327 return buf_size;
00328 }
00329
00330 static av_cold int cinvideo_decode_end(AVCodecContext *avctx)
00331 {
00332 CinVideoContext *cin = avctx->priv_data;
00333
00334 if (cin->frame.data[0])
00335 avctx->release_buffer(avctx, &cin->frame);
00336
00337 destroy_buffers(cin);
00338
00339 return 0;
00340 }
00341
00342 static av_cold int cinaudio_decode_init(AVCodecContext *avctx)
00343 {
00344 CinAudioContext *cin = avctx->priv_data;
00345
00346 cin->initial_decode_frame = 1;
00347 cin->delta = 0;
00348 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
00349 avctx->channels = 1;
00350 avctx->channel_layout = AV_CH_LAYOUT_MONO;
00351
00352 avcodec_get_frame_defaults(&cin->frame);
00353 avctx->coded_frame = &cin->frame;
00354
00355 return 0;
00356 }
00357
00358 static int cinaudio_decode_frame(AVCodecContext *avctx, void *data,
00359 int *got_frame_ptr, AVPacket *avpkt)
00360 {
00361 const uint8_t *buf = avpkt->data;
00362 CinAudioContext *cin = avctx->priv_data;
00363 const uint8_t *buf_end = buf + avpkt->size;
00364 int16_t *samples;
00365 int delta, ret;
00366
00367
00368 cin->frame.nb_samples = avpkt->size - cin->initial_decode_frame;
00369 if ((ret = ff_get_buffer(avctx, &cin->frame)) < 0) {
00370 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00371 return ret;
00372 }
00373 samples = (int16_t *)cin->frame.data[0];
00374
00375 delta = cin->delta;
00376 if (cin->initial_decode_frame) {
00377 cin->initial_decode_frame = 0;
00378 delta = sign_extend(AV_RL16(buf), 16);
00379 buf += 2;
00380 *samples++ = delta;
00381 }
00382 while (buf < buf_end) {
00383 delta += cinaudio_delta16_table[*buf++];
00384 delta = av_clip_int16(delta);
00385 *samples++ = delta;
00386 }
00387 cin->delta = delta;
00388
00389 *got_frame_ptr = 1;
00390 *(AVFrame *)data = cin->frame;
00391
00392 return avpkt->size;
00393 }
00394
00395
00396 AVCodec ff_dsicinvideo_decoder = {
00397 .name = "dsicinvideo",
00398 .type = AVMEDIA_TYPE_VIDEO,
00399 .id = AV_CODEC_ID_DSICINVIDEO,
00400 .priv_data_size = sizeof(CinVideoContext),
00401 .init = cinvideo_decode_init,
00402 .close = cinvideo_decode_end,
00403 .decode = cinvideo_decode_frame,
00404 .capabilities = CODEC_CAP_DR1,
00405 .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN video"),
00406 };
00407
00408 AVCodec ff_dsicinaudio_decoder = {
00409 .name = "dsicinaudio",
00410 .type = AVMEDIA_TYPE_AUDIO,
00411 .id = AV_CODEC_ID_DSICINAUDIO,
00412 .priv_data_size = sizeof(CinAudioContext),
00413 .init = cinaudio_decode_init,
00414 .decode = cinaudio_decode_frame,
00415 .capabilities = CODEC_CAP_DR1,
00416 .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN audio"),
00417 };