diff options
Diffstat (limited to 'libavcodec/ivi_common.c')
-rw-r--r-- | libavcodec/ivi_common.c | 76 |
1 files changed, 55 insertions, 21 deletions
diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c index 7ca53b7..4179852 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 */ @@ -79,12 +79,9 @@ static int ivi_mc(IVIBandDesc *band, ivi_mc_func mc, int min_size = band->pitch * (band->blk_size - 1) + band->blk_size; int ref_size = (mc_type > 1) * band->pitch + (mc_type & 1); - if (offs < 0 || ref_offs < 0 || !band->ref_buf) - return AVERROR_INVALIDDATA; - if (buf_size - min_size < offs) - return AVERROR_INVALIDDATA; - if (buf_size - min_size - ref_size < ref_offs) - return AVERROR_INVALIDDATA; + av_assert0(offs >= 0 && ref_offs >= 0 && band->ref_buf); + av_assert0(buf_size - min_size >= offs); + av_assert0(buf_size - min_size - ref_size >= ref_offs); mc(band->buf + offs, band->ref_buf + ref_offs, band->pitch, mc_type); @@ -110,7 +107,7 @@ static uint16_t inv_bits(uint16_t val, int nbits) /* * Generate a huffman codebook from the given descriptor - * and convert it into the Libav VLC table. + * and convert it into the FFmpeg VLC table. * * @param[in] cb pointer to codebook descriptor * @param[out] vlc where to place the generated VLC table @@ -224,7 +221,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 (ivi_huff_desc_cmp(&new_huff, &huff_tab->cust_desc)) { + if (ivi_huff_desc_cmp(&new_huff, &huff_tab->cust_desc) || !huff_tab->cust_tab.table) { ivi_huff_desc_copy(&huff_tab->cust_desc, &new_huff); if (huff_tab->cust_tab.table) @@ -259,6 +256,7 @@ static av_cold void ivi_free_buffers(IVIPlaneDesc *planes) int p, b, t; for (p = 0; p < 3; p++) { + if (planes[p].bands) for (b = 0; b < planes[p].num_bands; b++) { av_freep(&planes[p].bands[b].bufs[0]); av_freep(&planes[p].bands[b].bufs[1]); @@ -328,6 +326,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); @@ -370,8 +369,10 @@ static int ivi_init_tiles(IVIBandDesc *band, IVITile *ref_tile, tile->ref_mbs = 0; if (p || b) { - if (tile->num_MBs != ref_tile->num_MBs) + if (tile->num_MBs != ref_tile->num_MBs) { + av_log(NULL, AV_LOG_DEBUG, "ref_tile mismatch\n"); return AVERROR_INVALIDDATA; + } tile->ref_mbs = ref_tile->mbs; ref_tile++; } @@ -396,6 +397,8 @@ av_cold int ff_ivi_init_tiles(IVIPlaneDesc *planes, 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]; @@ -453,10 +456,6 @@ static int ivi_dc_transform(IVIBandDesc *band, int *prev_dc, int buf_offs, int buf_size = band->pitch * band->aheight - buf_offs; int min_size = (blk_size - 1) * band->pitch + blk_size; - if (!band->dc_transform) - return 0; - - if (min_size > buf_size) return AVERROR_INVALIDDATA; @@ -547,6 +546,11 @@ static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band, col_flags[0] |= !!*prev_dc; } + if(band->transform_size > band->blk_size){ + av_log(NULL, AV_LOG_ERROR, "Too large transform\n"); + return AVERROR_INVALIDDATA; + } + /* apply inverse transform */ band->inv_transform(trvec, band->buf + offs, band->pitch, col_flags); @@ -734,6 +738,22 @@ static int ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, mb->mv_y = ref_mb->mv_y; } need_mc |= mb->mv_x || mb->mv_y; /* tracking non-zero motion vectors */ + { + int dmv_x, dmv_y, cx, cy; + + dmv_x = mb->mv_x >> band->is_halfpel; + dmv_y = mb->mv_y >> band->is_halfpel; + cx = mb->mv_x & band->is_halfpel; + cy = mb->mv_y & band->is_halfpel; + + if ( mb->xpos + dmv_x < 0 + || mb->xpos + dmv_x + band->mb_size + cx > band->pitch + || mb->ypos + dmv_y < 0 + || mb->ypos + dmv_y + band->mb_size + cy > band->aheight) { + av_log(avctx, AV_LOG_ERROR, "MV out of bounds\n"); + return AVERROR_INVALIDDATA; + } + } } mb++; @@ -869,6 +889,10 @@ static int decode_band(IVI45DecContext *ctx, 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); @@ -892,7 +916,8 @@ static int decode_band(IVI45DecContext *ctx, tile->data_size = 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); @@ -924,6 +949,10 @@ static int decode_band(IVI45DecContext *ctx, 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 @@ -980,6 +1009,7 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, //{ 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, &ctx->planes[p].bands[b], avctx); @@ -990,6 +1020,7 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } } } + ctx->buf_invalid[ctx->dst_buf] = 0; } else { if (ctx->is_scalable) return AVERROR_INVALIDDATA; @@ -999,6 +1030,8 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return AVERROR_INVALIDDATA; } } + if (ctx->buf_invalid[ctx->dst_buf]) + return -1; //STOP_TIMER("decode_planes"); } @@ -1015,11 +1048,12 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, av_log(avctx, AV_LOG_ERROR, "Buffer contains IP frames!\n"); } + if (!ctx->is_nonnull_frame(ctx)) + return buf_size; + avcodec_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height); - if ((result = ff_get_buffer(avctx, frame, 0)) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + if ((result = ff_get_buffer(avctx, frame, 0)) < 0) return result; - } if (ctx->is_scalable) { if (avctx->codec_id == AV_CODEC_ID_INDEO4) |