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 avcodec_get_frame_defaults(&cin->frame);
00098 cin->frame.data[0] = NULL;
00099
00100 cin->bitmap_size = avctx->width * avctx->height;
00101 for (i = 0; i < 3; ++i) {
00102 cin->bitmap_table[i] = av_mallocz(cin->bitmap_size);
00103 if (!cin->bitmap_table[i])
00104 av_log(avctx, AV_LOG_ERROR, "Can't allocate bitmap buffers.\n");
00105 }
00106
00107 return 0;
00108 }
00109
00110 static void cin_apply_delta_data(const unsigned char *src, unsigned char *dst, int size)
00111 {
00112 while (size--)
00113 *dst++ += *src++;
00114 }
00115
00116 static int cin_decode_huffman(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
00117 {
00118 int b, huff_code = 0;
00119 unsigned char huff_code_table[15];
00120 unsigned char *dst_cur = dst;
00121 unsigned char *dst_end = dst + dst_size;
00122 const unsigned char *src_end = src + src_size;
00123
00124 memcpy(huff_code_table, src, 15); src += 15; src_size -= 15;
00125
00126 while (src < src_end) {
00127 huff_code = *src++;
00128 if ((huff_code >> 4) == 15) {
00129 b = huff_code << 4;
00130 huff_code = *src++;
00131 *dst_cur++ = b | (huff_code >> 4);
00132 } else
00133 *dst_cur++ = huff_code_table[huff_code >> 4];
00134 if (dst_cur >= dst_end)
00135 break;
00136
00137 huff_code &= 15;
00138 if (huff_code == 15) {
00139 *dst_cur++ = *src++;
00140 } else
00141 *dst_cur++ = huff_code_table[huff_code];
00142 if (dst_cur >= dst_end)
00143 break;
00144 }
00145
00146 return dst_cur - dst;
00147 }
00148
00149 static int cin_decode_lzss(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
00150 {
00151 uint16_t cmd;
00152 int i, sz, offset, code;
00153 unsigned char *dst_end = dst + dst_size, *dst_start = dst;
00154 const unsigned char *src_end = src + src_size;
00155
00156 while (src < src_end && dst < dst_end) {
00157 code = *src++;
00158 for (i = 0; i < 8 && src < src_end && dst < dst_end; ++i) {
00159 if (code & (1 << i)) {
00160 *dst++ = *src++;
00161 } else {
00162 cmd = AV_RL16(src); src += 2;
00163 offset = cmd >> 4;
00164 if ((int) (dst - dst_start) < offset + 1)
00165 return AVERROR_INVALIDDATA;
00166 sz = (cmd & 0xF) + 2;
00167
00168
00169 sz = FFMIN(sz, dst_end - dst);
00170 while (sz--) {
00171 *dst = *(dst - offset - 1);
00172 ++dst;
00173 }
00174 }
00175 }
00176 }
00177
00178 return 0;
00179 }
00180
00181 static void cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
00182 {
00183 int len, code;
00184 unsigned char *dst_end = dst + dst_size;
00185 const unsigned char *src_end = src + src_size;
00186
00187 while (src < src_end && dst < dst_end) {
00188 code = *src++;
00189 if (code & 0x80) {
00190 len = code - 0x7F;
00191 memset(dst, *src++, FFMIN(len, dst_end - dst));
00192 } else {
00193 len = code + 1;
00194 memcpy(dst, src, FFMIN(len, dst_end - dst));
00195 src += len;
00196 }
00197 dst += len;
00198 }
00199 }
00200
00201 static int cinvideo_decode_frame(AVCodecContext *avctx,
00202 void *data, int *data_size,
00203 AVPacket *avpkt)
00204 {
00205 const uint8_t *buf = avpkt->data;
00206 int buf_size = avpkt->size;
00207 CinVideoContext *cin = avctx->priv_data;
00208 int i, y, palette_type, palette_colors_count, bitmap_frame_type, bitmap_frame_size, res = 0;
00209
00210 palette_type = buf[0];
00211 palette_colors_count = AV_RL16(buf+1);
00212 bitmap_frame_type = buf[3];
00213 buf += 4;
00214
00215 bitmap_frame_size = buf_size - 4;
00216
00217
00218 if (bitmap_frame_size < palette_colors_count * (3 + (palette_type != 0)))
00219 return AVERROR_INVALIDDATA;
00220 if (palette_type == 0) {
00221 if (palette_colors_count > 256)
00222 return AVERROR_INVALIDDATA;
00223 for (i = 0; i < palette_colors_count; ++i) {
00224 cin->palette[i] = bytestream_get_le24(&buf);
00225 bitmap_frame_size -= 3;
00226 }
00227 } else {
00228 for (i = 0; i < palette_colors_count; ++i) {
00229 cin->palette[buf[0]] = AV_RL24(buf+1);
00230 buf += 4;
00231 bitmap_frame_size -= 4;
00232 }
00233 }
00234
00235
00236 switch (bitmap_frame_type) {
00237 case 9:
00238 cin_decode_rle(buf, bitmap_frame_size,
00239 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00240 break;
00241 case 34:
00242 cin_decode_rle(buf, bitmap_frame_size,
00243 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00244 cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
00245 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00246 break;
00247 case 35:
00248 cin_decode_huffman(buf, bitmap_frame_size,
00249 cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
00250 cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
00251 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00252 break;
00253 case 36:
00254 bitmap_frame_size = cin_decode_huffman(buf, bitmap_frame_size,
00255 cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
00256 cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
00257 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00258 cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
00259 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00260 break;
00261 case 37:
00262 cin_decode_huffman(buf, bitmap_frame_size,
00263 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00264 break;
00265 case 38:
00266 res = cin_decode_lzss(buf, bitmap_frame_size,
00267 cin->bitmap_table[CIN_CUR_BMP],
00268 cin->bitmap_size);
00269 if (res < 0)
00270 return res;
00271 break;
00272 case 39:
00273 res = cin_decode_lzss(buf, bitmap_frame_size,
00274 cin->bitmap_table[CIN_CUR_BMP],
00275 cin->bitmap_size);
00276 if (res < 0)
00277 return res;
00278 cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
00279 cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
00280 break;
00281 }
00282
00283 cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
00284 if (avctx->reget_buffer(avctx, &cin->frame)) {
00285 av_log(cin->avctx, AV_LOG_ERROR, "delphinecinvideo: reget_buffer() failed to allocate a frame\n");
00286 return -1;
00287 }
00288
00289 memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette));
00290 cin->frame.palette_has_changed = 1;
00291 for (y = 0; y < cin->avctx->height; ++y)
00292 memcpy(cin->frame.data[0] + (cin->avctx->height - 1 - y) * cin->frame.linesize[0],
00293 cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width,
00294 cin->avctx->width);
00295
00296 FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_table[CIN_PRE_BMP]);
00297
00298 *data_size = sizeof(AVFrame);
00299 *(AVFrame *)data = cin->frame;
00300
00301 return buf_size;
00302 }
00303
00304 static av_cold int cinvideo_decode_end(AVCodecContext *avctx)
00305 {
00306 CinVideoContext *cin = avctx->priv_data;
00307 int i;
00308
00309 if (cin->frame.data[0])
00310 avctx->release_buffer(avctx, &cin->frame);
00311
00312 for (i = 0; i < 3; ++i)
00313 av_free(cin->bitmap_table[i]);
00314
00315 return 0;
00316 }
00317
00318 static av_cold int cinaudio_decode_init(AVCodecContext *avctx)
00319 {
00320 CinAudioContext *cin = avctx->priv_data;
00321
00322 cin->avctx = avctx;
00323 if (avctx->channels != 1) {
00324 av_log_ask_for_sample(avctx, "Number of channels is not supported\n");
00325 return AVERROR_PATCHWELCOME;
00326 }
00327
00328 cin->initial_decode_frame = 1;
00329 cin->delta = 0;
00330 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
00331
00332 return 0;
00333 }
00334
00335 static int cinaudio_decode_frame(AVCodecContext *avctx,
00336 void *data, int *data_size,
00337 AVPacket *avpkt)
00338 {
00339 const uint8_t *buf = avpkt->data;
00340 int buf_size = avpkt->size;
00341 CinAudioContext *cin = avctx->priv_data;
00342 const uint8_t *src = buf;
00343 int16_t *samples = (int16_t *)data;
00344
00345 buf_size = FFMIN(buf_size, *data_size/2);
00346
00347 if (cin->initial_decode_frame) {
00348 cin->initial_decode_frame = 0;
00349 cin->delta = (int16_t)AV_RL16(src); src += 2;
00350 *samples++ = cin->delta;
00351 buf_size -= 2;
00352 }
00353 while (buf_size > 0) {
00354 cin->delta += cinaudio_delta16_table[*src++];
00355 cin->delta = av_clip_int16(cin->delta);
00356 *samples++ = cin->delta;
00357 --buf_size;
00358 }
00359
00360 *data_size = (uint8_t *)samples - (uint8_t *)data;
00361
00362 return src - buf;
00363 }
00364
00365
00366 AVCodec ff_dsicinvideo_decoder = {
00367 "dsicinvideo",
00368 AVMEDIA_TYPE_VIDEO,
00369 CODEC_ID_DSICINVIDEO,
00370 sizeof(CinVideoContext),
00371 cinvideo_decode_init,
00372 NULL,
00373 cinvideo_decode_end,
00374 cinvideo_decode_frame,
00375 CODEC_CAP_DR1,
00376 .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN video"),
00377 };
00378
00379 AVCodec ff_dsicinaudio_decoder = {
00380 "dsicinaudio",
00381 AVMEDIA_TYPE_AUDIO,
00382 CODEC_ID_DSICINAUDIO,
00383 sizeof(CinAudioContext),
00384 cinaudio_decode_init,
00385 NULL,
00386 NULL,
00387 cinaudio_decode_frame,
00388 .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN audio"),
00389 };