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