summaryrefslogtreecommitdiffstats
path: root/libavcodec/vqavideo.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/vqavideo.c')
-rw-r--r--libavcodec/vqavideo.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/libavcodec/vqavideo.c b/libavcodec/vqavideo.c
index 7a6308a..ae99c6d 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
*/
@@ -138,6 +138,10 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx)
/* load up the VQA parameters from the header */
vqa_header = (unsigned char *)s->avctx->extradata;
s->vqa_version = vqa_header[0];
+ if (s->vqa_version < 1 || s->vqa_version > 3) {
+ av_log(s->avctx, AV_LOG_ERROR, " VQA video: unsupported version %d\n", s->vqa_version);
+ return -1;
+ }
s->width = AV_RL16(&vqa_header[6]);
s->height = AV_RL16(&vqa_header[8]);
if(av_image_check_size(s->width, s->height, 0, avctx)){
@@ -179,6 +183,7 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx)
(s->height / s->vector_height) * 2;
s->decode_buffer = av_malloc(s->decode_buffer_size);
+ avcodec_get_frame_defaults(&s->frame);
s->frame.data[0] = NULL;
return 0;
@@ -225,6 +230,8 @@ static void decode_format80(const unsigned char *src, int src_size,
src_index += 2;
av_dlog(NULL, "(1) copy %X bytes from absolute pos %X\n", count, src_pos);
CHECK_COUNT();
+ if (src_pos + count > dest_size)
+ return;
for (i = 0; i < count; i++)
dest[dest_index + i] = dest[src_pos + i];
dest_index += count;
@@ -247,6 +254,8 @@ static void decode_format80(const unsigned char *src, int src_size,
src_index += 2;
av_dlog(NULL, "(3) copy %X bytes from absolute pos %X\n", count, src_pos);
CHECK_COUNT();
+ if (src_pos + count > dest_size)
+ return;
for (i = 0; i < count; i++)
dest[dest_index + i] = dest[src_pos + i];
dest_index += count;
@@ -267,6 +276,8 @@ static void decode_format80(const unsigned char *src, int src_size,
src_index += 2;
av_dlog(NULL, "(5) copy %X bytes from relpos %X\n", count, src_pos);
CHECK_COUNT();
+ if (dest_index < src_pos)
+ return;
for (i = 0; i < count; i++)
dest[dest_index + i] = dest[dest_index - src_pos + i];
dest_index += count;
@@ -311,10 +322,17 @@ static void vqa_decode_chunk(VqaContext *s)
int hibytes = s->decode_buffer_size / 2;
/* first, traverse through the frame and find the subchunks */
- while (index < s->size) {
+ while (index + CHUNK_PREAMBLE_SIZE <= s->size) {
+ unsigned next_index;
chunk_type = AV_RB32(&s->buf[index]);
chunk_size = AV_RB32(&s->buf[index + 4]);
+ byte_skip = chunk_size & 0x01;
+ next_index = index + CHUNK_PREAMBLE_SIZE + chunk_size + byte_skip;
+ if (next_index > s->size) {
+ av_log(s->avctx, AV_LOG_ERROR, "Dropping incomplete chunk\n");
+ break;
+ }
switch (chunk_type) {
@@ -355,9 +373,7 @@ static void vqa_decode_chunk(VqaContext *s)
chunk_type);
break;
}
-
- byte_skip = chunk_size & 0x01;
- index += (CHUNK_PREAMBLE_SIZE + chunk_size + byte_skip);
+ index = next_index;
}
/* next, deal with the palette */
@@ -391,7 +407,8 @@ static void vqa_decode_chunk(VqaContext *s)
r = s->buf[cpl0_chunk++] * 4;
g = s->buf[cpl0_chunk++] * 4;
b = s->buf[cpl0_chunk++] * 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;
}
}
OpenPOWER on IntegriCloud