]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blobdiff - libavcodec/bmp.c
frsh: Export information about the last RTP contract and VRES
[frescor/ffmpeg.git] / libavcodec / bmp.c
index ca2e201b549a38da10c12deffe415171a120a974..735c085273fb3d840ca335c8530618e30039705e 100644 (file)
@@ -35,8 +35,10 @@ static av_cold int bmp_decode_init(AVCodecContext *avctx){
 
 static int bmp_decode_frame(AVCodecContext *avctx,
                             void *data, int *data_size,
-                            const uint8_t *buf, int buf_size)
+                            AVPacket *avpkt)
 {
+    const uint8_t *buf = avpkt->data;
+    int buf_size = avpkt->size;
     BMPContext *s = avctx->priv_data;
     AVFrame *picture = data;
     AVFrame *p = &s->picture;
@@ -64,34 +66,44 @@ static int bmp_decode_frame(AVCodecContext *avctx,
 
     fsize = bytestream_get_le32(&buf);
     if(buf_size < fsize){
-        av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n",
+        av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d), trying to decode anyway\n",
                buf_size, fsize);
-        return -1;
+        fsize = buf_size;
     }
 
     buf += 2; /* reserved1 */
     buf += 2; /* reserved2 */
 
     hsize = bytestream_get_le32(&buf); /* header size */
-    if(fsize <= hsize){
-        av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n",
-               fsize, hsize);
-        return -1;
-    }
-
     ihsize = bytestream_get_le32(&buf);       /* more header size */
     if(ihsize + 14 > hsize){
         av_log(avctx, AV_LOG_ERROR, "invalid header size %d\n", hsize);
         return -1;
     }
 
-    if (ihsize == 40) {
+    /* sometimes file size is set to some headers size, set a real size in that case */
+    if(fsize == 14 || fsize == ihsize + 14)
+        fsize = buf_size - 2;
+
+    if(fsize <= hsize){
+        av_log(avctx, AV_LOG_ERROR, "declared file size is less than header size (%d < %d)\n",
+               fsize, hsize);
+        return -1;
+    }
+
+    switch(ihsize){
+    case  40: // windib v3
+    case  64: // OS/2 v2
+    case 108: // windib v4
+    case 124: // windib v5
         width = bytestream_get_le32(&buf);
         height = bytestream_get_le32(&buf);
-    } else if (ihsize == 12) {
+        break;
+    case  12: // OS/2 v1
         width  = bytestream_get_le16(&buf);
         height = bytestream_get_le16(&buf);
-    } else {
+        break;
+    default:
         av_log(avctx, AV_LOG_ERROR, "unsupported BMP file, patch welcome\n");
         return -1;
     }
@@ -230,10 +242,12 @@ 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);
+        ff_msrle_decode(avctx, (AVPicture*)p, depth, buf, dsize);
     }else{
         switch(depth){
         case 1:
+        case 8:
+        case 24:
             for(i = 0; i < avctx->height; i++){
                 memcpy(ptr, buf, n);
                 buf += n;
@@ -251,20 +265,6 @@ static int bmp_decode_frame(AVCodecContext *avctx,
                 ptr += linesize;
             }
             break;
-        case 8:
-            for(i = 0; i < avctx->height; i++){
-                memcpy(ptr, buf, avctx->width);
-                buf += n;
-                ptr += linesize;
-            }
-            break;
-        case 24:
-            for(i = 0; i < avctx->height; i++){
-                memcpy(ptr, buf, avctx->width*(depth>>3));
-                buf += n;
-                ptr += linesize;
-            }
-            break;
         case 16:
             for(i = 0; i < avctx->height; i++){
                 const uint16_t *src = (const uint16_t *) buf;