diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-04-16 19:53:24 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-05-14 01:22:27 +0200 |
commit | ee57bfc47a9867fbd59cea33430caa42006116d8 (patch) | |
tree | 91928c6670d3f323cc658fa2d6b65ec4f181b6df | |
parent | 4a442ac117c47c8d05e5c385ced93d951fa3e9bf (diff) | |
download | ffmpeg-ee57bfc47a9867fbd59cea33430caa42006116d8.tar.gz |
mjpegdec: fix overlapping memcpy with upscale_v
Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit b39fd7d63648442c20671c3e4b357268ec5c49f2)
Conflicts:
libavcodec/mjpegdec.c
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/mjpegdec.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 0fca3721af..814571f3bc 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -1602,6 +1602,7 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size, MJpegDecodeContext *s = avctx->priv_data; const uint8_t *buf_end, *buf_ptr; const uint8_t *unescaped_buf_ptr; + int hshift, vshift; int unescaped_buf_size; int start_code; int i, index; @@ -1779,6 +1780,9 @@ the_end: } if (s->upscale_v) { uint8_t *dst = &((uint8_t *)s->picture_ptr->data[s->upscale_v])[(s->height - 1) * s->linesize[s->upscale_v]]; + int w; + avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &hshift, &vshift); + w = s->width >> hshift; av_assert0(avctx->pix_fmt == PIX_FMT_YUVJ444P || avctx->pix_fmt == PIX_FMT_YUV444P || avctx->pix_fmt == PIX_FMT_YUVJ422P || @@ -1787,16 +1791,16 @@ the_end: uint8_t *src1 = &((uint8_t *)s->picture_ptr->data[s->upscale_v])[i / 2 * s->linesize[s->upscale_v]]; uint8_t *src2 = &((uint8_t *)s->picture_ptr->data[s->upscale_v])[(i + 1) / 2 * s->linesize[s->upscale_v]]; if (src1 == src2) { - memcpy(dst, src1, s->width); + memcpy(dst, src1, w); } else { - for (index = 0; index < s->width; index++) + for (index = 0; index < w; index++) dst[index] = (src1[index] + src2[index]) >> 1; } dst -= s->linesize[s->upscale_v]; } } if (s->flipped && (s->avctx->flags & CODEC_FLAG_EMU_EDGE)) { - int hshift, vshift, j; + int j; avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &hshift, &vshift); for (index=0; index<4; index++) { uint8_t *dst = s->picture_ptr->data[index]; |