diff options
Diffstat (limited to 'libavcodec/hapdec.c')
-rw-r--r-- | libavcodec/hapdec.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/libavcodec/hapdec.c b/libavcodec/hapdec.c index 8f5365b269..5a399dcb25 100644 --- a/libavcodec/hapdec.c +++ b/libavcodec/hapdec.c @@ -3,20 +3,20 @@ * Copyright (C) 2015 Vittorio Giovara <vittorio.giovara@gmail.com> * Copyright (C) 2015 Tom Butterworth <bangnoise@gmail.com> * - * 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 */ @@ -61,7 +61,7 @@ static int parse_section_header(GetByteContext *gbc, int *section_size, *section_size = bytestream2_get_le32(gbc); } - if (*section_size > bytestream2_get_bytes_left(gbc)) + if (*section_size > bytestream2_get_bytes_left(gbc) || *section_size < 0) return AVERROR_INVALIDDATA; else return 0; @@ -309,6 +309,7 @@ static int hap_decode(AVCodecContext *avctx, void *data, HapContext *ctx = avctx->priv_data; ThreadFrame tframe; int ret, i; + int tex_size; bytestream2_init(&ctx->gbc, avpkt->data, avpkt->size); @@ -322,12 +323,14 @@ static int hap_decode(AVCodecContext *avctx, void *data, ret = ff_thread_get_buffer(avctx, &tframe, 0); if (ret < 0) return ret; - ff_thread_finish_setup(avctx); + if (avctx->codec->update_thread_context) + ff_thread_finish_setup(avctx); /* Unpack the DXT texture */ if (hap_can_use_tex_in_place(ctx)) { /* Only DXTC texture compression in a contiguous block */ ctx->tex_data = ctx->gbc.buffer; + tex_size = bytestream2_get_bytes_left(&ctx->gbc); } else { /* Perform the second-stage decompression */ ret = av_reallocp(&ctx->tex_buf, ctx->tex_size); @@ -343,6 +346,14 @@ static int hap_decode(AVCodecContext *avctx, void *data, } ctx->tex_data = ctx->tex_buf; + tex_size = ctx->tex_size; + } + + if (tex_size < (avctx->coded_width / TEXTURE_BLOCK_W) + *(avctx->coded_height / TEXTURE_BLOCK_H) + *ctx->tex_rat) { + av_log(avctx, AV_LOG_ERROR, "Insufficient data\n"); + return AVERROR_INVALIDDATA; } /* Use the decompress function on the texture, one block per thread */ @@ -372,9 +383,6 @@ static av_cold int hap_init(AVCodecContext *avctx) avctx->coded_width = FFALIGN(avctx->width, TEXTURE_BLOCK_W); avctx->coded_height = FFALIGN(avctx->height, TEXTURE_BLOCK_H); - /* Technically only one mode has alpha, but 32 bits are easier to handle */ - avctx->pix_fmt = AV_PIX_FMT_RGBA; - ff_texturedsp_init(&ctx->dxtc); switch (avctx->codec_tag) { @@ -382,16 +390,19 @@ static av_cold int hap_init(AVCodecContext *avctx) texture_name = "DXT1"; ctx->tex_rat = 8; ctx->tex_fun = ctx->dxtc.dxt1_block; + avctx->pix_fmt = AV_PIX_FMT_RGB0; break; case MKTAG('H','a','p','5'): texture_name = "DXT5"; ctx->tex_rat = 16; ctx->tex_fun = ctx->dxtc.dxt5_block; + avctx->pix_fmt = AV_PIX_FMT_RGBA; break; case MKTAG('H','a','p','Y'): texture_name = "DXT5-YCoCg-scaled"; ctx->tex_rat = 16; ctx->tex_fun = ctx->dxtc.dxt5ys_block; + avctx->pix_fmt = AV_PIX_FMT_RGB0; break; default: return AVERROR_DECODER_NOT_FOUND; |