aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2019-03-07 01:38:26 +0100
committerPaul B Mahol <onemda@gmail.com>2019-03-07 01:41:36 +0100
commit7b966af930d46494426cd33d7bd8b767e8bfff9e (patch)
tree9115248d942c4e235e95e5fdafe3a95dd780b31e
parent53248acfb3b23007c89ae822d7bcae451272d5a7 (diff)
downloadffmpeg-7b966af930d46494426cd33d7bd8b767e8bfff9e.tar.gz
avcodec/imm4: fix artifacts on some files with special coding mode
-rw-r--r--libavcodec/imm4.c43
1 files changed, 22 insertions, 21 deletions
diff --git a/libavcodec/imm4.c b/libavcodec/imm4.c
index aeb29f5d44..b66689acab 100644
--- a/libavcodec/imm4.c
+++ b/libavcodec/imm4.c
@@ -138,7 +138,7 @@ static int get_cbphi(GetBitContext *gb, int x)
}
static int decode_block(AVCodecContext *avctx, GetBitContext *gb,
- int block, int factor, int flag, int offset)
+ int block, int factor, int flag, int offset, int flag2)
{
IMM4Context *s = avctx->priv_data;
const uint8_t *scantable = s->intra_scantable.permutated;
@@ -169,11 +169,19 @@ static int decode_block(AVCodecContext *avctx, GetBitContext *gb,
break;
}
+ if (s->hi == 2 && flag2 && block < 4) {
+ if (flag)
+ s->block[block][scantable[0]] *= 2;
+ s->block[block][scantable[1]] *= 2;
+ s->block[block][scantable[8]] *= 2;
+ s->block[block][scantable[16]] *= 2;
+ }
+
return 0;
}
static int decode_blocks(AVCodecContext *avctx, GetBitContext *gb,
- unsigned cbp, int flag, int offset)
+ unsigned cbp, int flag, int offset, unsigned flag2)
{
IMM4Context *s = avctx->priv_data;
const uint8_t *scantable = s->intra_scantable.permutated;
@@ -193,7 +201,7 @@ static int decode_blocks(AVCodecContext *avctx, GetBitContext *gb,
}
if (cbp & (1 << (5 - i))) {
- ret = decode_block(avctx, gb, i, s->factor, flag, offset);
+ ret = decode_block(avctx, gb, i, s->factor, flag, offset, flag2);
if (ret < 0)
return ret;
}
@@ -212,11 +220,7 @@ static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame
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;
- }
+ s->factor = s->lo * 2;
}
if (s->hi) {
@@ -228,14 +232,14 @@ static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame
for (y = 0; y < avctx->height; y += 16) {
for (x = 0; x < avctx->width; x += 16) {
- unsigned cbphi, cbplo;
+ unsigned flag, cbphi, cbplo;
cbplo = get_vlc2(gb, cbplo_tab.table, cbplo_tab.bits, 1) >> 4;
- skip_bits1(gb);
+ flag = get_bits1(gb);
cbphi = get_cbphi(gb, 1);
- ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset);
+ ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset, flag);
if (ret < 0)
return ret;
@@ -268,11 +272,7 @@ static int decode_inter(AVCodecContext *avctx, GetBitContext *gb,
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;
- }
+ s->factor = s->lo * 2;
}
if (s->hi) {
@@ -285,7 +285,7 @@ static int decode_inter(AVCodecContext *avctx, GetBitContext *gb,
for (y = 0; y < avctx->height; y += 16) {
for (x = 0; x < avctx->width; x += 16) {
int reverse, intra_block, value;
- unsigned cbphi, cbplo;
+ unsigned cbphi, cbplo, flag2 = 0;
if (get_bits1(gb)) {
copy_block16(frame->data[0] + y * frame->linesize[0] + x,
@@ -307,12 +307,12 @@ static int decode_inter(AVCodecContext *avctx, GetBitContext *gb,
intra_block = value & 0x07;
reverse = intra_block == 3;
if (reverse)
- skip_bits1(gb);
+ flag2 = get_bits1(gb);
cbplo = value >> 4;
cbphi = get_cbphi(gb, reverse);
if (intra_block) {
- ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset);
+ ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset, flag2);
if (ret < 0)
return ret;
@@ -329,8 +329,9 @@ static int decode_inter(AVCodecContext *avctx, GetBitContext *gb,
s->idsp.idct_put(frame->data[2] + (y >> 1) * frame->linesize[2] + (x >> 1),
frame->linesize[2], s->block[5]);
} else {
- skip_bits(gb, 2);
- ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 1, offset);
+ flag2 = get_bits1(gb);
+ skip_bits1(gb);
+ ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 1, offset, flag2);
if (ret < 0)
return ret;