Libav 0.7.1
|
00001 /* 00002 * Delphine Software International CIN Audio/Video Decoders 00003 * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net) 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * Libav is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with Libav; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00027 #include "avcodec.h" 00028 #include "bytestream.h" 00029 00030 00031 typedef enum CinVideoBitmapIndex { 00032 CIN_CUR_BMP = 0, /* current */ 00033 CIN_PRE_BMP = 1, /* previous */ 00034 CIN_INT_BMP = 2 /* intermediate */ 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 /* table defining a geometric sequence with multiplier = 32767 ^ (1 / 128) */ 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 /* don't use memcpy/memmove here as the decoding routine (ab)uses */ 00165 /* buffer overlappings to repeat bytes in the destination */ 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 /* handle palette */ 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 /* note: the decoding routines below assumes that surface.width = surface.pitch */ 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 = AV_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 ff_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 ff_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 };