summaryrefslogtreecommitdiff
path: root/libavcodec/indeo4.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/indeo4.c')
-rw-r--r--libavcodec/indeo4.c52
1 files changed, 46 insertions, 6 deletions
diff --git a/libavcodec/indeo4.c b/libavcodec/indeo4.c
index 3e8a3988d6..0fe5f8fb5c 100644
--- a/libavcodec/indeo4.c
+++ b/libavcodec/indeo4.c
@@ -393,6 +393,10 @@ static int decode_band_hdr(IVI4DecContext *ctx, IVIBandDesc *band,
band->is_2d_trans = transforms[transform_id].is_2d_trans;
scan_indx = get_bits(&ctx->gb, 4);
+ if ((scan_indx>4 && scan_indx<10) != (band->blk_size==4)) {
+ av_log(avctx, AV_LOG_ERROR, "mismatching scan table!\n");
+ return AVERROR_INVALIDDATA;
+ }
if (scan_indx == 15) {
av_log(avctx, AV_LOG_ERROR, "Custom scan pattern encountered!\n");
return AVERROR_INVALIDDATA;
@@ -404,6 +408,10 @@ static int decode_band_hdr(IVI4DecContext *ctx, IVIBandDesc *band,
av_log(avctx, AV_LOG_ERROR, "Custom quant matrix encountered!\n");
return AVERROR_INVALIDDATA;
}
+ if (band->quant_mat > 21) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid quant matrix encountered!\n");
+ return AVERROR_INVALIDDATA;
+ }
}
/* decode block huffman codebook */
@@ -444,6 +452,11 @@ static int decode_band_hdr(IVI4DecContext *ctx, IVIBandDesc *band,
align_get_bits(&ctx->gb);
+ if (!band->scan) {
+ av_log(avctx, AV_LOG_ERROR, "band->scan not set\n");
+ return AVERROR_INVALIDDATA;
+ }
+
return 0;
}
@@ -462,7 +475,7 @@ static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band,
IVITile *tile, AVCodecContext *avctx)
{
int x, y, mv_x, mv_y, mv_delta, offs, mb_offset, blks_per_mb,
- mv_scale, mb_type_bits;
+ mv_scale, mb_type_bits, s;
IVIMbInfo *mb, *ref_mb;
int row_offset = band->mb_size * band->pitch;
@@ -477,6 +490,11 @@ static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band,
mv_scale = (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3);
mv_x = mv_y = 0;
+ if (((tile->width + band->mb_size-1)/band->mb_size) * ((tile->height + band->mb_size-1)/band->mb_size) != tile->num_MBs) {
+ av_log(avctx, AV_LOG_ERROR, "num_MBs mismatch %d %d %d %d\n", tile->width, tile->height, band->mb_size, tile->num_MBs);
+ return -1;
+ }
+
for (y = tile->ypos; y < tile->ypos + tile->height; y += band->mb_size) {
mb_offset = offs;
@@ -501,7 +519,7 @@ static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band,
}
mb->mv_x = mb->mv_y = 0; /* no motion vector coded */
- if (band->inherit_mv) {
+ if (band->inherit_mv && ref_mb) {
/* motion vector inheritance */
if (mv_scale) {
mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);
@@ -512,7 +530,7 @@ static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band,
}
}
} else {
- if (band->inherit_mv) {
+ if (band->inherit_mv && ref_mb) {
mb->type = ref_mb->type; /* copy mb_type from corresponding reference mb */
} else if (ctx->frame_type == FRAMETYPE_INTRA) {
mb->type = 0; /* mb_type is always INTRA for intra-frames */
@@ -535,7 +553,7 @@ static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band,
if (!mb->type) {
mb->mv_x = mb->mv_y = 0; /* there is no motion vector in intra-macroblocks */
} else {
- if (band->inherit_mv) {
+ if (band->inherit_mv && ref_mb) {
/* motion vector inheritance */
if (mv_scale) {
mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);
@@ -558,6 +576,15 @@ static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band,
}
}
+ s= band->is_halfpel;
+ if (mb->type)
+ if ( x + (mb->mv_x >>s) + (y+ (mb->mv_y >>s))*band->pitch < 0 ||
+ x + ((mb->mv_x+s)>>s) + band->mb_size - 1
+ + (y+band->mb_size - 1 +((mb->mv_y+s)>>s))*band->pitch > band->bufsize -1) {
+ av_log(avctx, AV_LOG_ERROR, "motion vector %d %d outside reference\n", x*s + mb->mv_x, y*s + mb->mv_y);
+ return AVERROR_INVALIDDATA;
+ }
+
mb++;
if (ref_mb)
ref_mb++;
@@ -586,6 +613,7 @@ static int decode_band(IVI4DecContext *ctx, int plane_num,
{
int result, i, t, pos, idx1, idx2;
IVITile *tile;
+ int ret = 0;
band->buf = band->bufs[ctx->dst_buf];
band->ref_buf = band->bufs[ctx->ref_buf];
@@ -609,6 +637,10 @@ static int decode_band(IVI4DecContext *ctx, int plane_num,
idx2 = band->corr[i * 2 + 1];
FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);
FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
+ if (idx1 == band->rv_map->eob_sym || idx2 == band->rv_map->eob_sym)
+ band->rv_map->eob_sym ^= idx1 ^ idx2;
+ if (idx1 == band->rv_map->esc_sym || idx2 == band->rv_map->esc_sym)
+ band->rv_map->esc_sym ^= idx1 ^ idx2;
}
pos = get_bits_count(&ctx->gb);
@@ -625,7 +657,8 @@ static int decode_band(IVI4DecContext *ctx, int plane_num,
tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb);
if (!tile->data_size) {
av_log(avctx, AV_LOG_ERROR, "Tile data size is zero!\n");
- return AVERROR_INVALIDDATA;
+ ret = AVERROR_INVALIDDATA;
+ break;
}
result = decode_mb_info(ctx, band, tile, avctx);
@@ -648,6 +681,10 @@ static int decode_band(IVI4DecContext *ctx, int plane_num,
idx2 = band->corr[i * 2 + 1];
FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);
FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
+ if (idx1 == band->rv_map->eob_sym || idx2 == band->rv_map->eob_sym)
+ band->rv_map->eob_sym ^= idx1 ^ idx2;
+ if (idx1 == band->rv_map->esc_sym || idx2 == band->rv_map->esc_sym)
+ band->rv_map->esc_sym ^= idx1 ^ idx2;
}
#if defined(DEBUG) && IVI4_DEBUG_CHECKSUM
@@ -663,7 +700,7 @@ static int decode_band(IVI4DecContext *ctx, int plane_num,
align_get_bits(&ctx->gb);
- return 0;
+ return ret;
}
@@ -762,6 +799,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
av_log(avctx, AV_LOG_ERROR, "Buffer contains IP frames!\n");
}
+ if (ctx->frame_type >= FRAMETYPE_NULL_FIRST)
+ return buf_size;
+
if (ctx->frame.data[0])
avctx->release_buffer(avctx, &ctx->frame);