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 AVPacket *avpkt)
00199 {
00200 const uint8_t *buf = avpkt->data;
00201 int buf_size = avpkt->size;
00202 CinVideoContext *cin = avctx->priv_data;
00203 int i, y, palette_type, palette_colors_count, bitmap_frame_type, bitmap_frame_size;
00204
00205 cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
00206 if (avctx->reget_buffer(avctx, &cin->frame)) {
00207 av_log(cin->avctx, AV_LOG_ERROR, "delphinecinvideo: reget_buffer() failed to allocate a frame\n");
00208 return -1;
00209 }
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 (palette_type == 0) {
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 AVPacket *avpkt)
00318 {
00319 const uint8_t *buf = avpkt->data;
00320 int buf_size = avpkt->size;
00321 CinAudioContext *cin = avctx->priv_data;
00322 const uint8_t *src = buf;
00323 int16_t *samples = (int16_t *)data;
00324
00325 buf_size = FFMIN(buf_size, *data_size/2);
00326
00327 if (cin->initial_decode_frame) {
00328 cin->initial_decode_frame = 0;
00329 cin->delta = (int16_t)AV_RL16(src); src += 2;
00330 *samples++ = cin->delta;
00331 buf_size -= 2;
00332 }
00333 while (buf_size > 0) {
00334 cin->delta += cinaudio_delta16_table[*src++];
00335 cin->delta = av_clip_int16(cin->delta);
00336 *samples++ = cin->delta;
00337 --buf_size;
00338 }
00339
00340 *data_size = (uint8_t *)samples - (uint8_t *)data;
00341
00342 return src - buf;
00343 }
00344
00345
00346 AVCodec dsicinvideo_decoder = {
00347 "dsicinvideo",
00348 AVMEDIA_TYPE_VIDEO,
00349 CODEC_ID_DSICINVIDEO,
00350 sizeof(CinVideoContext),
00351 cinvideo_decode_init,
00352 NULL,
00353 cinvideo_decode_end,
00354 cinvideo_decode_frame,
00355 CODEC_CAP_DR1,
00356 .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN video"),
00357 };
00358
00359 AVCodec dsicinaudio_decoder = {
00360 "dsicinaudio",
00361 AVMEDIA_TYPE_AUDIO,
00362 CODEC_ID_DSICINAUDIO,
00363 sizeof(CinAudioContext),
00364 cinaudio_decode_init,
00365 NULL,
00366 NULL,
00367 cinaudio_decode_frame,
00368 .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN audio"),
00369 };