|
|
|
@ -43,7 +43,8 @@ typedef struct IMM4Context { |
|
|
|
|
|
|
|
|
|
int changed_size; |
|
|
|
|
int factor; |
|
|
|
|
unsigned sindex; |
|
|
|
|
unsigned lo; |
|
|
|
|
unsigned hi; |
|
|
|
|
|
|
|
|
|
ScanTable intra_scantable; |
|
|
|
|
DECLARE_ALIGNED(32, int16_t, block)[6][64]; |
|
|
|
@ -138,7 +139,7 @@ static int get_cbphi(GetBitContext *gb, int x) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int decode_block(AVCodecContext *avctx, GetBitContext *gb, |
|
|
|
|
int block, int factor, int flag) |
|
|
|
|
int block, int factor, int flag, int offset) |
|
|
|
|
{ |
|
|
|
|
IMM4Context *s = avctx->priv_data; |
|
|
|
|
const uint8_t *scantable = s->intra_scantable.permutated; |
|
|
|
@ -164,7 +165,7 @@ static int decode_block(AVCodecContext *avctx, GetBitContext *gb, |
|
|
|
|
i += len; |
|
|
|
|
if (i >= 64) |
|
|
|
|
break; |
|
|
|
|
s->block[block][scantable[i]] = factor * factor2; |
|
|
|
|
s->block[block][scantable[i]] = offset * (factor2 < 0 ? -1 : 1) + factor * factor2; |
|
|
|
|
if (last) |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
@ -173,7 +174,7 @@ static int decode_block(AVCodecContext *avctx, GetBitContext *gb, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int decode_blocks(AVCodecContext *avctx, GetBitContext *gb, |
|
|
|
|
unsigned cbp, int flag) |
|
|
|
|
unsigned cbp, int flag, int offset) |
|
|
|
|
{ |
|
|
|
|
IMM4Context *s = avctx->priv_data; |
|
|
|
|
const uint8_t *scantable = s->intra_scantable.permutated; |
|
|
|
@ -193,7 +194,7 @@ static int decode_blocks(AVCodecContext *avctx, GetBitContext *gb, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (cbp & (1 << (5 - i))) { |
|
|
|
|
ret = decode_block(avctx, gb, i, s->factor, flag); |
|
|
|
|
ret = decode_block(avctx, gb, i, s->factor, flag, offset); |
|
|
|
|
if (ret < 0) |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
@ -205,9 +206,26 @@ static int decode_blocks(AVCodecContext *avctx, GetBitContext *gb, |
|
|
|
|
static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame) |
|
|
|
|
{ |
|
|
|
|
IMM4Context *s = avctx->priv_data; |
|
|
|
|
int ret, x, y; |
|
|
|
|
int ret, x, y, offset = 0; |
|
|
|
|
|
|
|
|
|
s->factor = intra_cb[s->sindex]; |
|
|
|
|
if (s->hi == 0) { |
|
|
|
|
if (s->lo > 2) |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
s->factor = intra_cb[s->lo]; |
|
|
|
|
} else { |
|
|
|
|
if (s->hi == 1) { |
|
|
|
|
s->factor = s->lo * 2; |
|
|
|
|
} else { |
|
|
|
|
s->factor = s->lo * 2; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (s->hi) { |
|
|
|
|
offset = s->factor; |
|
|
|
|
offset >>= 1; |
|
|
|
|
if (!(offset & 1)) |
|
|
|
|
offset--; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (y = 0; y < avctx->height; y += 16) { |
|
|
|
|
for (x = 0; x < avctx->width; x += 16) { |
|
|
|
@ -218,7 +236,7 @@ static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame |
|
|
|
|
|
|
|
|
|
cbphi = get_cbphi(gb, 1); |
|
|
|
|
|
|
|
|
|
ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0); |
|
|
|
|
ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset); |
|
|
|
|
if (ret < 0) |
|
|
|
|
return ret; |
|
|
|
|
|
|
|
|
@ -244,9 +262,26 @@ static int decode_inter(AVCodecContext *avctx, GetBitContext *gb, |
|
|
|
|
AVFrame *frame, AVFrame *prev) |
|
|
|
|
{ |
|
|
|
|
IMM4Context *s = avctx->priv_data; |
|
|
|
|
int ret, x, y; |
|
|
|
|
int ret, x, y, offset = 0; |
|
|
|
|
|
|
|
|
|
s->factor = inter_cb[s->sindex]; |
|
|
|
|
if (s->hi == 0) { |
|
|
|
|
if (s->lo > 2) |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
s->factor = inter_cb[s->lo]; |
|
|
|
|
} else { |
|
|
|
|
if (s->hi == 1) { |
|
|
|
|
s->factor = s->lo * 2; |
|
|
|
|
} else { |
|
|
|
|
s->factor = s->lo * 2; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (s->hi) { |
|
|
|
|
offset = s->factor; |
|
|
|
|
offset >>= 1; |
|
|
|
|
if (!(offset & 1)) |
|
|
|
|
offset--; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (y = 0; y < avctx->height; y += 16) { |
|
|
|
|
for (x = 0; x < avctx->width; x += 16) { |
|
|
|
@ -278,7 +313,7 @@ static int decode_inter(AVCodecContext *avctx, GetBitContext *gb, |
|
|
|
|
cbplo = value >> 4; |
|
|
|
|
cbphi = get_cbphi(gb, reverse); |
|
|
|
|
if (intra_block) { |
|
|
|
|
ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0); |
|
|
|
|
ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset); |
|
|
|
|
if (ret < 0) |
|
|
|
|
return ret; |
|
|
|
|
|
|
|
|
@ -296,7 +331,7 @@ static int decode_inter(AVCodecContext *avctx, GetBitContext *gb, |
|
|
|
|
frame->linesize[2], s->block[5]); |
|
|
|
|
} else { |
|
|
|
|
skip_bits(gb, 2); |
|
|
|
|
ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 1); |
|
|
|
|
ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 1, offset); |
|
|
|
|
if (ret < 0) |
|
|
|
|
return ret; |
|
|
|
|
|
|
|
|
@ -400,9 +435,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, |
|
|
|
|
s->changed_size = 1; |
|
|
|
|
skip_bits_long(gb, 24 * 8); |
|
|
|
|
type = get_bits_long(gb, 32); |
|
|
|
|
skip_bits(gb, 16); |
|
|
|
|
s->sindex = get_bits(gb, 16); |
|
|
|
|
s->sindex = FFMIN(s->sindex, 2); |
|
|
|
|
s->hi = get_bits(gb, 16); |
|
|
|
|
s->lo = get_bits(gb, 16); |
|
|
|
|
|
|
|
|
|
switch (type) { |
|
|
|
|
case 0x19781977: |
|
|
|
|