Libav 0.7.1
|
00001 /* 00002 * Feeble Files/ScummVM DXA decoder 00003 * Copyright (c) 2007 Konstantin Shishkov 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 <stdio.h> 00028 #include <stdlib.h> 00029 00030 #include "libavutil/intreadwrite.h" 00031 #include "avcodec.h" 00032 00033 #include <zlib.h> 00034 00035 /* 00036 * Decoder context 00037 */ 00038 typedef struct DxaDecContext { 00039 AVCodecContext *avctx; 00040 AVFrame pic, prev; 00041 00042 int dsize; 00043 uint8_t *decomp_buf; 00044 uint32_t pal[256]; 00045 } DxaDecContext; 00046 00047 static const int shift1[6] = { 0, 8, 8, 8, 4, 4 }; 00048 static const int shift2[6] = { 0, 0, 8, 4, 0, 4 }; 00049 00050 static int decode_13(AVCodecContext *avctx, DxaDecContext *c, uint8_t* dst, uint8_t *src, uint8_t *ref) 00051 { 00052 uint8_t *code, *data, *mv, *msk, *tmp, *tmp2; 00053 int i, j, k; 00054 int type, x, y, d, d2; 00055 int stride = c->pic.linesize[0]; 00056 uint32_t mask; 00057 00058 code = src + 12; 00059 data = code + ((avctx->width * avctx->height) >> 4); 00060 mv = data + AV_RB32(src + 0); 00061 msk = mv + AV_RB32(src + 4); 00062 00063 for(j = 0; j < avctx->height; j += 4){ 00064 for(i = 0; i < avctx->width; i += 4){ 00065 tmp = dst + i; 00066 tmp2 = ref + i; 00067 type = *code++; 00068 switch(type){ 00069 case 4: // motion compensation 00070 x = (*mv) >> 4; if(x & 8) x = 8 - x; 00071 y = (*mv++) & 0xF; if(y & 8) y = 8 - y; 00072 tmp2 += x + y*stride; 00073 case 0: // skip 00074 case 5: // skip in method 12 00075 for(y = 0; y < 4; y++){ 00076 memcpy(tmp, tmp2, 4); 00077 tmp += stride; 00078 tmp2 += stride; 00079 } 00080 break; 00081 case 1: // masked change 00082 case 10: // masked change with only half of pixels changed 00083 case 11: // cases 10-15 are for method 12 only 00084 case 12: 00085 case 13: 00086 case 14: 00087 case 15: 00088 if(type == 1){ 00089 mask = AV_RB16(msk); 00090 msk += 2; 00091 }else{ 00092 type -= 10; 00093 mask = ((msk[0] & 0xF0) << shift1[type]) | ((msk[0] & 0xF) << shift2[type]); 00094 msk++; 00095 } 00096 for(y = 0; y < 4; y++){ 00097 for(x = 0; x < 4; x++){ 00098 tmp[x] = (mask & 0x8000) ? *data++ : tmp2[x]; 00099 mask <<= 1; 00100 } 00101 tmp += stride; 00102 tmp2 += stride; 00103 } 00104 break; 00105 case 2: // fill block 00106 for(y = 0; y < 4; y++){ 00107 memset(tmp, data[0], 4); 00108 tmp += stride; 00109 } 00110 data++; 00111 break; 00112 case 3: // raw block 00113 for(y = 0; y < 4; y++){ 00114 memcpy(tmp, data, 4); 00115 data += 4; 00116 tmp += stride; 00117 } 00118 break; 00119 case 8: // subblocks - method 13 only 00120 mask = *msk++; 00121 for(k = 0; k < 4; k++){ 00122 d = ((k & 1) << 1) + ((k & 2) * stride); 00123 d2 = ((k & 1) << 1) + ((k & 2) * stride); 00124 tmp2 = ref + i + d2; 00125 switch(mask & 0xC0){ 00126 case 0x80: // motion compensation 00127 x = (*mv) >> 4; if(x & 8) x = 8 - x; 00128 y = (*mv++) & 0xF; if(y & 8) y = 8 - y; 00129 tmp2 += x + y*stride; 00130 case 0x00: // skip 00131 tmp[d + 0 ] = tmp2[0]; 00132 tmp[d + 1 ] = tmp2[1]; 00133 tmp[d + 0 + stride] = tmp2[0 + stride]; 00134 tmp[d + 1 + stride] = tmp2[1 + stride]; 00135 break; 00136 case 0x40: // fill 00137 tmp[d + 0 ] = data[0]; 00138 tmp[d + 1 ] = data[0]; 00139 tmp[d + 0 + stride] = data[0]; 00140 tmp[d + 1 + stride] = data[0]; 00141 data++; 00142 break; 00143 case 0xC0: // raw 00144 tmp[d + 0 ] = *data++; 00145 tmp[d + 1 ] = *data++; 00146 tmp[d + 0 + stride] = *data++; 00147 tmp[d + 1 + stride] = *data++; 00148 break; 00149 } 00150 mask <<= 2; 00151 } 00152 break; 00153 case 32: // vector quantization - 2 colors 00154 mask = AV_RB16(msk); 00155 msk += 2; 00156 for(y = 0; y < 4; y++){ 00157 for(x = 0; x < 4; x++){ 00158 tmp[x] = data[mask & 1]; 00159 mask >>= 1; 00160 } 00161 tmp += stride; 00162 tmp2 += stride; 00163 } 00164 data += 2; 00165 break; 00166 case 33: // vector quantization - 3 or 4 colors 00167 case 34: 00168 mask = AV_RB32(msk); 00169 msk += 4; 00170 for(y = 0; y < 4; y++){ 00171 for(x = 0; x < 4; x++){ 00172 tmp[x] = data[mask & 3]; 00173 mask >>= 2; 00174 } 00175 tmp += stride; 00176 tmp2 += stride; 00177 } 00178 data += type - 30; 00179 break; 00180 default: 00181 av_log(avctx, AV_LOG_ERROR, "Unknown opcode %d\n", type); 00182 return -1; 00183 } 00184 } 00185 dst += stride * 4; 00186 ref += stride * 4; 00187 } 00188 return 0; 00189 } 00190 00191 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) 00192 { 00193 const uint8_t *buf = avpkt->data; 00194 int buf_size = avpkt->size; 00195 DxaDecContext * const c = avctx->priv_data; 00196 uint8_t *outptr, *srcptr, *tmpptr; 00197 unsigned long dsize; 00198 int i, j, compr; 00199 int stride; 00200 int orig_buf_size = buf_size; 00201 int pc = 0; 00202 00203 /* make the palette available on the way out */ 00204 if(buf[0]=='C' && buf[1]=='M' && buf[2]=='A' && buf[3]=='P'){ 00205 int r, g, b; 00206 00207 buf += 4; 00208 for(i = 0; i < 256; i++){ 00209 r = *buf++; 00210 g = *buf++; 00211 b = *buf++; 00212 c->pal[i] = (r << 16) | (g << 8) | b; 00213 } 00214 pc = 1; 00215 buf_size -= 768+4; 00216 } 00217 00218 if(avctx->get_buffer(avctx, &c->pic) < 0){ 00219 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); 00220 return -1; 00221 } 00222 memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE); 00223 c->pic.palette_has_changed = pc; 00224 00225 outptr = c->pic.data[0]; 00226 srcptr = c->decomp_buf; 00227 tmpptr = c->prev.data[0]; 00228 stride = c->pic.linesize[0]; 00229 00230 if(buf[0]=='N' && buf[1]=='U' && buf[2]=='L' && buf[3]=='L') 00231 compr = -1; 00232 else 00233 compr = buf[4]; 00234 00235 dsize = c->dsize; 00236 if((compr != 4 && compr != -1) && uncompress(c->decomp_buf, &dsize, buf + 9, buf_size - 9) != Z_OK){ 00237 av_log(avctx, AV_LOG_ERROR, "Uncompress failed!\n"); 00238 return -1; 00239 } 00240 switch(compr){ 00241 case -1: 00242 c->pic.key_frame = 0; 00243 c->pic.pict_type = AV_PICTURE_TYPE_P; 00244 if(c->prev.data[0]) 00245 memcpy(c->pic.data[0], c->prev.data[0], c->pic.linesize[0] * avctx->height); 00246 else{ // Should happen only when first frame is 'NULL' 00247 memset(c->pic.data[0], 0, c->pic.linesize[0] * avctx->height); 00248 c->pic.key_frame = 1; 00249 c->pic.pict_type = AV_PICTURE_TYPE_I; 00250 } 00251 break; 00252 case 2: 00253 case 3: 00254 case 4: 00255 case 5: 00256 c->pic.key_frame = !(compr & 1); 00257 c->pic.pict_type = (compr & 1) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; 00258 for(j = 0; j < avctx->height; j++){ 00259 if(compr & 1){ 00260 for(i = 0; i < avctx->width; i++) 00261 outptr[i] = srcptr[i] ^ tmpptr[i]; 00262 tmpptr += stride; 00263 }else 00264 memcpy(outptr, srcptr, avctx->width); 00265 outptr += stride; 00266 srcptr += avctx->width; 00267 } 00268 break; 00269 case 12: // ScummVM coding 00270 case 13: 00271 c->pic.key_frame = 0; 00272 c->pic.pict_type = AV_PICTURE_TYPE_P; 00273 decode_13(avctx, c, c->pic.data[0], srcptr, c->prev.data[0]); 00274 break; 00275 default: 00276 av_log(avctx, AV_LOG_ERROR, "Unknown/unsupported compression type %d\n", buf[4]); 00277 return -1; 00278 } 00279 00280 FFSWAP(AVFrame, c->pic, c->prev); 00281 if(c->pic.data[0]) 00282 avctx->release_buffer(avctx, &c->pic); 00283 00284 *data_size = sizeof(AVFrame); 00285 *(AVFrame*)data = c->prev; 00286 00287 /* always report that the buffer was completely consumed */ 00288 return orig_buf_size; 00289 } 00290 00291 static av_cold int decode_init(AVCodecContext *avctx) 00292 { 00293 DxaDecContext * const c = avctx->priv_data; 00294 00295 c->avctx = avctx; 00296 avctx->pix_fmt = PIX_FMT_PAL8; 00297 00298 c->dsize = avctx->width * avctx->height * 2; 00299 if((c->decomp_buf = av_malloc(c->dsize)) == NULL) { 00300 av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); 00301 return -1; 00302 } 00303 00304 return 0; 00305 } 00306 00307 static av_cold int decode_end(AVCodecContext *avctx) 00308 { 00309 DxaDecContext * const c = avctx->priv_data; 00310 00311 av_freep(&c->decomp_buf); 00312 if(c->prev.data[0]) 00313 avctx->release_buffer(avctx, &c->prev); 00314 if(c->pic.data[0]) 00315 avctx->release_buffer(avctx, &c->pic); 00316 00317 return 0; 00318 } 00319 00320 AVCodec ff_dxa_decoder = { 00321 "dxa", 00322 AVMEDIA_TYPE_VIDEO, 00323 CODEC_ID_DXA, 00324 sizeof(DxaDecContext), 00325 decode_init, 00326 NULL, 00327 decode_end, 00328 decode_frame, 00329 CODEC_CAP_DR1, 00330 .long_name = NULL_IF_CONFIG_SMALL("Feeble Files/ScummVM DXA"), 00331 }; 00332