]> granicus.if.org Git - imagemagick/blobdiff - coders/bmp.c
...
[imagemagick] / coders / bmp.c
index cc036a1f5cc2ab256064334b3352c905a3a7d92f..ab5818379d1497d8a4a389aa338b9e7ed026b2b9 100644 (file)
@@ -18,7 +18,7 @@
 %                               December 2001                                 %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2017 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2018 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
@@ -75,7 +75,7 @@
 #define BI_JPEG  4
 #undef BI_PNG
 #define BI_PNG  5
-#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__MINGW32__) || defined(__MINGW64__)
+#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__MINGW32__)
 #undef BI_RGB
 #define BI_RGB  0
 #undef BI_RLE8
@@ -123,7 +123,7 @@ typedef enum
 */
 typedef struct _BMPInfo
 {
-  unsigned long
+  unsigned int
     file_size,
     ba_offset,
     offset_bits,
@@ -137,7 +137,7 @@ typedef struct _BMPInfo
     planes,
     bits_per_pixel;
 
-  unsigned long
+  unsigned int
     compression,
     image_size,
     x_pixels,
@@ -181,8 +181,8 @@ static MagickBooleanType
 %
 %  The format of the DecodeImage method is:
 %
-%      MagickBooleanType DecodeImage(Image *image,
-%        const size_t compression,unsigned char *pixels)
+%      MagickBooleanType DecodeImage(Image *image,const size_t compression,
+%        unsigned char *pixels,const size_t number_pixels)
 %
 %  A description of each parameter follows:
 %
@@ -196,11 +196,14 @@ static MagickBooleanType
 %    o pixels:  The address of a byte (8 bits) array of pixel data created by
 %      the decoding process.
 %
+%    o number_pixels:  The number of pixels.
+%
 */
 static MagickBooleanType DecodeImage(Image *image,const size_t compression,
-  unsigned char *pixels)
+  unsigned char *pixels,const size_t number_pixels)
 {
   int
+    byte,
     count;
 
   register ssize_t
@@ -214,20 +217,16 @@ static MagickBooleanType DecodeImage(Image *image,const size_t compression,
   ssize_t
     y;
 
-  unsigned char
-    byte;
-
   assert(image != (Image *) NULL);
   assert(image->signature == MagickCoreSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   assert(pixels != (unsigned char *) NULL);
-  (void) ResetMagickMemory(pixels,0,(size_t) image->columns*image->rows*
-    sizeof(*pixels));
+  (void) memset(pixels,0,number_pixels*sizeof(*pixels));
   byte=0;
   x=0;
   p=pixels;
-  q=pixels+(size_t) image->columns*image->rows;
+  q=pixels+number_pixels;
   for (y=0; y < (ssize_t) image->rows; )
   {
     MagickBooleanType
@@ -238,13 +237,15 @@ static MagickBooleanType DecodeImage(Image *image,const size_t compression,
     count=ReadBlobByte(image);
     if (count == EOF)
       break;
-    if (count != 0)
+    if (count > 0)
       {
         /*
           Encoded mode.
         */
         count=(int) MagickMin((ssize_t) count,(ssize_t) (q-p));
-        byte=(unsigned char) ReadBlobByte(image);
+        byte=ReadBlobByte(image);
+        if (byte == EOF)
+          break;
         if (compression == BI_RLE8)
           {
             for (i=0; i < (ssize_t) count; i++)
@@ -298,12 +299,21 @@ static MagickBooleanType DecodeImage(Image *image,const size_t compression,
             count=(int) MagickMin((ssize_t) count,(ssize_t) (q-p));
             if (compression == BI_RLE8)
               for (i=0; i < (ssize_t) count; i++)
-                *p++=(unsigned char) ReadBlobByte(image);
+              {
+                byte=ReadBlobByte(image);
+                if (byte == EOF)
+                  break;
+                *p++=(unsigned char) byte;
+              }
             else
               for (i=0; i < (ssize_t) count; i++)
               {
                 if ((i & 0x01) == 0)
-                  byte=(unsigned char) ReadBlobByte(image);
+                  {
+                    byte=ReadBlobByte(image);
+                    if (byte == EOF)
+                      break;
+                  }
                 *p++=(unsigned char)
                   ((i & 0x01) != 0 ? (byte & 0x0f) : ((byte >> 4) & 0x0f));
               }
@@ -314,11 +324,13 @@ static MagickBooleanType DecodeImage(Image *image,const size_t compression,
             if (compression == BI_RLE8)
               {
                 if ((count & 0x01) != 0)
-                  (void) ReadBlobByte(image);
+                  if (ReadBlobByte(image) == EOF)
+                    break;
               }
             else
               if (((count & 0x03) == 1) || ((count & 0x03) == 2))
-                (void) ReadBlobByte(image);
+                if (ReadBlobByte(image) == EOF)
+                  break;
             break;
           }
         }
@@ -528,11 +540,8 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
 
   size_t
     bit,
-    blue,
     bytes_per_line,
-    green,
-    length,
-    red;
+    length;
 
   ssize_t
     count,
@@ -542,6 +551,12 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
     magick[12],
     *pixels;
 
+  unsigned int
+    blue,
+    green,
+    offset_bits,
+    red;
+
   /*
     Open image file.
   */
@@ -562,9 +577,10 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
   /*
     Determine if this a BMP file.
   */
-  (void) ResetMagickMemory(&bmp_info,0,sizeof(bmp_info));
+  (void) memset(&bmp_info,0,sizeof(bmp_info));
   bmp_info.ba_offset=0;
   start_position=0;
+  offset_bits=0;
   count=ReadBlob(image,2,magick);
   if (count != 2)
     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
@@ -576,15 +592,10 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
     PixelPacket
       shift;
 
-    size_t
-      profile_data,
-      profile_size;
-
     /*
       Verify BMP identifier.
     */
-    if (bmp_info.ba_offset == 0)
-      start_position=TellBlob(image)-2;
+    start_position=TellBlob(image)-2;
     bmp_info.ba_offset=0;
     while (LocaleNCompare((char *) magick,"BA",2) == 0)
     {
@@ -606,7 +617,7 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
     bmp_info.offset_bits=ReadBlobLSBLong(image);
     bmp_info.size=ReadBlobLSBLong(image);
     if (image->debug != MagickFalse)
-      (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  BMP size: %lu",
+      (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  BMP size: %u",
         bmp_info.size);
     if (bmp_info.size == 12)
       {
@@ -649,9 +660,9 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         bmp_info.x_pixels=ReadBlobLSBLong(image);
         bmp_info.y_pixels=ReadBlobLSBLong(image);
         bmp_info.number_colors=ReadBlobLSBLong(image);
+        if (bmp_info.number_colors > GetBlobSize(image))
+          ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
         bmp_info.colors_important=ReadBlobLSBLong(image);
-        profile_data=0;
-        profile_size=0;
         if (image->debug != MagickFalse)
           {
             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
@@ -661,7 +672,7 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
               bmp_info.height);
             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
               "  Bits per pixel: %.20g",(double) bmp_info.bits_per_pixel);
-            switch ((int) bmp_info.compression)
+            switch (bmp_info.compression)
             {
               case BI_RGB:
               {
@@ -702,11 +713,11 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
               default:
               {
                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-                  "  Compression: UNKNOWN (%lu)",bmp_info.compression);
+                  "  Compression: UNKNOWN (%u)",bmp_info.compression);
               }
             }
             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-              "  Number of colors: %lu",bmp_info.number_colors);
+              "  Number of colors: %u",bmp_info.number_colors);
           }
         bmp_info.red_mask=ReadBlobLSBLong(image);
         bmp_info.green_mask=ReadBlobLSBLong(image);
@@ -806,10 +817,8 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
                 break;
               }
             }
-            profile_data=ReadBlobLSBLong(image);
-            profile_size=ReadBlobLSBLong(image);
-            (void) profile_data;
-            (void) profile_size;
+            (void) ReadBlobLSBLong(image);  /* Profile data */
+            (void) ReadBlobLSBLong(image);  /* Profile size */
             (void) ReadBlobLSBLong(image);  /* Reserved byte */
           }
       }
@@ -875,6 +884,15 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         if (image->colors == 0)
           image->colors=one << bmp_info.bits_per_pixel;
       }
