#include "avcodec.h"
#include "libavutil/intreadwrite.h"
+#include "libavutil/mem.h"
#include "bytestream.h"
#define BITSTREAM_READER_LE
#include "get_bits.h"
-// for av_memcpy_backptr
-#include "libavutil/lzo.h"
typedef struct XanContext {
AVCodecContext *avctx;
s->avctx = avctx;
- avctx->pix_fmt = PIX_FMT_YUV420P;
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P;
s->buffer_size = avctx->width * avctx->height;
s->y_buffer = av_malloc(s->buffer_size);
static int xan_unpack_luma(XanContext *s,
uint8_t *dst, const int dst_size)
{
- int tree_size, eof;
- int bits, mask;
- int tree_root, node;
- const uint8_t *dst_end = dst + dst_size;
- GetByteContext tree = s->gb;
- int start_off = bytestream2_tell(&tree);
-
- tree_size = bytestream2_get_byte(&s->gb);
- eof = bytestream2_get_byte(&s->gb);
- tree_root = eof + tree_size;
- bytestream2_skip(&s->gb, tree_size * 2);
-
- node = tree_root;
- bits = bytestream2_get_byte(&s->gb);
- mask = 0x80;
- for (;;) {
- int bit = !!(bits & mask);
- mask >>= 1;
- bytestream2_seek(&tree, start_off + node*2 + bit - eof * 2, SEEK_SET);
- node = bytestream2_get_byte(&tree);
- if (node == eof)
- break;
- if (node < eof) {
- *dst++ = node;
- if (dst > dst_end)
- break;
- node = tree_root;
- }
- if (!mask) {
- if (bytestream2_get_bytes_left(&s->gb) <= 0)
- break;
- bits = bytestream2_get_byteu(&s->gb);
- mask = 0x80;
- }
- }
- return dst != dst_end ? AVERROR_INVALIDDATA : 0;
+ int tree_size, eof;
+ int bits, mask;
+ int tree_root, node;
+ const uint8_t *dst_end = dst + dst_size;
+ GetByteContext tree = s->gb;
+ int start_off = bytestream2_tell(&tree);
+
+ tree_size = bytestream2_get_byte(&s->gb);
+ eof = bytestream2_get_byte(&s->gb);
+ tree_root = eof + tree_size;
+ bytestream2_skip(&s->gb, tree_size * 2);
+
+ node = tree_root;
+ bits = bytestream2_get_byte(&s->gb);
+ mask = 0x80;
+ for (;;) {
+ int bit = !!(bits & mask);
+ mask >>= 1;
+ bytestream2_seek(&tree, start_off + node*2 + bit - eof * 2, SEEK_SET);
+ node = bytestream2_get_byte(&tree);
+ if (node == eof)
+ break;
+ if (node < eof) {
+ *dst++ = node;
+ if (dst > dst_end)
+ break;
+ node = tree_root;
+ }
+ if (!mask) {
+ if (bytestream2_get_bytes_left(&s->gb) <= 0)
+ break;
+ bits = bytestream2_get_byteu(&s->gb);
+ mask = 0x80;
+ }
+ }
+ return dst != dst_end ? AVERROR_INVALIDDATA : 0;
}
/* almost the same as in xan_wc3 decoder */
int i, j;
const uint8_t *src, *src_end;
const uint8_t *table;
- int mode, offset, dec_size;
+ int mode, offset, dec_size, table_size;
if (!chroma_off)
return 0;
return -1;
}
bytestream2_seek(&s->gb, chroma_off + 4, SEEK_SET);
- mode = bytestream2_get_le16(&s->gb);
- table = s->gb.buffer;
- offset = bytestream2_get_le16(&s->gb) * 2;
+ mode = bytestream2_get_le16(&s->gb);
+ table = s->gb.buffer;
+ table_size = bytestream2_get_le16(&s->gb);
+ offset = table_size * 2;
+ table_size += 1;
if (offset >= bytestream2_get_bytes_left(&s->gb)) {
av_log(avctx, AV_LOG_ERROR, "Invalid chroma block offset\n");
for (j = 0; j < avctx->height >> 1; j++) {
for (i = 0; i < avctx->width >> 1; i++) {
val = *src++;
- if (val) {
+ if (val && val < table_size) {
val = AV_RL16(table + (val << 1));
uval = (val >> 3) & 0xF8;
vval = (val >> 8) & 0xF8;
for (j = 0; j < avctx->height >> 2; j++) {
for (i = 0; i < avctx->width >> 1; i += 2) {
val = *src++;
- if (val) {
+ if (val && val < table_size) {
val = AV_RL16(table + (val << 1));
uval = (val >> 3) & 0xF8;
vval = (val >> 8) & 0xF8;
}
if (corr_off) {
- int corr_end, dec_size;
+ int dec_size;
- corr_end = (s->gb.buffer_end - s->gb.buffer_start);
- if (chroma_off > corr_off)
- corr_end = chroma_off;
bytestream2_seek(&s->gb, 8 + corr_off, SEEK_SET);
dec_size = xan_unpack(s, s->scratch_buffer, s->buffer_size);
if (dec_size < 0)
AVCodec ff_xan_wc4_decoder = {
.name = "xan_wc4",
.type = AVMEDIA_TYPE_VIDEO,
- .id = CODEC_ID_XAN_WC4,
+ .id = AV_CODEC_ID_XAN_WC4,
.priv_data_size = sizeof(XanContext),
.init = xan_decode_init,
.close = xan_decode_end,
.decode = xan_decode_frame,
.capabilities = CODEC_CAP_DR1,
- .long_name = NULL_IF_CONFIG_SMALL("Wing Commander IV / Xxan"),
+ .long_name = NULL_IF_CONFIG_SMALL("Wing Commander IV / Xxan"),
};