bink: Factorize bink put_pixel

And make sure to check INTER_BLOCK as had been fixed by Michael
Niedermayer.

Reported-By: Andreas Cadhalpun
CC: libav-stable@libav.org
This commit is contained in:
Luca Barbato 2015-06-03 02:09:31 +02:00
parent e97446e600
commit 7f596368a4

@ -944,15 +944,32 @@ static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb,
return 0; return 0;
} }
static int bink_put_pixels(BinkContext *c,
uint8_t *dst, uint8_t *prev, int stride,
uint8_t *ref_start,
uint8_t *ref_end)
{
int xoff = get_value(c, BINK_SRC_X_OFF);
int yoff = get_value(c, BINK_SRC_Y_OFF);
uint8_t *ref = prev + xoff + yoff * stride;
if (ref < ref_start || ref > ref_end) {
av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n",
xoff, yoff);
return AVERROR_INVALIDDATA;
}
c->hdsp.put_pixels_tab[1][0](dst, ref, stride, 8);
return 0;
}
static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb,
int plane_idx, int is_chroma) int plane_idx, int is_chroma)
{ {
int blk, ret; int blk, ret;
int i, j, bx, by; int i, j, bx, by;
uint8_t *dst, *prev, *ref, *ref_start, *ref_end; uint8_t *dst, *prev, *ref_start, *ref_end;
int v, col[2]; int v, col[2];
const uint8_t *scan; const uint8_t *scan;
int xoff, yoff;
LOCAL_ALIGNED_16(int16_t, block, [64]); LOCAL_ALIGNED_16(int16_t, block, [64]);
LOCAL_ALIGNED_16(uint8_t, ublock, [64]); LOCAL_ALIGNED_16(uint8_t, ublock, [64]);
LOCAL_ALIGNED_16(int32_t, dctblock, [64]); LOCAL_ALIGNED_16(int32_t, dctblock, [64]);
@ -1074,15 +1091,10 @@ static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb,
prev += 8; prev += 8;
break; break;
case MOTION_BLOCK: case MOTION_BLOCK:
xoff = get_value(c, BINK_SRC_X_OFF); ret = bink_put_pixels(c, dst, prev, stride,
yoff = get_value(c, BINK_SRC_Y_OFF); ref_start, ref_end);
ref = prev + xoff + yoff * stride; if (ret < 0)
if (ref < ref_start || ref > ref_end) { return ret;
av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n",
bx*8 + xoff, by*8 + yoff);
return AVERROR_INVALIDDATA;
}
c->hdsp.put_pixels_tab[1][0](dst, ref, stride, 8);
break; break;
case RUN_BLOCK: case RUN_BLOCK:
scan = bink_patterns[get_bits(gb, 4)]; scan = bink_patterns[get_bits(gb, 4)];
@ -1108,15 +1120,10 @@ static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb,
dst[coordmap[*scan++]] = get_value(c, BINK_SRC_COLORS); dst[coordmap[*scan++]] = get_value(c, BINK_SRC_COLORS);
break; break;
case RESIDUE_BLOCK: case RESIDUE_BLOCK:
xoff = get_value(c, BINK_SRC_X_OFF); ret = bink_put_pixels(c, dst, prev, stride,
yoff = get_value(c, BINK_SRC_Y_OFF); ref_start, ref_end);
ref = prev + xoff + yoff * stride; if (ret < 0)
if (ref < ref_start || ref > ref_end) { return ret;
av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n",
bx*8 + xoff, by*8 + yoff);
return AVERROR_INVALIDDATA;
}
c->hdsp.put_pixels_tab[1][0](dst, ref, stride, 8);
c->bdsp.clear_block(block); c->bdsp.clear_block(block);
v = get_bits(gb, 7); v = get_bits(gb, 7);
read_residue(gb, block, v); read_residue(gb, block, v);
@ -1133,10 +1140,10 @@ static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb,
c->bdsp.fill_block_tab[1](dst, v, stride, 8); c->bdsp.fill_block_tab[1](dst, v, stride, 8);
break; break;
case INTER_BLOCK: case INTER_BLOCK:
xoff = get_value(c, BINK_SRC_X_OFF); ret = bink_put_pixels(c, dst, prev, stride,
yoff = get_value(c, BINK_SRC_Y_OFF); ref_start, ref_end);
ref = prev + xoff + yoff * stride; if (ret < 0)
c->hdsp.put_pixels_tab[1][0](dst, ref, stride, 8); return ret;
memset(dctblock, 0, sizeof(*dctblock) * 64); memset(dctblock, 0, sizeof(*dctblock) * 64);
dctblock[0] = get_value(c, BINK_SRC_INTER_DC); dctblock[0] = get_value(c, BINK_SRC_INTER_DC);
read_dct_coeffs(gb, dctblock, bink_scan, bink_inter_quant, -1); read_dct_coeffs(gb, dctblock, bink_scan, bink_inter_quant, -1);