+    image->resolution.x=(double) bmp_info.x_pixels/100.0;
+    image->resolution.y=(double) bmp_info.y_pixels/100.0;
+    image->units=PixelsPerCentimeterResolution;
+    if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
+      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
+        break;
+    status=SetImageExtent(image,image->columns,image->rows,exception);
+    if (status == MagickFalse)
+      return(DestroyImageList(image));
     if (image->storage_class == PseudoClass)
       {
         unsigned char
@@ -923,18 +941,12 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         }
         bmp_colormap=(unsigned char *) RelinquishMagickMemory(bmp_colormap);
       }
-    image->resolution.x=(double) bmp_info.x_pixels/100.0;
-    image->resolution.y=(double) bmp_info.y_pixels/100.0;
-    image->units=PixelsPerCentimeterResolution;
-    if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
-      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
-        break;
-    status=SetImageExtent(image,image->columns,image->rows,exception);
-    if (status == MagickFalse)
-      return(DestroyImageList(image));
     /*
       Read image data.
     */
+    if (bmp_info.offset_bits == offset_bits)
+      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+    offset_bits=bmp_info.offset_bits;
     offset=SeekBlob(image,start_position+bmp_info.offset_bits,SEEK_SET);
     if (offset < 0)
       ThrowReaderException(CorruptImageError,"ImproperImageHeader");
@@ -942,14 +954,16 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
       bmp_info.bits_per_pixel<<=1;
     bytes_per_line=4*((image->columns*bmp_info.bits_per_pixel+31)/32);
     length=(size_t) bytes_per_line*image->rows;
-    pixel_info=AcquireVirtualMemory((size_t) image->rows,
-      MagickMax(bytes_per_line,image->columns+256UL)*sizeof(*pixels));
-    if (pixel_info == (MemoryInfo *) NULL)
-      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
-    pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
+    if (((MagickSizeType) length/8) > GetBlobSize(image))
+      ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
     if ((bmp_info.compression == BI_RGB) ||
         (bmp_info.compression == BI_BITFIELDS))
       {
+        pixel_info=AcquireVirtualMemory(image->rows,
+          MagickMax(bytes_per_line,image->columns+256UL)*sizeof(*pixels));
+        if (pixel_info == (MemoryInfo *) NULL)
+          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+        pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
         if (image->debug != MagickFalse)
           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
             "  Reading pixels (%.20g bytes)",(double) length);
@@ -966,7 +980,13 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         /*
           Convert run-length encoded raster pixels.
         */
-        status=DecodeImage(image,bmp_info.compression,pixels);
+        pixel_info=AcquireVirtualMemory(image->rows,
+          MagickMax(bytes_per_line,image->columns+256UL)*sizeof(*pixels));
+        if (pixel_info == (MemoryInfo *) NULL)
+          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+        pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
+        status=DecodeImage(image,bmp_info.compression,pixels,
+          image->columns*image->rows);
         if (status == MagickFalse)
           {
             pixel_info=RelinquishVirtualMemory(pixel_info);
@@ -1020,11 +1040,11 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
             bmp_info.blue_mask=0x0000001fU;
           }
       }
-    (void) ResetMagickMemory(&shift,0,sizeof(shift));
-    (void) ResetMagickMemory(&quantum_bits,0,sizeof(quantum_bits));
+    (void) memset(&shift,0,sizeof(shift));
+    (void) memset(&quantum_bits,0,sizeof(quantum_bits));
     if ((bmp_info.bits_per_pixel == 16) || (bmp_info.bits_per_pixel == 32))
       {
-        register size_t
+        register unsigned int
           sample;
 
         /*
@@ -1032,31 +1052,63 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         */
         if (bmp_info.red_mask != 0)
           while (((bmp_info.red_mask << shift.red) & 0x80000000UL) == 0)
+          {
             shift.red++;
+            if (shift.red >= 32U)
+              break;
+          }
         if (bmp_info.green_mask != 0)
           while (((bmp_info.green_mask << shift.green) & 0x80000000UL) == 0)
+          {
             shift.green++;
+            if (shift.green >= 32U)
+              break;
+          }
         if (bmp_info.blue_mask != 0)
           while (((bmp_info.blue_mask << shift.blue) & 0x80000000UL) == 0)
+          {
             shift.blue++;
+            if (shift.blue >= 32U)
+              break;
+          }
         if (bmp_info.alpha_mask != 0)
           while (((bmp_info.alpha_mask << shift.alpha) & 0x80000000UL) == 0)
+          {
             shift.alpha++;
+            if (shift.alpha >= 32U)
+              break;
+          }
         sample=shift.red;
         while (((bmp_info.red_mask << sample) & 0x80000000UL) != 0)
+        {
           sample++;
+          if (sample >= 32U)
+            break;
+        }
         quantum_bits.red=(MagickRealType) (sample-shift.red);
         sample=shift.green;
         while (((bmp_info.green_mask << sample) & 0x80000000UL) != 0)
+        {
           sample++;
+          if (sample >= 32U)
+            break;
+        }
         quantum_bits.green=(MagickRealType) (sample-shift.green);
         sample=shift.blue;
         while (((bmp_info.blue_mask << sample) & 0x80000000UL) != 0)
+        {
           sample++;
+          if (sample >= 32U)
+            break;
+        }
         quantum_bits.blue=(MagickRealType) (sample-shift.blue);
         sample=shift.alpha;
         while (((bmp_info.alpha_mask << sample) & 0x80000000UL) != 0)
+        {
           sample++;
+          if (sample >= 32U)
+            break;
+        }
         quantum_bits.alpha=(MagickRealType) (sample-shift.alpha);
       }
     switch (bmp_info.bits_per_pixel)
@@ -1118,17 +1170,19 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
             break;
           for (x=0; x < ((ssize_t) image->columns-1); x+=2)
           {
-            ValidateColormapValue(image,(*p >> 4) & 0x0f,&index,exception);
+            ValidateColormapValue(image,(ssize_t) ((*p >> 4) & 0x0f),&index,
+              exception);
             SetPixelIndex(image,index,q);
             q+=GetPixelChannels(image);
-            ValidateColormapValue(image,*p & 0x0f,&index,exception);
+            ValidateColormapValue(image,(ssize_t) (*p & 0x0f),&index,exception);
             SetPixelIndex(image,index,q);
             q+=GetPixelChannels(image);
             p++;
           }
           if ((image->columns % 2) != 0)
             {
-              ValidateColormapValue(image,(*p >> 4) & 0xf,&index,exception);
+              ValidateColormapValue(image,(ssize_t) ((*p >> 4) & 0xf),&index,
+                exception);
               SetPixelIndex(image,index,q);
               q+=GetPixelChannels(image);
               p++;
@@ -1165,7 +1219,7 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
             break;
           for (x=(ssize_t) image->columns; x != 0; --x)
           {
-            ValidateColormapValue(image,*p++,&index,exception);
+            ValidateColormapValue(image,(ssize_t) *p++,&index,exception);
             SetPixelIndex(image,index,q);
             q+=GetPixelChannels(image);
           }
@@ -1185,15 +1239,15 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
       }
       case 16:
       {
-        size_t
+        unsigned int
           alpha,
           pixel;
 
         /*
           Convert bitfield encoded 16-bit PseudoColor scanline.
         */
-        if (bmp_info.compression != BI_RGB &&
-            bmp_info.compression != BI_BITFIELDS)
+        if ((bmp_info.compression != BI_RGB) &&
+            (bmp_info.compression != BI_BITFIELDS))
           {
             pixel_info=RelinquishVirtualMemory(pixel_info);
             ThrowReaderException(CorruptImageError,
@@ -1209,7 +1263,7 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
             break;
           for (x=0; x < (ssize_t) image->columns; x++)
           {
-            pixel=(size_t) (*p++);
+            pixel=(unsigned int) (*p++);
             pixel|=(*p++) << 8;
             red=((pixel & bmp_info.red_mask) << shift.red) >> 16;
             if (quantum_bits.red == 5)
@@ -1303,7 +1357,7 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         bytes_per_line=4*(image->columns);
         for (y=(ssize_t) image->rows-1; y >= 0; y--)
         {
-          size_t
+          unsigned int
             alpha,
             pixel;
 
@@ -1313,10 +1367,10 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
             break;
           for (x=0; x < (ssize_t) image->columns; x++)
           {
-            pixel=(size_t) (*p++);
-            pixel|=((size_t) *p++ << 8);
-            pixel|=((size_t) *p++ << 16);
-            pixel|=((size_t) *p++ << 24);
+            pixel=(unsigned int) (*p++);
+            pixel|=((unsigned int) *p++ << 8);
+            pixel|=((unsigned int) *p++ << 16);
+            pixel|=((unsigned int) *p++ << 24);
             red=((pixel & bmp_info.red_mask) << shift.red) >> 16;
             if (quantum_bits.red == 8)
               red|=(red >> 8);
@@ -1380,7 +1434,7 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         if (flipped_image != (Image *) NULL)
           {
             DuplicateBlob(flipped_image,image);
-            image=DestroyImage(image);
+            ReplaceImageInList(&image, flipped_image);
             image=flipped_image;
           }
       }
@@ -1406,7 +1460,7 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         AcquireNextImage(image_info,image,exception);
         if (GetNextImageInList(image) == (Image *) NULL)
           {
-            image=DestroyImageList(image);
+            status=MagickFalse;
             return((Image *) NULL);
           }
         image=SyncNextImageInList(image);
@@ -1417,6 +1471,8 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
       }
   } while (IsBMP(magick,2) != MagickFalse);
   (void) CloseBlob(image);
+  if (status == MagickFalse)
+    return(DestroyImageList(image));
   return(GetFirstImageInList(image));
 }
 \f
@@ -1456,12 +1512,14 @@ ModuleExport size_t RegisterBMPImage(void)
   entry->flags|=CoderDecoderSeekableStreamFlag;
   (void) RegisterMagickInfo(entry);
   entry=AcquireMagickInfo("BMP","BMP2","Microsoft Windows bitmap image (V2)");
+  entry->decoder=(DecodeImageHandler *) ReadBMPImage;
   entry->encoder=(EncodeImageHandler *) WriteBMPImage;
   entry->magick=(IsImageFormatHandler *) IsBMP;
   entry->flags^=CoderAdjoinFlag;
   entry->flags|=CoderDecoderSeekableStreamFlag;
   (void) RegisterMagickInfo(entry);
   entry=AcquireMagickInfo("BMP","BMP3","Microsoft Windows bitmap image (V3)");
+  entry->decoder=(DecodeImageHandler *) ReadBMPImage;
   entry->encoder=(EncodeImageHandler *) WriteBMPImage;
   entry->magick=(IsImageFormatHandler *) IsBMP;
   entry->flags^=CoderAdjoinFlag;
@@ -1562,6 +1620,7 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
 
   size_t
     bytes_per_line,
+    imageListLength,
     type;
 
   ssize_t
@@ -1591,13 +1650,11 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
   else
     if (LocaleCompare(image_info->magick,"BMP3") == 0)
       type=3;
-
   option=GetImageOption(image_info,"bmp:format");
   if (option != (char *) NULL)
     {
       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
           "  Format=%s",option);
-
       if (LocaleCompare(option,"bmp2") == 0)
         type=2;
       if (LocaleCompare(option,"bmp3") == 0)
@@ -1605,15 +1662,16 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
       if (LocaleCompare(option,"bmp4") == 0)
         type=4;
     }
-
   scene=0;
+  imageListLength=GetImageListLength(image);
   do
   {
     /*
       Initialize BMP raster file header.
     */
-    (void) TransformImageColorspace(image,sRGBColorspace,exception);
-    (void) ResetMagickMemory(&bmp_info,0,sizeof(bmp_info));
+    if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
+      (void) TransformImageColorspace(image,sRGBColorspace,exception);
+    (void) memset(&bmp_info,0,sizeof(bmp_info));
     bmp_info.file_size=14+12;
     if (type > 2)
       bmp_info.file_size+=28;
@@ -1757,13 +1815,13 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
           bmp_info.file_size+=extra_size;
           bmp_info.offset_bits+=extra_size;
         }
-    if (((ssize_t) image->columns != (signed int) image->columns) ||
-        ((ssize_t) image->rows != (signed int) image->rows))
+    if (((ssize_t) image->columns != (ssize_t) ((signed int) image->columns)) ||
+        ((ssize_t) image->rows != (ssize_t) ((signed int) image->rows)))
       ThrowWriterException(ImageError,"WidthOrHeightExceedsLimit");
     bmp_info.width=(ssize_t) image->columns;
     bmp_info.height=(ssize_t) image->rows;
     bmp_info.planes=1;
-    bmp_info.image_size=(unsigned long) (bytes_per_line*image->rows);
+    bmp_info.image_size=(unsigned int) (bytes_per_line*image->rows);
     bmp_info.file_size+=bmp_info.image_size;
     bmp_info.x_pixels=75*39;
     bmp_info.y_pixels=75*39;
@@ -1787,12 +1845,12 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
     /*
       Convert MIFF to BMP raster pixels.
     */
-    pixel_info=AcquireVirtualMemory((size_t) bmp_info.image_size,
-      sizeof(*pixels));
+    pixel_info=AcquireVirtualMemory(image->rows,
+      MagickMax(bytes_per_line,image->columns+256UL)*sizeof(*pixels));
     if (pixel_info == (MemoryInfo *) NULL)
       ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
     pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
-    (void) ResetMagickMemory(pixels,0,(size_t) bmp_info.image_size);
+    (void) memset(pixels,0,(size_t) bmp_info.image_size);
     switch (bmp_info.bits_per_pixel)
     {
       case 1:
@@ -1848,7 +1906,7 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
       }
       case 4:
       {
-        size_t
+        unsigned int
           byte,
           nibble;
 
@@ -1869,7 +1927,7 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
           for (x=0; x < (ssize_t) image->columns; x++)
           {
             byte<<=4;
-            byte|=((size_t) GetPixelIndex(image,p) & 0x0f);
+            byte|=((unsigned int) GetPixelIndex(image,p) & 0x0f);
             nibble++;
             if (nibble == 2)
               {
@@ -1944,35 +2002,35 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
             pixel=0;
             if (bmp_subtype == ARGB4444)
               {
-                pixel=(unsigned short) ScaleQuantumToAny(
-                  GetPixelAlpha(image,p),15) << 12;
-                pixel|=(unsigned short) ScaleQuantumToAny(
-                  GetPixelRed(image,p),15) << 8;
-                pixel|=(unsigned short) ScaleQuantumToAny(
-                  GetPixelGreen(image,p),15) << 4;
-                pixel|=(unsigned short) ScaleQuantumToAny(
-                  GetPixelBlue(image,p),15);
+                pixel=(unsigned short) (ScaleQuantumToAny(
+                  GetPixelAlpha(image,p),15) << 12);
+                pixel|=(unsigned short) (ScaleQuantumToAny(
+                  GetPixelRed(image,p),15) << 8);
+                pixel|=(unsigned short) (ScaleQuantumToAny(
+                  GetPixelGreen(image,p),15) << 4);
+                pixel|=(unsigned short) (ScaleQuantumToAny(
+                  GetPixelBlue(image,p),15));
               }
             else if (bmp_subtype == RGB565)
               {
-                pixel=(unsigned short) ScaleQuantumToAny(
-                  GetPixelRed(image,p),31) << 11;
-                pixel|=(unsigned short) ScaleQuantumToAny(
-                  GetPixelGreen(image,p),63) << 5;
-                pixel|=(unsigned short) ScaleQuantumToAny(
-                  GetPixelBlue(image,p),31);
+                pixel=(unsigned short) (ScaleQuantumToAny(
+                  GetPixelRed(image,p),31) << 11);
+                pixel|=(unsigned short) (ScaleQuantumToAny(
+                  GetPixelGreen(image,p),63) << 5);
+                pixel|=(unsigned short) (ScaleQuantumToAny(
+                  GetPixelBlue(image,p),31));
               }
             else
               {
                 if (bmp_subtype == ARGB1555)
-                  pixel=(unsigned short) ScaleQuantumToAny(
-                    GetPixelAlpha(image,p),1) << 15;
-                pixel|=(unsigned short) ScaleQuantumToAny(
-                  GetPixelRed(image,p),31) << 10;
-                pixel|=(unsigned short) ScaleQuantumToAny(
-                  GetPixelGreen(image,p),31) << 5;
-                pixel|=(unsigned short) ScaleQuantumToAny(
-                  GetPixelBlue(image,p),31);
+                  pixel=(unsigned short) (ScaleQuantumToAny(
+                    GetPixelAlpha(image,p),1) << 15);
+                pixel|=(unsigned short) (ScaleQuantumToAny(
+                  GetPixelRed(image,p),31) << 10);
+                pixel|=(unsigned short) (ScaleQuantumToAny(
+                  GetPixelGreen(image,p),31) << 5);
+                pixel|=(unsigned short) (ScaleQuantumToAny(
+                  GetPixelBlue(image,p),31));
               }
             *((unsigned short *) q)=pixel;
             q+=2;
@@ -2122,7 +2180,7 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
            default:
            {
              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-               "   Compression=UNKNOWN (%lu)",bmp_info.compression);
+               "   Compression=UNKNOWN (%u)",bmp_info.compression);
              break;
            }
         }
@@ -2131,7 +2189,7 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
             "   Number_colors=unspecified");
         else
           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-            "   Number_colors=%lu",bmp_info.number_colors);
+            "   Number_colors=%u",bmp_info.number_colors);
       }
     (void) WriteBlob(image,2,(unsigned char *) "BM");
     (void) WriteBlobLSBLong(image,bmp_info.file_size);
@@ -2285,14 +2343,13 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
       }
     if (image->debug != MagickFalse)
       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-        "  Pixels:  %lu bytes",bmp_info.image_size);
+        "  Pixels:  %u bytes",bmp_info.image_size);
     (void) WriteBlob(image,(size_t) bmp_info.image_size,pixels);
     pixel_info=RelinquishVirtualMemory(pixel_info);
     if (GetNextImageInList(image) == (Image *) NULL)
       break;
     image=SyncNextImageInList(image);
-    status=SetImageProgress(image,SaveImagesTag,scene++,
-      GetImageListLength(image));
+    status=SetImageProgress(image,SaveImagesTag,scene++,imageListLength);
     if (status == MagickFalse)
       break;
   } while (image_info->adjoin != MagickFalse);