diff options
Diffstat (limited to 'libavcodec/ivi_common.c')
-rw-r--r-- | libavcodec/ivi_common.c | 49 |
1 files changed, 39 insertions, 10 deletions
diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c index 715a536d38..98e3e25b93 100644 --- a/libavcodec/ivi_common.c +++ b/libavcodec/ivi_common.c @@ -3,20 +3,20 @@ * * Copyright (c) 2009 Maxim Poliakovski * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -132,7 +132,7 @@ int ff_ivi_dec_huff_desc(GetBitContext *gb, int desc_coded, int which_tab, new_huff.xbits[i] = get_bits(gb, 4); /* Have we got the same custom table? Rebuild if not. */ - if (ff_ivi_huff_desc_cmp(&new_huff, &huff_tab->cust_desc)) { + if (ff_ivi_huff_desc_cmp(&new_huff, &huff_tab->cust_desc) || !huff_tab->cust_tab.table) { ff_ivi_huff_desc_copy(&huff_tab->cust_desc, &new_huff); if (huff_tab->cust_tab.table) @@ -215,6 +215,7 @@ av_cold int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg) band->aheight = height_aligned; band->bufs[0] = av_mallocz(buf_size); band->bufs[1] = av_mallocz(buf_size); + band->bufsize = buf_size/2; if (!band->bufs[0] || !band->bufs[1]) return AVERROR(ENOMEM); @@ -266,6 +267,8 @@ av_cold int ff_ivi_init_tiles(IVIPlaneDesc *planes, int tile_width, int tile_hei t_width >>= 1; t_height >>= 1; } + if(t_width<=0 || t_height<=0) + return AVERROR(EINVAL); for (b = 0; b < planes[p].num_bands; b++) { band = &planes[p].bands[b]; @@ -434,7 +437,7 @@ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile) /* de-zigzag and dequantize */ scan_pos += run; - if (scan_pos >= num_coeffs) + if (scan_pos >= (unsigned)num_coeffs) break; pos = band->scan[scan_pos]; @@ -457,7 +460,10 @@ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile) trvec[0] = prev_dc; col_flags[0] |= !!prev_dc; } - + if(band->transform_size > band->blk_size){ + av_log(0, AV_LOG_ERROR, "Too large transform\n"); + return AVERROR_INVALIDDATA; + } /* apply inverse transform */ band->inv_transform(trvec, band->buf + buf_offs, band->pitch, col_flags); @@ -500,6 +506,12 @@ void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, void (*mc_no_delta_func)(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); + if( tile->num_MBs != IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size) ){ + av_log(avctx, AV_LOG_ERROR, "allocated tile size %d mismatches parameters %d in ff_ivi_process_empty_tile()\n", + tile->num_MBs, IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size)); + return; + } + offs = tile->ypos * band->pitch + tile->xpos; mb = tile->mbs; ref_mb = tile->ref_mbs; @@ -526,7 +538,7 @@ void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, if (band->inherit_qdelta && ref_mb) mb->q_delta = ref_mb->q_delta; - 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); @@ -659,6 +671,10 @@ static int decode_band(IVI45DecContext *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); @@ -680,7 +696,8 @@ static int decode_band(IVI45DecContext *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; + result = AVERROR_INVALIDDATA; + break; } result = ctx->decode_mb_info(ctx, band, tile, avctx); @@ -703,6 +720,10 @@ static int decode_band(IVI45DecContext *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; } #ifdef DEBUG @@ -734,7 +755,7 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *data_size, ctx->frame_size = buf_size; result = ctx->decode_pic_hdr(ctx, avctx); - if (result) { + if (result || ctx->gop_invalid) { av_log(avctx, AV_LOG_ERROR, "Error while decoding picture header: %d\n", result); return -1; @@ -750,6 +771,7 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *data_size, //{ START_TIMER; if (ctx->is_nonnull_frame(ctx)) { + ctx->buf_invalid[ctx->dst_buf] = 1; for (p = 0; p < 3; p++) { for (b = 0; b < ctx->planes[p].num_bands; b++) { result = decode_band(ctx, p, &ctx->planes[p].bands[b], avctx); @@ -760,7 +782,10 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *data_size, } } } + ctx->buf_invalid[ctx->dst_buf] = 0; } + if (ctx->buf_invalid[ctx->dst_buf]) + return -1; //STOP_TIMER("decode_planes"); } @@ -774,9 +799,13 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *data_size, av_log(avctx, AV_LOG_ERROR, "Buffer contains IP frames!\n"); } + if (!ctx->is_nonnull_frame(ctx)) + return buf_size; + if (ctx->frame.data[0]) avctx->release_buffer(avctx, &ctx->frame); + avcodec_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height); ctx->frame.reference = 0; if ((result = avctx->get_buffer(avctx, &ctx->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |