---
 libavcodec/bmp.c |  150 ++++++++++++++++++++++++------------------------------
 1 files changed, 66 insertions(+), 84 deletions(-)

diff --git a/libavcodec/bmp.c b/libavcodec/bmp.c
index 4d586dc..60a3308 100644
--- a/libavcodec/bmp.c
+++ b/libavcodec/bmp.c
@@ -37,58 +37,38 @@ static int bmp_decode_frame(AVCodecContext *avctx,
                             void *data, int *data_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;
-    unsigned int fsize, hsize;
+    unsigned int hsize;
     int width, height;
     unsigned int depth;
     BiCompression comp;
     unsigned int ihsize;
-    int i, j, n, linesize;
+    int i, j, n, linesize, ret;
     uint32_t rgb[3];
     uint8_t *ptr;
-    int dsize;
-    const uint8_t *buf0 = buf;
+    GetByteContext gb;
 
-    if(buf_size < 14){
+    if(buf_size < 22){
         av_log(avctx, AV_LOG_ERROR, "buf size too small (%d)\n", buf_size);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    if(bytestream_get_byte(&buf) != 'B' ||
-       bytestream_get_byte(&buf) != 'M') {
+    bytestream2_init(&gb, avpkt->data, buf_size);
+    if(bytestream2_get_byteu(&gb) != 'B' ||
+       bytestream2_get_byteu(&gb) != 'M') {
         av_log(avctx, AV_LOG_ERROR, "bad magic number\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
+    bytestream2_skip(&gb, 8); // file size[4], reserved1[2], reserved2[2]
 
-    fsize = bytestream_get_le32(&buf);
-    if(buf_size < fsize){
-        av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d), trying to 
decode anyway\n",
-               buf_size, fsize);
-        fsize = buf_size;
-    }
-
-    buf += 2; /* reserved1 */
-    buf += 2; /* reserved2 */
-
-    hsize = bytestream_get_le32(&buf); /* header size */
-    ihsize = bytestream_get_le32(&buf);       /* more header size */
+    hsize = bytestream2_get_le32u(&gb); /* header size */
+    ihsize = bytestream2_get_le32u(&gb); /* more header size */
     if(ihsize + 14 > hsize){
         av_log(avctx, AV_LOG_ERROR, "invalid header size %d\n", hsize);
-        return -1;
-    }
-
-    /* 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;
+        return AVERROR_INVALIDDATA;
     }
 
     switch(ihsize){
@@ -96,27 +76,27 @@ static int bmp_decode_frame(AVCodecContext *avctx,
     case  64: // OS/2 v2
     case 108: // windib v4
     case 124: // windib v5
-        width = bytestream_get_le32(&buf);
-        height = bytestream_get_le32(&buf);
+        width  = bytestream2_get_le32u(&gb);
+        height = bytestream2_get_le32(&gb);
         break;
     case  12: // OS/2 v1
-        width  = bytestream_get_le16(&buf);
-        height = bytestream_get_le16(&buf);
+        width  = bytestream2_get_le16u(&gb);
+        height = bytestream2_get_le16u(&gb);
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "unsupported BMP file, patch welcome\n");
         return -1;
     }
 
-    if(bytestream_get_le16(&buf) != 1){ /* planes */
+    if (bytestream2_get_le16(&gb) != 1) { /* planes */
         av_log(avctx, AV_LOG_ERROR, "invalid BMP header\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    depth = bytestream_get_le16(&buf);
+    depth = bytestream2_get_le16(&gb);
 
     if(ihsize == 40)
-        comp = bytestream_get_le32(&buf);
+        comp = bytestream2_get_le32(&gb);
     else
         comp = BMP_RGB;
 
@@ -126,10 +106,10 @@ static int bmp_decode_frame(AVCodecContext *avctx,
     }
 
     if(comp == BMP_BITFIELDS){
-        buf += 20;
-        rgb[0] = bytestream_get_le32(&buf);
-        rgb[1] = bytestream_get_le32(&buf);
-        rgb[2] = bytestream_get_le32(&buf);
+        bytestream2_skip(&gb, 20);
+        rgb[0] = bytestream2_get_le32(&gb);
+        rgb[1] = bytestream2_get_le32(&gb);
+        rgb[2] = bytestream2_get_le32(&gb);
     }
 
     avctx->width = width;
@@ -187,40 +167,40 @@ static int bmp_decode_frame(AVCodecContext *avctx,
             avctx->pix_fmt = PIX_FMT_PAL8;
         }else{
             av_log(avctx, AV_LOG_ERROR, "Unknown palette for %d-colour BMP\n", 
1<<depth);
-            return -1;
+            return AVERROR_PATCHWELCOME;
         }
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "depth %d not supported\n", depth);
-        return -1;
+        return AVERROR_PATCHWELCOME;
     }
 
     if(avctx->pix_fmt == PIX_FMT_NONE){
         av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n");
-        return -1;
+        return AVERROR_PATCHWELCOME;
     }
 
     if(p->data[0])
         avctx->release_buffer(avctx, p);
 
     p->reference = 0;
-    if(avctx->get_buffer(avctx, p) < 0){
+    if ((ret = avctx->get_buffer(avctx, p)) < 0){
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
     p->pict_type = AV_PICTURE_TYPE_I;
     p->key_frame = 1;
 
-    buf = buf0 + hsize;
-    dsize = buf_size - hsize;
+    bytestream2_seek(&gb, hsize, SEEK_SET);
 
     /* Line size in file multiple of 4 */
     n = ((avctx->width * depth) / 8 + 3) & ~3;
 
-    if(n * avctx->height > dsize && comp != BMP_RLE4 && comp != BMP_RLE8){
+    if (n * avctx->height > bytestream2_get_bytes_left(&gb) &&
+        comp != BMP_RLE4 && comp != BMP_RLE8){
         av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n",
-               dsize, n * avctx->height);
-        return -1;
+               bytestream2_get_bytes_left(&gb), n * avctx->height);
+        return AVERROR_INVALIDDATA;
     }
 
     // RLE may skip decoding some picture areas, so blank picture before 
decoding
@@ -242,30 +222,31 @@ static int bmp_decode_frame(AVCodecContext *avctx,
         int colors = 1 << depth;
         if(ihsize >= 36){
             int t;
-            buf = buf0 + 46;
-            t = bytestream_get_le32(&buf);
+            bytestream2_seek(&gb, 46, SEEK_SET);
+            t = bytestream2_get_le32(&gb);
             if(t < 0 || t > (1 << depth)){
                 av_log(avctx, AV_LOG_ERROR, "Incorrect number of colors - %X 
for bitdepth %d\n", t, depth);
             }else if(t){
                 colors = t;
             }
         }
-        buf = buf0 + 14 + ihsize; //palette location
+        bytestream2_seek(&gb, 14 + ihsize, SEEK_SET); // palette location
         if((hsize-ihsize-14) < (colors << 2)){ // OS/2 bitmap, 3 bytes per 
palette entry
             for(i = 0; i < colors; i++)
-                ((uint32_t*)p->data[1])[i] = bytestream_get_le24(&buf);
+                ((uint32_t*)p->data[1])[i] = bytestream2_get_le24(&gb);
         }else{
             for(i = 0; i < colors; i++)
-                ((uint32_t*)p->data[1])[i] = bytestream_get_le32(&buf);
+                ((uint32_t*)p->data[1])[i] = bytestream2_get_le32(&gb);
         }
-        buf = buf0 + hsize;
+        bytestream2_seek(&gb, hsize, SEEK_SET);
     }
     if(comp == BMP_RLE4 || comp == BMP_RLE8){
         if(height < 0){
             p->data[0] += p->linesize[0] * (avctx->height - 1);
             p->linesize[0] = -p->linesize[0];
         }
-        ff_msrle_decode(avctx, (AVPicture*)p, depth, buf, dsize);
+        ff_msrle_decode(avctx, (AVPicture*)p, depth, avpkt->data + hsize,
+                        avpkt->size - hsize);
         if(height < 0){
             p->data[0] += p->linesize[0] * (avctx->height - 1);
             p->linesize[0] = -p->linesize[0];
@@ -276,24 +257,23 @@ static int bmp_decode_frame(AVCodecContext *avctx,
             for (i = 0; i < avctx->height; i++) {
                 int j;
                 for (j = 0; j < n; j++) {
-                    ptr[j*8+0] =  buf[j] >> 7;
-                    ptr[j*8+1] = (buf[j] >> 6) & 1;
-                    ptr[j*8+2] = (buf[j] >> 5) & 1;
-                    ptr[j*8+3] = (buf[j] >> 4) & 1;
-                    ptr[j*8+4] = (buf[j] >> 3) & 1;
-                    ptr[j*8+5] = (buf[j] >> 2) & 1;
-                    ptr[j*8+6] = (buf[j] >> 1) & 1;
-                    ptr[j*8+7] =  buf[j]       & 1;
+                    int byte = bytestream2_get_byteu(&gb);
+                    ptr[j*8+0] =  byte >> 7;
+                    ptr[j*8+1] = (byte >> 6) & 1;
+                    ptr[j*8+2] = (byte >> 5) & 1;
+                    ptr[j*8+3] = (byte >> 4) & 1;
+                    ptr[j*8+4] = (byte >> 3) & 1;
+                    ptr[j*8+5] = (byte >> 2) & 1;
+                    ptr[j*8+6] = (byte >> 1) & 1;
+                    ptr[j*8+7] =  byte       & 1;
                 }
-                buf += n;
                 ptr += linesize;
             }
             break;
         case 8:
         case 24:
             for(i = 0; i < avctx->height; i++){
-                memcpy(ptr, buf, n);
-                buf += n;
+                bytestream2_get_bufferu(&gb, ptr, n);
                 ptr += linesize;
             }
             break;
@@ -301,28 +281,29 @@ static int bmp_decode_frame(AVCodecContext *avctx,
             for(i = 0; i < avctx->height; i++){
                 int j;
                 for(j = 0; j < n; j++){
-                    ptr[j*2+0] = (buf[j] >> 4) & 0xF;
-                    ptr[j*2+1] = buf[j] & 0xF;
+                    int byte = bytestream2_get_byteu(&gb);
+                    ptr[j*2+0] = (byte >> 4) & 0xF;
+                    ptr[j*2+1] =  byte & 0xF;
                 }
-                buf += n;
                 ptr += linesize;
             }
             break;
-        case 16:
+        case 16: {
+            int padding = n - avctx->width * 2;
             for(i = 0; i < avctx->height; i++){
-                const uint16_t *src = (const uint16_t *) buf;
                 uint16_t *dst = (uint16_t *) ptr;
 
                 for(j = 0; j < avctx->width; j++)
-                    *dst++ = av_le2ne16(*src++);
+                    *dst++ = bytestream2_get_le16u(&gb);
 
-                buf += n;
+                bytestream2_skipu(&gb, padding);
                 ptr += linesize;
             }
             break;
-        case 32:
+        }
+        case 32: {
             for(i = 0; i < avctx->height; i++){
-                const uint8_t *src = buf;
+                const uint8_t *src = gb.buffer;
                 uint8_t *dst = ptr;
 
                 for(j = 0; j < avctx->width; j++){
@@ -330,13 +311,14 @@ static int bmp_decode_frame(AVCodecContext *avctx,
                     dst[1] = src[rgb[1]];
                     dst[2] = src[rgb[0]];
                     dst += 3;
-                    src += 4;
+                    bytestream2_skipu(&gb, 4);
                 }
 
-                buf += n;
+                bytestream2_skipu(&gb, n);
                 ptr += linesize;
             }
             break;
+        }
         default:
             av_log(avctx, AV_LOG_ERROR, "BMP decoder is broken\n");
             return -1;
-- 
1.7.2.1

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to