X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fmsrledec.c;h=b8f5e6246b7d59950dd09f9e4dc97b9d769b090b;hb=b07781b6e4f6267f20aec4e7f1d390ddb223af46;hp=ce3c56d4718116c3dd7d52896c3f2849466b9d43;hpb=ce60c2d133876b2878b724cb512b81d4a149c72e;p=ffmpeg diff --git a/libavcodec/msrledec.c b/libavcodec/msrledec.c index ce3c56d4718..b8f5e6246b7 100644 --- a/libavcodec/msrledec.c +++ b/libavcodec/msrledec.c @@ -1,5 +1,5 @@ /* - * Micrsoft RLE Decoder + * Microsoft RLE decoder * Copyright (C) 2008 Konstantin Shishkov * * This file is part of FFmpeg. @@ -20,12 +20,13 @@ */ /** - * @file msrledec.c - * MS RLE Decoder based on decoder by Mike Melanson and my own for TSCC + * @file libavcodec/msrledec.c + * MS RLE decoder based on decoder by Mike Melanson and my own for TSCC * For more information about the MS RLE format, visit: * http://www.multimedia.cx/msrle.txt */ +#include "libavutil/intreadwrite.h" #include "avcodec.h" #define FETCH_NEXT_STREAM_BYTE() \ @@ -133,9 +134,9 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, int de { uint8_t *output, *output_end; const uint8_t* src = data; - int p1, p2, line=avctx->height, pos=0, i; - uint16_t pix16; - uint32_t pix32; + int p1, p2, line=avctx->height - 1, pos=0, i; + uint16_t av_uninit(pix16); + uint32_t av_uninit(pix32); output = pic->data[0] + (avctx->height - 1) * pic->linesize[0]; output_end = pic->data[0] + (avctx->height) * pic->linesize[0]; @@ -145,7 +146,7 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, int de p2 = *src++; if(p2 == 0) { //End-of-line output = pic->data[0] + (--line) * pic->linesize[0]; - if (line < 0){ + if (line < 0 && !(src+1 < data + srcsize && AV_RB16(src) == 1)) { av_log(avctx, AV_LOG_ERROR, "Next line is beyond picture bounds\n"); return -1; } @@ -166,7 +167,8 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, int de continue; } // Copy data - if (output + p2 * (depth >> 3) > output_end) { + if ((pic->linesize[0] > 0 && output + p2 * (depth >> 3) > output_end) + ||(pic->linesize[0] < 0 && output + p2 * (depth >> 3) < output_end)) { src += p2 * (depth >> 3); continue; } @@ -194,14 +196,13 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, int de } } pos += p2; - } else { //Run of pixels - int pix[4]; //original pixel + } else { //run of pixels + uint8_t pix[3]; //original pixel switch(depth){ case 8: pix[0] = *src++; break; case 16: pix16 = AV_RL16(src); src += 2; - *(uint16_t*)pix = pix16; break; case 24: pix[0] = *src++; pix[1] = *src++; @@ -209,10 +210,10 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, int de break; case 32: pix32 = AV_RL32(src); src += 4; - *(uint32_t*)pix = pix32; break; } - if (output + p1 * (depth >> 3) > output_end) + if ((pic->linesize[0] > 0 && output + p1 * (depth >> 3) > output_end) + ||(pic->linesize[0] < 0 && output + p1 * (depth >> 3) < output_end)) continue; for(i = 0; i < p1; i++) { switch(depth){ @@ -234,7 +235,7 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, int de } } - av_log(avctx, AV_LOG_WARNING, "MS RLE warning: no End-of-picture code\n"); + av_log(avctx, AV_LOG_WARNING, "MS RLE warning: no end-of-picture code\n"); return 0; }