Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/xxan.c')
-rw-r--r--libavcodec/xxan.c50
1 files changed, 31 insertions, 19 deletions
diff --git a/libavcodec/xxan.c b/libavcodec/xxan.c
index 2a5a8ca631..47b3544b05 100644
--- a/libavcodec/xxan.c
+++ b/libavcodec/xxan.c
@@ -3,20 +3,20 @@
* Copyright (C) 2011 Konstantin Shishkov
* based on work by Mike Melanson
*
- * 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
*/
@@ -133,7 +133,7 @@ static int xan_unpack(XanContext *s,
}
if (dest + size + size2 > dest_end ||
dest - orig_dest + size < back)
- return -1;
+ return AVERROR_INVALIDDATA;
bytestream2_get_buffer(&s->gb, dest, size);
dest += size;
av_memcpy_backptr(dest, back, size2);
@@ -143,7 +143,7 @@ static int xan_unpack(XanContext *s,
size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4;
if (dest_end - dest < size)
- return -1;
+ return AVERROR_INVALIDDATA;
bytestream2_get_buffer(&s->gb, dest, size);
dest += size;
if (finish)
@@ -167,7 +167,7 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off)
return 0;
if (chroma_off + 4 >= bytestream2_get_bytes_left(&s->gb)) {
av_log(avctx, AV_LOG_ERROR, "Invalid chroma block position\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
bytestream2_seek(&s->gb, chroma_off + 4, SEEK_SET);
mode = bytestream2_get_le16(&s->gb);
@@ -178,7 +178,7 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off)
if (offset >= bytestream2_get_bytes_left(&s->gb)) {
av_log(avctx, AV_LOG_ERROR, "Invalid chroma block offset\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
bytestream2_skip(&s->gb, offset);
@@ -186,7 +186,7 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off)
dec_size = xan_unpack(s, s->scratch_buffer, s->buffer_size);
if (dec_size < 0) {
av_log(avctx, AV_LOG_ERROR, "Chroma unpacking failed\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
U = s->pic.data[1];
@@ -196,16 +196,18 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off)
if (mode) {
for (j = 0; j < avctx->height >> 1; j++) {
for (i = 0; i < avctx->width >> 1; i++) {
+ if (src_end - src < 1)
+ return 0;
val = *src++;
- if (val && val < table_size) {
+ if (val) {
+ if (val >= table_size)
+ return AVERROR_INVALIDDATA;
val = AV_RL16(table + (val << 1));
uval = (val >> 3) & 0xF8;
vval = (val >> 8) & 0xF8;
U[i] = uval | (uval >> 5);
V[i] = vval | (vval >> 5);
}
- if (src == src_end)
- return 0;
}
U += s->pic.linesize[1];
V += s->pic.linesize[2];
@@ -216,8 +218,12 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off)
for (j = 0; j < avctx->height >> 2; j++) {
for (i = 0; i < avctx->width >> 1; i += 2) {
+ if (src_end - src < 1)
+ return 0;
val = *src++;
- if (val && val < table_size) {
+ if (val) {
+ if (val >= table_size)
+ return AVERROR_INVALIDDATA;
val = AV_RL16(table + (val << 1));
uval = (val >> 3) & 0xF8;
vval = (val >> 8) & 0xF8;
@@ -250,7 +256,7 @@ static int xan_decode_frame_type0(AVCodecContext *avctx)
if ((ret = xan_decode_chroma(avctx, chroma_off)) != 0)
return ret;
- if (corr_off >= (s->gb.buffer_end - s->gb.buffer_start)) {
+ if (corr_off >= bytestream2_size(&s->gb)) {
av_log(avctx, AV_LOG_WARNING, "Ignoring invalid correction block position\n");
corr_off = 0;
}
@@ -270,7 +276,8 @@ static int xan_decode_frame_type0(AVCodecContext *avctx)
ybuf[j+1] = cur << 1;
last = cur;
}
- ybuf[j] = last << 1;
+ if(j < avctx->width)
+ ybuf[j] = last << 1;
prev_buf = ybuf;
ybuf += avctx->width;
@@ -283,7 +290,8 @@ static int xan_decode_frame_type0(AVCodecContext *avctx)
ybuf[j+1] = cur << 1;
last = cur;
}
- ybuf[j] = last << 1;
+ if(j < avctx->width)
+ ybuf[j] = last << 1;
prev_buf = ybuf;
ybuf += avctx->width;
}
@@ -295,6 +303,9 @@ static int xan_decode_frame_type0(AVCodecContext *avctx)
dec_size = xan_unpack(s, s->scratch_buffer, s->buffer_size);
if (dec_size < 0)
dec_size = 0;
+ else
+ dec_size = FFMIN(dec_size, s->buffer_size/2 - 1);
+
for (i = 0; i < dec_size; i++)
s->y_buffer[i*2+1] = (s->y_buffer[i*2+1] + (s->scratch_buffer[i] << 1)) & 0x3F;
}
@@ -340,7 +351,8 @@ static int xan_decode_frame_type1(AVCodecContext *avctx)
ybuf[j+1] = cur;
last = cur;
}
- ybuf[j] = last;
+ if(j < avctx->width)
+ ybuf[j] = last;
ybuf += avctx->width;
}
@@ -364,7 +376,7 @@ static int xan_decode_frame(AVCodecContext *avctx,
int ftype;
int ret;
- s->pic.reference = 1;
+ s->pic.reference = 3;
s->pic.buffer_hints = FF_BUFFER_HINTS_VALID |
FF_BUFFER_HINTS_PRESERVE |
FF_BUFFER_HINTS_REUSABLE;
@@ -384,7 +396,7 @@ static int xan_decode_frame(AVCodecContext *avctx,
break;
default:
av_log(avctx, AV_LOG_ERROR, "Unknown frame type %d\n", ftype);
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (ret)
return ret;