Add RLE4 and RLE8 decoding support for BMP
authorKostya Shishkov <kostya.shishkov@gmail.com>
Tue, 23 Sep 2008 08:45:12 +0000 (08:45 +0000)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Tue, 23 Sep 2008 08:45:12 +0000 (08:45 +0000)
Originally committed as revision 15390 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/Makefile
libavcodec/bmp.c

index d91185e..c180181 100644 (file)
@@ -41,7 +41,7 @@ OBJS-$(CONFIG_ATRAC3_DECODER)          += atrac3.o mdct.o fft.o
 OBJS-$(CONFIG_AVS_DECODER)             += avs.o
 OBJS-$(CONFIG_BETHSOFTVID_DECODER)     += bethsoftvideo.o
 OBJS-$(CONFIG_BFI_DECODER)             += bfi.o
-OBJS-$(CONFIG_BMP_DECODER)             += bmp.o
+OBJS-$(CONFIG_BMP_DECODER)             += bmp.o msrledec.o
 OBJS-$(CONFIG_BMP_ENCODER)             += bmpenc.o
 OBJS-$(CONFIG_C93_DECODER)             += c93.o
 OBJS-$(CONFIG_CAVS_DECODER)            += cavs.o cavsdec.o cavsdsp.o golomb.o mpeg12data.o mpegvideo.o
index 62beb6d..d88131a 100644 (file)
@@ -22,6 +22,7 @@
 #include "avcodec.h"
 #include "bytestream.h"
 #include "bmp.h"
+#include "msrledec.h"
 
 static av_cold int bmp_decode_init(AVCodecContext *avctx){
     BMPContext *s = avctx->priv_data;
@@ -107,7 +108,7 @@ static int bmp_decode_frame(AVCodecContext *avctx,
     else
         comp = BMP_RGB;
 
-    if(comp != BMP_RGB && comp != BMP_BITFIELDS){
+    if(comp != BMP_RGB && comp != BMP_BITFIELDS && comp != BMP_RLE4 && comp != BMP_RLE8){
         av_log(avctx, AV_LOG_ERROR, "BMP coding %d not supported\n", comp);
         return -1;
     }
@@ -196,12 +197,16 @@ static int bmp_decode_frame(AVCodecContext *avctx,
     /* Line size in file multiple of 4 */
     n = ((avctx->width * depth) / 8 + 3) & ~3;
 
-    if(n * avctx->height > dsize){
+    if(n * avctx->height > dsize && comp != BMP_RLE4 && comp != BMP_RLE8){
         av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n",
                dsize, n * avctx->height);
         return -1;
     }
 
+    // RLE may skip decoding some picture areas, so blank picture before decoding
+    if(comp == BMP_RLE4 || comp == BMP_RLE8)
+        memset(p->data[0], 0, avctx->height * p->linesize[0]);
+
     if(depth == 4 || depth == 8)
         memset(p->data[1], 0, 1024);
 
@@ -224,6 +229,9 @@ static int bmp_decode_frame(AVCodecContext *avctx,
         }
         buf = buf0 + hsize;
     }
+    if(comp == BMP_RLE4 || comp == BMP_RLE8){
+        ff_msrle_decode(avctx, p, depth, buf, dsize);
+    }else{
     switch(depth){
     case 1:
         for(i = 0; i < avctx->height; i++){
@@ -290,6 +298,7 @@ static int bmp_decode_frame(AVCodecContext *avctx,
         av_log(avctx, AV_LOG_ERROR, "BMP decoder is broken\n");
         return -1;
     }
+    }
 
     *picture = s->picture;
     *data_size = sizeof(AVPicture);