]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/msrledec.c
fix linking on systems with a function name prefix (10l in r20287)
[ffmpeg] / libavcodec / msrledec.c
index ce3c56d4718116c3dd7d52896c3f2849466b9d43..b8f5e6246b7d59950dd09f9e4dc97b9d769b090b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Micrsoft RLE Decoder
+ * Microsoft RLE decoder
  * Copyright (C) 2008 Konstantin Shishkov
  *
  * This file is part of FFmpeg.
  */
 
 /**
- * @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;
 }