Libav 0.7.1
|
00001 /* 00002 * Wing Commander/Xan Video Decoder 00003 * Copyright (C) 2011 Konstantin Shishkov 00004 * based on work by Mike Melanson 00005 * 00006 * This file is part of Libav. 00007 * 00008 * Libav is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * Libav is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with Libav; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00023 #include "avcodec.h" 00024 #include "libavutil/intreadwrite.h" 00025 #include "bytestream.h" 00026 #define ALT_BITSTREAM_READER_LE 00027 #include "get_bits.h" 00028 // for av_memcpy_backptr 00029 #include "libavutil/lzo.h" 00030 00031 typedef struct XanContext { 00032 AVCodecContext *avctx; 00033 AVFrame pic; 00034 00035 uint8_t *y_buffer; 00036 uint8_t *scratch_buffer; 00037 int buffer_size; 00038 } XanContext; 00039 00040 static av_cold int xan_decode_init(AVCodecContext *avctx) 00041 { 00042 XanContext *s = avctx->priv_data; 00043 00044 s->avctx = avctx; 00045 00046 avctx->pix_fmt = PIX_FMT_YUV420P; 00047 00048 s->buffer_size = avctx->width * avctx->height; 00049 s->y_buffer = av_malloc(s->buffer_size); 00050 if (!s->y_buffer) 00051 return AVERROR(ENOMEM); 00052 s->scratch_buffer = av_malloc(s->buffer_size + 130); 00053 if (!s->scratch_buffer) { 00054 av_freep(&s->y_buffer); 00055 return AVERROR(ENOMEM); 00056 } 00057 00058 return 0; 00059 } 00060 00061 static int xan_unpack_luma(const uint8_t *src, const int src_size, 00062 uint8_t *dst, const int dst_size) 00063 { 00064 int tree_size, eof; 00065 const uint8_t *tree; 00066 int bits, mask; 00067 int tree_root, node; 00068 const uint8_t *dst_end = dst + dst_size; 00069 const uint8_t *src_end = src + src_size; 00070 00071 tree_size = *src++; 00072 eof = *src++; 00073 tree = src - eof * 2 - 2; 00074 tree_root = eof + tree_size; 00075 src += tree_size * 2; 00076 00077 node = tree_root; 00078 bits = *src++; 00079 mask = 0x80; 00080 for (;;) { 00081 int bit = !!(bits & mask); 00082 mask >>= 1; 00083 node = tree[node*2 + bit]; 00084 if (node == eof) 00085 break; 00086 if (node < eof) { 00087 *dst++ = node; 00088 if (dst > dst_end) 00089 break; 00090 node = tree_root; 00091 } 00092 if (!mask) { 00093 bits = *src++; 00094 if (src > src_end) 00095 break; 00096 mask = 0x80; 00097 } 00098 } 00099 return dst != dst_end; 00100 } 00101 00102 /* almost the same as in xan_wc3 decoder */ 00103 static int xan_unpack(uint8_t *dest, const int dest_len, 00104 const uint8_t *src, const int src_len) 00105 { 00106 uint8_t opcode; 00107 int size; 00108 uint8_t *orig_dest = dest; 00109 const uint8_t *src_end = src + src_len; 00110 const uint8_t *dest_end = dest + dest_len; 00111 00112 while (dest < dest_end) { 00113 opcode = *src++; 00114 00115 if (opcode < 0xe0) { 00116 int size2, back; 00117 if ((opcode & 0x80) == 0) { 00118 size = opcode & 3; 00119 back = ((opcode & 0x60) << 3) + *src++ + 1; 00120 size2 = ((opcode & 0x1c) >> 2) + 3; 00121 } else if ((opcode & 0x40) == 0) { 00122 size = *src >> 6; 00123 back = (bytestream_get_be16(&src) & 0x3fff) + 1; 00124 size2 = (opcode & 0x3f) + 4; 00125 } else { 00126 size = opcode & 3; 00127 back = ((opcode & 0x10) << 12) + bytestream_get_be16(&src) + 1; 00128 size2 = ((opcode & 0x0c) << 6) + *src++ + 5; 00129 if (size + size2 > dest_end - dest) 00130 break; 00131 } 00132 if (src + size > src_end || dest + size + size2 > dest_end || 00133 dest - orig_dest + size < back) 00134 return -1; 00135 bytestream_get_buffer(&src, dest, size); 00136 dest += size; 00137 av_memcpy_backptr(dest, back, size2); 00138 dest += size2; 00139 } else { 00140 int finish = opcode >= 0xfc; 00141 00142 size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4; 00143 if (src + size > src_end || dest + size > dest_end) 00144 return -1; 00145 bytestream_get_buffer(&src, dest, size); 00146 dest += size; 00147 if (finish) 00148 break; 00149 } 00150 } 00151 return dest - orig_dest; 00152 } 00153 00154 static int xan_decode_chroma(AVCodecContext *avctx, AVPacket *avpkt) 00155 { 00156 const uint8_t *buf = avpkt->data; 00157 XanContext *s = avctx->priv_data; 00158 uint8_t *U, *V; 00159 unsigned chroma_off; 00160 int val, uval, vval; 00161 int i, j; 00162 const uint8_t *src, *src_end; 00163 const uint8_t *table; 00164 int mode, offset, dec_size; 00165 00166 chroma_off = AV_RL32(buf + 4); 00167 if (!chroma_off) 00168 return 0; 00169 if (chroma_off + 10 >= avpkt->size) { 00170 av_log(avctx, AV_LOG_ERROR, "Invalid chroma block position\n"); 00171 return -1; 00172 } 00173 src = avpkt->data + 4 + chroma_off; 00174 table = src + 2; 00175 mode = bytestream_get_le16(&src); 00176 offset = bytestream_get_le16(&src) * 2; 00177 00178 if (src - avpkt->data >= avpkt->size - offset) { 00179 av_log(avctx, AV_LOG_ERROR, "Invalid chroma block offset\n"); 00180 return -1; 00181 } 00182 00183 memset(s->scratch_buffer, 0, s->buffer_size); 00184 dec_size = xan_unpack(s->scratch_buffer, s->buffer_size, src + offset, 00185 avpkt->size - offset - (src - avpkt->data)); 00186 if (dec_size < 0) { 00187 av_log(avctx, AV_LOG_ERROR, "Chroma unpacking failed\n"); 00188 return -1; 00189 } 00190 00191 U = s->pic.data[1]; 00192 V = s->pic.data[2]; 00193 src = s->scratch_buffer; 00194 src_end = src + dec_size; 00195 if (mode) { 00196 for (j = 0; j < avctx->height >> 1; j++) { 00197 for (i = 0; i < avctx->width >> 1; i++) { 00198 val = *src++; 00199 if (val) { 00200 val = AV_RL16(table + (val << 1)); 00201 uval = (val >> 3) & 0xF8; 00202 vval = (val >> 8) & 0xF8; 00203 U[i] = uval | (uval >> 5); 00204 V[i] = vval | (vval >> 5); 00205 } 00206 if (src == src_end) 00207 return 0; 00208 } 00209 U += s->pic.linesize[1]; 00210 V += s->pic.linesize[2]; 00211 } 00212 } else { 00213 uint8_t *U2 = U + s->pic.linesize[1]; 00214 uint8_t *V2 = V + s->pic.linesize[2]; 00215 00216 for (j = 0; j < avctx->height >> 2; j++) { 00217 for (i = 0; i < avctx->width >> 1; i += 2) { 00218 val = *src++; 00219 if (val) { 00220 val = AV_RL16(table + (val << 1)); 00221 uval = (val >> 3) & 0xF8; 00222 vval = (val >> 8) & 0xF8; 00223 U[i] = U[i+1] = U2[i] = U2[i+1] = uval | (uval >> 5); 00224 V[i] = V[i+1] = V2[i] = V2[i+1] = vval | (vval >> 5); 00225 } 00226 } 00227 U += s->pic.linesize[1] * 2; 00228 V += s->pic.linesize[2] * 2; 00229 U2 += s->pic.linesize[1] * 2; 00230 V2 += s->pic.linesize[2] * 2; 00231 } 00232 } 00233 00234 return 0; 00235 } 00236 00237 static int xan_decode_frame_type0(AVCodecContext *avctx, AVPacket *avpkt) 00238 { 00239 const uint8_t *buf = avpkt->data; 00240 XanContext *s = avctx->priv_data; 00241 uint8_t *ybuf, *prev_buf, *src = s->scratch_buffer; 00242 unsigned chroma_off, corr_off; 00243 int cur, last, size; 00244 int i, j; 00245 int ret; 00246 00247 corr_off = AV_RL32(buf + 8); 00248 chroma_off = AV_RL32(buf + 4); 00249 00250 if ((ret = xan_decode_chroma(avctx, avpkt)) != 0) 00251 return ret; 00252 00253 size = avpkt->size - 4; 00254 if (corr_off >= avpkt->size) { 00255 av_log(avctx, AV_LOG_WARNING, "Ignoring invalid correction block position\n"); 00256 corr_off = 0; 00257 } 00258 if (corr_off) 00259 size = corr_off; 00260 if (chroma_off) 00261 size = FFMIN(size, chroma_off); 00262 ret = xan_unpack_luma(buf + 12, size, src, s->buffer_size >> 1); 00263 if (ret) { 00264 av_log(avctx, AV_LOG_ERROR, "Luma decoding failed\n"); 00265 return ret; 00266 } 00267 00268 ybuf = s->y_buffer; 00269 last = *src++; 00270 ybuf[0] = last << 1; 00271 for (j = 1; j < avctx->width - 1; j += 2) { 00272 cur = (last + *src++) & 0x1F; 00273 ybuf[j] = last + cur; 00274 ybuf[j+1] = cur << 1; 00275 last = cur; 00276 } 00277 ybuf[j] = last << 1; 00278 prev_buf = ybuf; 00279 ybuf += avctx->width; 00280 00281 for (i = 1; i < avctx->height; i++) { 00282 last = ((prev_buf[0] >> 1) + *src++) & 0x1F; 00283 ybuf[0] = last << 1; 00284 for (j = 1; j < avctx->width - 1; j += 2) { 00285 cur = ((prev_buf[j + 1] >> 1) + *src++) & 0x1F; 00286 ybuf[j] = last + cur; 00287 ybuf[j+1] = cur << 1; 00288 last = cur; 00289 } 00290 ybuf[j] = last << 1; 00291 prev_buf = ybuf; 00292 ybuf += avctx->width; 00293 } 00294 00295 if (corr_off) { 00296 int corr_end, dec_size; 00297 00298 corr_end = avpkt->size; 00299 if (chroma_off > corr_off) 00300 corr_end = chroma_off; 00301 dec_size = xan_unpack(s->scratch_buffer, s->buffer_size, 00302 avpkt->data + 8 + corr_off, 00303 corr_end - corr_off); 00304 if (dec_size < 0) 00305 dec_size = 0; 00306 for (i = 0; i < dec_size; i++) 00307 s->y_buffer[i*2+1] = (s->y_buffer[i*2+1] + (s->scratch_buffer[i] << 1)) & 0x3F; 00308 } 00309 00310 src = s->y_buffer; 00311 ybuf = s->pic.data[0]; 00312 for (j = 0; j < avctx->height; j++) { 00313 for (i = 0; i < avctx->width; i++) 00314 ybuf[i] = (src[i] << 2) | (src[i] >> 3); 00315 src += avctx->width; 00316 ybuf += s->pic.linesize[0]; 00317 } 00318 00319 return 0; 00320 } 00321 00322 static int xan_decode_frame_type1(AVCodecContext *avctx, AVPacket *avpkt) 00323 { 00324 const uint8_t *buf = avpkt->data; 00325 XanContext *s = avctx->priv_data; 00326 uint8_t *ybuf, *src = s->scratch_buffer; 00327 int cur, last; 00328 int i, j; 00329 int ret; 00330 00331 if ((ret = xan_decode_chroma(avctx, avpkt)) != 0) 00332 return ret; 00333 00334 ret = xan_unpack_luma(buf + 16, avpkt->size - 16, src, 00335 s->buffer_size >> 1); 00336 if (ret) { 00337 av_log(avctx, AV_LOG_ERROR, "Luma decoding failed\n"); 00338 return ret; 00339 } 00340 00341 ybuf = s->y_buffer; 00342 for (i = 0; i < avctx->height; i++) { 00343 last = (ybuf[0] + (*src++ << 1)) & 0x3F; 00344 ybuf[0] = last; 00345 for (j = 1; j < avctx->width - 1; j += 2) { 00346 cur = (ybuf[j + 1] + (*src++ << 1)) & 0x3F; 00347 ybuf[j] = (last + cur) >> 1; 00348 ybuf[j+1] = cur; 00349 last = cur; 00350 } 00351 ybuf[j] = last; 00352 ybuf += avctx->width; 00353 } 00354 00355 src = s->y_buffer; 00356 ybuf = s->pic.data[0]; 00357 for (j = 0; j < avctx->height; j++) { 00358 for (i = 0; i < avctx->width; i++) 00359 ybuf[i] = (src[i] << 2) | (src[i] >> 3); 00360 src += avctx->width; 00361 ybuf += s->pic.linesize[0]; 00362 } 00363 00364 return 0; 00365 } 00366 00367 static int xan_decode_frame(AVCodecContext *avctx, 00368 void *data, int *data_size, 00369 AVPacket *avpkt) 00370 { 00371 XanContext *s = avctx->priv_data; 00372 int ftype; 00373 int ret; 00374 00375 s->pic.reference = 1; 00376 s->pic.buffer_hints = FF_BUFFER_HINTS_VALID | 00377 FF_BUFFER_HINTS_PRESERVE | 00378 FF_BUFFER_HINTS_REUSABLE; 00379 if ((ret = avctx->reget_buffer(avctx, &s->pic))) { 00380 av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); 00381 return ret; 00382 } 00383 00384 ftype = AV_RL32(avpkt->data); 00385 switch (ftype) { 00386 case 0: 00387 ret = xan_decode_frame_type0(avctx, avpkt); 00388 break; 00389 case 1: 00390 ret = xan_decode_frame_type1(avctx, avpkt); 00391 break; 00392 default: 00393 av_log(avctx, AV_LOG_ERROR, "Unknown frame type %d\n", ftype); 00394 return -1; 00395 } 00396 if (ret) 00397 return ret; 00398 00399 *data_size = sizeof(AVFrame); 00400 *(AVFrame*)data = s->pic; 00401 00402 return avpkt->size; 00403 } 00404 00405 static av_cold int xan_decode_end(AVCodecContext *avctx) 00406 { 00407 XanContext *s = avctx->priv_data; 00408 00409 if (s->pic.data[0]) 00410 avctx->release_buffer(avctx, &s->pic); 00411 00412 av_freep(&s->y_buffer); 00413 av_freep(&s->scratch_buffer); 00414 00415 return 0; 00416 } 00417 00418 AVCodec ff_xan_wc4_decoder = { 00419 "xan_wc4", 00420 AVMEDIA_TYPE_VIDEO, 00421 CODEC_ID_XAN_WC4, 00422 sizeof(XanContext), 00423 xan_decode_init, 00424 NULL, 00425 xan_decode_end, 00426 xan_decode_frame, 00427 CODEC_CAP_DR1, 00428 .long_name = NULL_IF_CONFIG_SMALL("Wing Commander IV / Xxan"), 00429 }; 00430