diff options
Diffstat (limited to 'libavcodec/vqavideo.c')
-rw-r--r-- | libavcodec/vqavideo.c | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/libavcodec/vqavideo.c b/libavcodec/vqavideo.c index 9cca3e743d..dcd81c73c5 100644 --- a/libavcodec/vqavideo.c +++ b/libavcodec/vqavideo.c @@ -2,20 +2,20 @@ * Westwood Studios VQA Video Decoder * Copyright (C) 2003 the ffmpeg project * - * 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 */ @@ -128,12 +128,16 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx) /* make sure the extradata made it */ if (s->avctx->extradata_size != VQA_HEADER_SIZE) { - av_log(s->avctx, AV_LOG_ERROR, " VQA video: expected extradata size of %d\n", VQA_HEADER_SIZE); + av_log(s->avctx, AV_LOG_ERROR, "expected extradata size of %d\n", VQA_HEADER_SIZE); return -1; } /* load up the VQA parameters from the header */ s->vqa_version = s->avctx->extradata[0]; + if (s->vqa_version < 1 || s->vqa_version > 3) { + av_log(s->avctx, AV_LOG_ERROR, "unsupported version %d\n", s->vqa_version); + return -1; + } s->width = AV_RL16(&s->avctx->extradata[6]); s->height = AV_RL16(&s->avctx->extradata[8]); if(av_image_check_size(s->width, s->height, 0, avctx)){ @@ -160,6 +164,11 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx) if (!s->next_codebook_buffer) goto fail; + if (s->width % s->vector_width || s->height % s->vector_height) { + av_log(avctx, AV_LOG_ERROR, "Picture dimensions are not a multiple of the vector size\n"); + goto fail; + } + /* allocate decode buffer */ s->decode_buffer_size = (s->width / s->vector_width) * (s->height / s->vector_height) * 2; @@ -181,6 +190,7 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx) } s->next_codebook_buffer_index = 0; + avcodec_get_frame_defaults(&s->frame); s->frame.data[0] = NULL; return 0; @@ -362,7 +372,7 @@ static int vqa_decode_chunk(VqaContext *s) break; default: - av_log(s->avctx, AV_LOG_ERROR, " VQA video: Found unknown chunk type: %c%c%c%c (%08X)\n", + av_log(s->avctx, AV_LOG_ERROR, "Found unknown chunk type: %c%c%c%c (%08X)\n", (chunk_type >> 24) & 0xFF, (chunk_type >> 16) & 0xFF, (chunk_type >> 8) & 0xFF, @@ -379,7 +389,7 @@ static int vqa_decode_chunk(VqaContext *s) if ((cpl0_chunk != -1) && (cplz_chunk != -1)) { /* a chunk should not have both chunk types */ - av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: found both CPL0 and CPLZ chunks\n"); + av_log(s->avctx, AV_LOG_ERROR, "problem: found both CPL0 and CPLZ chunks\n"); return AVERROR_INVALIDDATA; } @@ -397,7 +407,7 @@ static int vqa_decode_chunk(VqaContext *s) chunk_size = bytestream2_get_be32(&s->gb); /* sanity check the palette size */ if (chunk_size / 3 > 256 || chunk_size > bytestream2_get_bytes_left(&s->gb)) { - av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: found a palette chunk with %d colors\n", + av_log(s->avctx, AV_LOG_ERROR, "problem: found a palette chunk with %d colors\n", chunk_size / 3); return AVERROR_INVALIDDATA; } @@ -406,7 +416,8 @@ static int vqa_decode_chunk(VqaContext *s) r = bytestream2_get_byteu(&s->gb) * 4; g = bytestream2_get_byteu(&s->gb) * 4; b = bytestream2_get_byteu(&s->gb) * 4; - s->palette[i] = (r << 16) | (g << 8) | (b); + s->palette[i] = 0xFF << 24 | r << 16 | g << 8 | b; + s->palette[i] |= s->palette[i] >> 6 & 0x30303; } } @@ -414,7 +425,7 @@ static int vqa_decode_chunk(VqaContext *s) if ((cbf0_chunk != -1) && (cbfz_chunk != -1)) { /* a chunk should not have both chunk types */ - av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: found both CBF0 and CBFZ chunks\n"); + av_log(s->avctx, AV_LOG_ERROR, "problem: found both CBF0 and CBFZ chunks\n"); return AVERROR_INVALIDDATA; } @@ -435,7 +446,7 @@ static int vqa_decode_chunk(VqaContext *s) chunk_size = bytestream2_get_be32(&s->gb); /* sanity check the full codebook size */ if (chunk_size > MAX_CODEBOOK_SIZE) { - av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: CBF0 chunk too large (0x%X bytes)\n", + av_log(s->avctx, AV_LOG_ERROR, "problem: CBF0 chunk too large (0x%X bytes)\n", chunk_size); return AVERROR_INVALIDDATA; } @@ -447,7 +458,7 @@ static int vqa_decode_chunk(VqaContext *s) if (vptz_chunk == -1) { /* something is wrong if there is no VPTZ chunk */ - av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: no VPTZ chunk found\n"); + av_log(s->avctx, AV_LOG_ERROR, "problem: no VPTZ chunk found\n"); return AVERROR_INVALIDDATA; } @@ -518,7 +529,7 @@ static int vqa_decode_chunk(VqaContext *s) /* handle partial codebook */ if ((cbp0_chunk != -1) && (cbpz_chunk != -1)) { /* a chunk should not have both chunk types */ - av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: found both CBP0 and CBPZ chunks\n"); + av_log(s->avctx, AV_LOG_ERROR, "problem: found both CBP0 and CBPZ chunks\n"); return AVERROR_INVALIDDATA; } @@ -533,7 +544,7 @@ static int vqa_decode_chunk(VqaContext *s) s->next_codebook_buffer_index += chunk_size; s->partial_countdown--; - if (s->partial_countdown == 0) { + if (s->partial_countdown <= 0) { /* time to replace codebook */ memcpy(s->codebook, s->next_codebook_buffer, @@ -556,7 +567,7 @@ static int vqa_decode_chunk(VqaContext *s) s->next_codebook_buffer_index += chunk_size; s->partial_countdown--; - if (s->partial_countdown == 0) { + if (s->partial_countdown <= 0) { GetByteContext gb; bytestream2_init(&gb, s->next_codebook_buffer, s->next_codebook_buffer_index); |