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 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 for (i = 0; i < palette_colors_count; ++i) {
00219 cin->palette[i] = bytestream_get_le24(&buf);
00220 bitmap_frame_size -= 3;
00221 }
00222 } else {
00223 for (i = 0; i < palette_colors_count; ++i) {
00224 cin->palette[buf[0]] = AV_RL24(buf+1);
00225 buf += 4;
00226 bitmap_frame_size -= 4;
00227 }
00228 }
00229 memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette));
00230 cin->frame.palette_has_changed = 1;
00231
00232
00233 switch (bitmap_frame_type) {
00234 case 9:
00235 cin_decode_rle(buf, bitmap_frame_size,
00236 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00237 break;
00238 case 34:
00239 cin_decode_rle(buf, bitmap_frame_size,
00240 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00241 cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
00242 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00243 break;
00244 case 35:
00245 cin_decode_huffman(buf, bitmap_frame_size,
00246 cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
00247 cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
00248 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00249 break;
00250 case 36:
00251 bitmap_frame_size = cin_decode_huffman(buf, bitmap_frame_size,
00252 cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
00253 cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
00254 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00255 cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
00256 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00257 break;
00258 case 37:
00259 cin_decode_huffman(buf, bitmap_frame_size,
00260 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00261 break;
00262 case 38:
00263 cin_decode_lzss(buf, bitmap_frame_size,
00264 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00265 break;
00266 case 39:
00267 cin_decode_lzss(buf, bitmap_frame_size,
00268 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00269 cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
00270 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00271 break;
00272 }
00273
00274 for (y = 0; y < cin->avctx->height; ++y)
00275 memcpy(cin->frame.data[0] + (cin->avctx->height - 1 - y) * cin->frame.linesize[0],
00276 cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width,
00277 cin->avctx->width);
00278
00279 FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_table[CIN_PRE_BMP]);
00280
00281 *data_size = sizeof(AVFrame);
00282 *(AVFrame *)data = cin->frame;
00283
00284 return buf_size;
00285 }
00286
00287 static int cinvideo_decode_end(AVCodecContext *avctx)
00288 {
00289 CinVideoContext *cin = avctx->priv_data;
00290 int i;
00291
00292 if (cin->frame.data[0])
00293 avctx->release_buffer(avctx, &cin->frame);
00294
00295 for (i = 0; i < 3; ++i)
00296 av_free(cin->bitmap_table[i]);
00297
00298 return 0;
00299 }
00300
00301 static int cinaudio_decode_init(AVCodecContext *avctx)
00302 {
00303 CinAudioContext *cin = avctx->priv_data;
00304
00305 cin->avctx = avctx;
00306 cin->initial_decode_frame = 1;
00307 cin->delta = 0;
00308
00309 return 0;
00310 }
00311
00312 static int cinaudio_decode_frame(AVCodecContext *avctx,
00313 void *data, int *data_size,
00314 const uint8_t *buf, int buf_size)
00315 {
00316 CinAudioContext *cin = avctx->priv_data;
00317 const uint8_t *src = buf;
00318 int16_t *samples = (int16_t *)data;
00319
00320 buf_size = FFMIN(buf_size, *data_size/2);
00321
00322 if (cin->initial_decode_frame) {
00323 cin->initial_decode_frame = 0;
00324 cin->delta = (int16_t)AV_RL16(src); src += 2;
00325 *samples++ = cin->delta;
00326 buf_size -= 2;
00327 }
00328 while (buf_size > 0) {
00329 cin->delta += cinaudio_delta16_table[*src++];
00330 cin->delta = av_clip_int16(cin->delta);
00331 *samples++ = cin->delta;
00332 --buf_size;
00333 }
00334
00335 *data_size = (uint8_t *)samples - (uint8_t *)data;
00336
00337 return src - buf;
00338 }
00339
00340
00341 AVCodec dsicinvideo_decoder = {
00342 "dsicinvideo",
00343 CODEC_TYPE_VIDEO,
00344 CODEC_ID_DSICINVIDEO,
00345 sizeof(CinVideoContext),
00346 cinvideo_decode_init,
00347 NULL,
00348 cinvideo_decode_end,
00349 cinvideo_decode_frame,
00350 CODEC_CAP_DR1,
00351 };
00352
00353 AVCodec dsicinaudio_decoder = {
00354 "dsicinaudio",
00355 CODEC_TYPE_AUDIO,
00356 CODEC_ID_DSICINAUDIO,
00357 sizeof(CinAudioContext),
00358 cinaudio_decode_init,
00359 NULL,
00360 NULL,
00361 cinaudio_decode_frame,
00362 };