avcodec/imm4: improve decoding of some files
This commit is contained in:
@@ -43,7 +43,8 @@ typedef struct IMM4Context {
|
|||||||
|
|
||||||
int changed_size;
|
int changed_size;
|
||||||
int factor;
|
int factor;
|
||||||
unsigned sindex;
|
unsigned lo;
|
||||||
|
unsigned hi;
|
||||||
|
|
||||||
ScanTable intra_scantable;
|
ScanTable intra_scantable;
|
||||||
DECLARE_ALIGNED(32, int16_t, block)[6][64];
|
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,
|
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;
|
IMM4Context *s = avctx->priv_data;
|
||||||
const uint8_t *scantable = s->intra_scantable.permutated;
|
const uint8_t *scantable = s->intra_scantable.permutated;
|
||||||
@@ -164,7 +165,7 @@ static int decode_block(AVCodecContext *avctx, GetBitContext *gb,
|
|||||||
i += len;
|
i += len;
|
||||||
if (i >= 64)
|
if (i >= 64)
|
||||||
break;
|
break;
|
||||||
s->block[block][scantable[i]] = factor * factor2;
|
s->block[block][scantable[i]] = offset * (factor2 < 0 ? -1 : 1) + factor * factor2;
|
||||||
if (last)
|
if (last)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -173,7 +174,7 @@ static int decode_block(AVCodecContext *avctx, GetBitContext *gb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int decode_blocks(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;
|
IMM4Context *s = avctx->priv_data;
|
||||||
const uint8_t *scantable = s->intra_scantable.permutated;
|
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))) {
|
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)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -205,9 +206,26 @@ static int decode_blocks(AVCodecContext *avctx, GetBitContext *gb,
|
|||||||
static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame)
|
static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame)
|
||||||
{
|
{
|
||||||
IMM4Context *s = avctx->priv_data;
|
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 (y = 0; y < avctx->height; y += 16) {
|
||||||
for (x = 0; x < avctx->width; x += 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);
|
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)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@@ -244,9 +262,26 @@ static int decode_inter(AVCodecContext *avctx, GetBitContext *gb,
|
|||||||
AVFrame *frame, AVFrame *prev)
|
AVFrame *frame, AVFrame *prev)
|
||||||
{
|
{
|
||||||
IMM4Context *s = avctx->priv_data;
|
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 (y = 0; y < avctx->height; y += 16) {
|
||||||
for (x = 0; x < avctx->width; x += 16) {
|
for (x = 0; x < avctx->width; x += 16) {
|
||||||
@@ -278,7 +313,7 @@ static int decode_inter(AVCodecContext *avctx, GetBitContext *gb,
|
|||||||
cbplo = value >> 4;
|
cbplo = value >> 4;
|
||||||
cbphi = get_cbphi(gb, reverse);
|
cbphi = get_cbphi(gb, reverse);
|
||||||
if (intra_block) {
|
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)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@@ -296,7 +331,7 @@ static int decode_inter(AVCodecContext *avctx, GetBitContext *gb,
|
|||||||
frame->linesize[2], s->block[5]);
|
frame->linesize[2], s->block[5]);
|
||||||
} else {
|
} else {
|
||||||
skip_bits(gb, 2);
|
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)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@@ -400,9 +435,8 @@ static int decode_frame(AVCodecContext *avctx, void *data,
|
|||||||
s->changed_size = 1;
|
s->changed_size = 1;
|
||||||
skip_bits_long(gb, 24 * 8);
|
skip_bits_long(gb, 24 * 8);
|
||||||
type = get_bits_long(gb, 32);
|
type = get_bits_long(gb, 32);
|
||||||
skip_bits(gb, 16);
|
s->hi = get_bits(gb, 16);
|
||||||
s->sindex = get_bits(gb, 16);
|
s->lo = get_bits(gb, 16);
|
||||||
s->sindex = FFMIN(s->sindex, 2);
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 0x19781977:
|
case 0x19781977:
|
||||||
|
Reference in New Issue
Block a user