]> granicus.if.org Git - imagemagick/blobdiff - coders/bmp.c
(no commit message)
[imagemagick] / coders / bmp.c
index 4cf51c1e79215e6a3ad6cae6ba0d495f65501947..1f16c79144cae24d8929b5006dae5096db6f4ff4 100644 (file)
@@ -18,7 +18,7 @@
 %                               December 2001                                 %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2013 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  %
 #define BI_JPEG  4
 #undef BI_PNG
 #define BI_PNG  5
-#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__MINGW32__)
+#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__MINGW32__) || defined(__MINGW64__)
+#undef BI_RGB
 #define BI_RGB  0
+#undef BI_RLE8
 #define BI_RLE8  1
+#undef BI_RLE4
 #define BI_RLE4  2
+#undef BI_BITFIELDS
 #define BI_BITFIELDS  3
 
+#undef LCS_CALIBRATED_RBG
 #define LCS_CALIBRATED_RBG  0
+#undef LCS_sRGB
 #define LCS_sRGB  1
+#undef LCS_WINDOWS_COLOR_SPACE
 #define LCS_WINDOWS_COLOR_SPACE  2
+#undef PROFILE_LINKED
 #define PROFILE_LINKED  3
+#undef PROFILE_EMBEDDED
 #define PROFILE_EMBEDDED  4
 
+#undef LCS_GM_BUSINESS
 #define LCS_GM_BUSINESS  1  /* Saturation */
+#undef LCS_GM_GRAPHICS
 #define LCS_GM_GRAPHICS  2  /* Relative */
+#undef LCS_GM_IMAGES
 #define LCS_GM_IMAGES  4  /* Perceptual */
+#undef LCS_GM_ABS_COLORIMETRIC
 #define LCS_GM_ABS_COLORIMETRIC  8  /* Absolute */
 #endif
 \f
@@ -103,7 +116,7 @@ typedef struct _BMPInfo
     offset_bits,
     size;
 
-  ssize_t
+  int
     width,
     height;
 
@@ -196,9 +209,6 @@ static inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
 static MagickBooleanType DecodeImage(Image *image,const size_t compression,
   unsigned char *pixels)
 {
-  int
-    count;
-
   register ssize_t
     i,
     x;
@@ -208,6 +218,7 @@ static MagickBooleanType DecodeImage(Image *image,const size_t compression,
     *q;
 
   ssize_t
+    count,
     y;
 
   unsigned char
@@ -228,15 +239,15 @@ static MagickBooleanType DecodeImage(Image *image,const size_t compression,
   {
     if ((p < pixels) || (p >= q))
       break;
-    count=ReadBlobByte(image);
-    if (count == EOF)
+    count=(ssize_t) ReadBlobByte(image);
+    if ((int) count == EOF)
       break;
     if (count != 0)
       {
         /*
           Encoded mode.
         */
-        count=MagickMin(count,(int) (q-p));
+        count=MagickMin(count,(ssize_t) (q-p));
         byte=(unsigned char) ReadBlobByte(image);
         if (compression == BI_RLE8)
           {
@@ -256,7 +267,7 @@ static MagickBooleanType DecodeImage(Image *image,const size_t compression,
         /*
           Escape mode.
         */
-        count=ReadBlobByte(image);
+        count=(ssize_t) ReadBlobByte(image);
         if (count == 0x01)
           return(MagickTrue);
         switch (count)
@@ -286,7 +297,7 @@ static MagickBooleanType DecodeImage(Image *image,const size_t compression,
             /*
               Absolute mode.
             */
-            count=MagickMin(count,(int) (q-p));
+            count=MagickMin(count,(ssize_t) (q-p));
             if (compression == BI_RLE8)
               for (i=0; i < count; i++)
                 *p++=(unsigned char) ReadBlobByte(image);
@@ -314,7 +325,7 @@ static MagickBooleanType DecodeImage(Image *image,const size_t compression,
           }
         }
       }
-    if (SetImageProgress(image,LoadImageTag,y,image->rows) == MagickFalse)
+    if (SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,image->rows) == MagickFalse)
       break;
   }
   (void) ReadBlobByte(image);  /* end of line */
@@ -493,6 +504,7 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
     *image;
 
   MagickBooleanType
+    mapped,
     status;
 
   MagickOffsetType
@@ -697,6 +709,7 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         bmp_info.blue_mask=ReadBlobLSBLong(image);
         if (bmp_info.size > 40)
           {
+
             double
               sum;
 
@@ -708,39 +721,51 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
             /*
               Decode 2^30 fixed point formatted CIE primaries.
             */
-            bmp_info.red_primary.x=(double) ReadBlobLSBLong(image)/0x3ffffff;
-            bmp_info.red_primary.y=(double) ReadBlobLSBLong(image)/0x3ffffff;
-            bmp_info.red_primary.z=(double) ReadBlobLSBLong(image)/0x3ffffff;
-            bmp_info.green_primary.x=(double) ReadBlobLSBLong(image)/0x3ffffff;
-            bmp_info.green_primary.y=(double) ReadBlobLSBLong(image)/0x3ffffff;
-            bmp_info.green_primary.z=(double) ReadBlobLSBLong(image)/0x3ffffff;
-            bmp_info.blue_primary.x=(double) ReadBlobLSBLong(image)/0x3ffffff;
-            bmp_info.blue_primary.y=(double) ReadBlobLSBLong(image)/0x3ffffff;
-            bmp_info.blue_primary.z=(double) ReadBlobLSBLong(image)/0x3ffffff;
+#           define BMP_DENOM ((double) 0x40000000)
+            bmp_info.red_primary.x=(double) ReadBlobLSBLong(image)/BMP_DENOM;
+            bmp_info.red_primary.y=(double) ReadBlobLSBLong(image)/BMP_DENOM;
+            bmp_info.red_primary.z=(double) ReadBlobLSBLong(image)/BMP_DENOM;
+            bmp_info.green_primary.x=(double) ReadBlobLSBLong(image)/BMP_DENOM;
+            bmp_info.green_primary.y=(double) ReadBlobLSBLong(image)/BMP_DENOM;
+            bmp_info.green_primary.z=(double) ReadBlobLSBLong(image)/BMP_DENOM;
+            bmp_info.blue_primary.x=(double) ReadBlobLSBLong(image)/BMP_DENOM;
+            bmp_info.blue_primary.y=(double) ReadBlobLSBLong(image)/BMP_DENOM;
+            bmp_info.blue_primary.z=(double) ReadBlobLSBLong(image)/BMP_DENOM;
+
             sum=bmp_info.red_primary.x+bmp_info.red_primary.y+
               bmp_info.red_primary.z;
-            image->chromaticity.red_primary.x/=sum;
-            image->chromaticity.red_primary.y/=sum;
+            bmp_info.red_primary.x/=sum;
+            bmp_info.red_primary.y/=sum;
+            image->chromaticity.red_primary.x=bmp_info.red_primary.x;
+            image->chromaticity.red_primary.y=bmp_info.red_primary.y;
+
             sum=bmp_info.green_primary.x+bmp_info.green_primary.y+
               bmp_info.green_primary.z;
-            image->chromaticity.green_primary.x/=sum;
-            image->chromaticity.green_primary.y/=sum;
+            bmp_info.green_primary.x/=sum;
+            bmp_info.green_primary.y/=sum;
+            image->chromaticity.green_primary.x=bmp_info.green_primary.x;
+            image->chromaticity.green_primary.y=bmp_info.green_primary.y;
+
             sum=bmp_info.blue_primary.x+bmp_info.blue_primary.y+
               bmp_info.blue_primary.z;
-            image->chromaticity.blue_primary.x/=sum;
-            image->chromaticity.blue_primary.y/=sum;
+            bmp_info.blue_primary.x/=sum;
+            bmp_info.blue_primary.y/=sum;
+            image->chromaticity.blue_primary.x=bmp_info.blue_primary.x;
+            image->chromaticity.blue_primary.y=bmp_info.blue_primary.y;
+
             /*
               Decode 16^16 fixed point formatted gamma_scales.
             */
-            bmp_info.gamma_scale.x=(double) ReadBlobLSBLong(image)/0xffff;
-            bmp_info.gamma_scale.y=(double) ReadBlobLSBLong(image)/0xffff;
-            bmp_info.gamma_scale.z=(double) ReadBlobLSBLong(image)/0xffff;
+            bmp_info.gamma_scale.x=(double) ReadBlobLSBLong(image)/0x10000;
+            bmp_info.gamma_scale.y=(double) ReadBlobLSBLong(image)/0x10000;
+            bmp_info.gamma_scale.z=(double) ReadBlobLSBLong(image)/0x10000;
             /*
               Compute a single gamma from the BMP 3-channel gamma.
             */
             image->gamma=(bmp_info.gamma_scale.x+bmp_info.gamma_scale.y+
               bmp_info.gamma_scale.z)/3.0;
           }
+
         if (bmp_info.size > 108)
           {
             size_t
@@ -798,11 +823,11 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         (bmp_info.bits_per_pixel != 8) && (bmp_info.bits_per_pixel != 16) &&
         (bmp_info.bits_per_pixel != 24) && (bmp_info.bits_per_pixel != 32))
       ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
-    if (bmp_info.number_colors > (1U << bmp_info.bits_per_pixel))
+    if (bmp_info.bits_per_pixel < 16 &&
+        bmp_info.number_colors > (1U << bmp_info.bits_per_pixel))
       {
-        if (bmp_info.bits_per_pixel < 24)
-          ThrowReaderException(CorruptImageError,"UnrecognizedNumberOfColors");
-        bmp_info.number_colors=0;
+        ThrowReaderException(CorruptImageError,
+            "UnrecognizedNumberOfColors");
       }
     if ((bmp_info.compression == 1) && (bmp_info.bits_per_pixel != 8))
       ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
@@ -824,13 +849,13 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
       default:
         ThrowReaderException(CorruptImageError,"UnrecognizedImageCompression");
     }
-    image->columns=(size_t) MagickAbsoluteValue(bmp_info.width);
-    image->rows=(size_t) MagickAbsoluteValue(bmp_info.height);
+    image->columns=(size_t) MagickAbsoluteValue((ssize_t) bmp_info.width);
+    image->rows=(size_t) MagickAbsoluteValue((ssize_t) bmp_info.height);
     image->depth=bmp_info.bits_per_pixel <= 8 ? bmp_info.bits_per_pixel : 8;
-    if ((bmp_info.bits_per_pixel == 16) ||
-        (bmp_info.bits_per_pixel == 32))
-      image->matte=bmp_info.alpha_mask != 0 ? MagickTrue : MagickFalse;
-    if ((bmp_info.number_colors != 0) || (bmp_info.bits_per_pixel < 16))
+    image->alpha_trait=(bmp_info.alpha_mask != 0) &&
+      (bmp_info.compression == BI_BITFIELDS) ? BlendPixelTrait :
+      UndefinedPixelTrait;
+    if (bmp_info.bits_per_pixel < 16)
       {
         size_t
           one;
@@ -874,14 +899,17 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         p=bmp_colormap;
         for (i=0; i < (ssize_t) image->colors; i++)
         {
-          image->colormap[i].blue=ScaleCharToQuantum(*p++);
-          image->colormap[i].green=ScaleCharToQuantum(*p++);
-          image->colormap[i].red=ScaleCharToQuantum(*p++);
+          image->colormap[i].blue=(MagickRealType) ScaleCharToQuantum(*p++);
+          image->colormap[i].green=(MagickRealType) ScaleCharToQuantum(*p++);
+          image->colormap[i].red=(MagickRealType) ScaleCharToQuantum(*p++);
           if (packet_size == 4)
             p++;
         }
         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;
@@ -895,22 +923,34 @@ 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;
-    pixels=(unsigned char *) AcquireQuantumMemory((size_t) image->rows,
-      MagickMax(bytes_per_line,image->columns+256UL)*sizeof(*pixels));
-    if (pixels == (unsigned char *) NULL)
-      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+    mapped=MagickFalse;
     if ((bmp_info.compression == BI_RGB) ||
         (bmp_info.compression == BI_BITFIELDS))
       {
         if (image->debug != MagickFalse)
           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
             "  Reading pixels (%.20g bytes)",(double) length);
-        count=ReadBlob(image,length,pixels);
-        if (count != (ssize_t) length)
+        if (GetBlobStreamData(image) != (unsigned char *) NULL)
           {
-            pixels=(unsigned char *) RelinquishMagickMemory(pixels);
-            ThrowReaderException(CorruptImageError,
-              "InsufficientImageDataInFile");
+            mapped=MagickTrue;
+            pixels=GetBlobStreamData(image)+TellBlob(image);
+            if (DiscardBlobBytes(image,length) == MagickFalse)
+              ThrowReaderException(CorruptImageError,
+                "InsufficientImageDataInFile");
+          }
+        else
+          {
+            pixels=(unsigned char *) AcquireQuantumMemory((size_t) image->rows,
+              MagickMax(bytes_per_line,image->columns)*sizeof(*pixels));
+            if (pixels == (unsigned char *) NULL)
+              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+            count=ReadBlob(image,length,pixels);
+            if (count != (ssize_t) length)
+              {
+                pixels=(unsigned char *) RelinquishMagickMemory(pixels);
+                ThrowReaderException(CorruptImageError,
+                  "InsufficientImageDataInFile");
+              }
           }
       }
     else
@@ -918,6 +958,10 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         /*
           Convert run-length encoded raster pixels.
         */
+        pixels=(unsigned char *) AcquireQuantumMemory((size_t) image->rows,
+          MagickMax(bytes_per_line,image->columns+256UL)*sizeof(*pixels));
+        if (pixels == (unsigned char *) NULL)
+          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
         status=DecodeImage(image,bmp_info.compression,pixels);
         if (status == MagickFalse)
           {
@@ -926,18 +970,13 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
               "UnableToRunlengthDecodeImage");
           }
       }
-    /*
-      Initialize image structure.
-    */
-    image->x_resolution=(double) bmp_info.x_pixels/100.0;
-    image->y_resolution=(double) bmp_info.y_pixels/100.0;
-    image->units=PixelsPerCentimeterResolution;
     /*
       Convert BMP raster image to pixel packets.
     */
     if (bmp_info.compression == BI_RGB)
       {
-        bmp_info.alpha_mask=0;
+        bmp_info.alpha_mask=image->alpha_trait == BlendPixelTrait ?
+          0xff000000U : 0U;
         bmp_info.red_mask=0x00ff0000U;
         bmp_info.green_mask=0x0000ff00U;
         bmp_info.blue_mask=0x000000ffU;
@@ -976,19 +1015,19 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         sample=shift.red;
         while (((bmp_info.red_mask << sample) & 0x80000000UL) != 0)
           sample++;
-        quantum_bits.red=(Quantum) (sample-shift.red);
+        quantum_bits.red=(MagickRealType) (sample-shift.red);
         sample=shift.green;
         while (((bmp_info.green_mask << sample) & 0x80000000UL) != 0)
           sample++;
-        quantum_bits.green=(Quantum) (sample-shift.green);
+        quantum_bits.green=(MagickRealType) (sample-shift.green);
         sample=shift.blue;
         while (((bmp_info.blue_mask << sample) & 0x80000000UL) != 0)
           sample++;
-        quantum_bits.blue=(Quantum) (sample-shift.blue);
+        quantum_bits.blue=(MagickRealType) (sample-shift.blue);
         sample=shift.alpha;
         while (((bmp_info.alpha_mask << sample) & 0x80000000UL) != 0)
           sample++;
-        quantum_bits.alpha=(Quantum) (sample-shift.alpha);
+        quantum_bits.alpha=(MagickRealType) (sample-shift.alpha);
       }
     switch (bmp_info.bits_per_pixel)
     {
@@ -1049,17 +1088,17 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
             break;
           for (x=0; x < ((ssize_t) image->columns-1); x+=2)
           {
-            index=ConstrainColormapIndex(image,(*p >> 4) & 0x0f);
+            index=ConstrainColormapIndex(image,(*p >> 4) & 0x0f,exception);
             SetPixelIndex(image,index,q);
             q+=GetPixelChannels(image);
-            index=ConstrainColormapIndex(image,*p & 0x0f);
+            index=ConstrainColormapIndex(image,*p & 0x0f,exception);
             SetPixelIndex(image,index,q);
             q+=GetPixelChannels(image);
             p++;
           }
           if ((image->columns % 2) != 0)
             {
-              index=ConstrainColormapIndex(image,(*p >> 4) & 0xf);
+              index=ConstrainColormapIndex(image,(*p >> 4) & 0xf,exception);
               SetPixelIndex(image,index,q);
               q+=GetPixelChannels(image);
               p++;
@@ -1091,9 +1130,9 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
           if (q == (Quantum *) NULL)
             break;
-          for (x = (ssize_t)image->columns; x != 0; --x)
+          for (x=(ssize_t) image->columns; x != 0; --x)
           {
-            index=ConstrainColormapIndex(image,*p++);
+            index=ConstrainColormapIndex(image,*p++,exception);
             SetPixelIndex(image,index,q);
             q+=GetPixelChannels(image);
           }
@@ -1122,7 +1161,8 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         if (bmp_info.compression != BI_RGB &&
             bmp_info.compression != BI_BITFIELDS)
           {
-            pixels=(unsigned char *) RelinquishMagickMemory(pixels);
+            if (mapped == MagickFalse)
+              pixels=(unsigned char *) RelinquishMagickMemory(pixels);
             ThrowReaderException(CorruptImageError,
               "UnrecognizedImageCompression");
           }
@@ -1162,7 +1202,7 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
             SetPixelGreen(image,ScaleShortToQuantum((unsigned short) green),q);
             SetPixelBlue(image,ScaleShortToQuantum((unsigned short) blue),q);
             SetPixelAlpha(image,OpaqueAlpha,q);
-            if (image->matte != MagickFalse)
+            if (image->alpha_trait == BlendPixelTrait)
               SetPixelAlpha(image,
                 ScaleShortToQuantum((unsigned short) opacity),q);
             q+=GetPixelChannels(image);
@@ -1221,7 +1261,8 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
         if ((bmp_info.compression != BI_RGB) &&
             (bmp_info.compression != BI_BITFIELDS))
           {
-            pixels=(unsigned char *) RelinquishMagickMemory(pixels);
+            if (mapped == MagickFalse)
+              pixels=(unsigned char *) RelinquishMagickMemory(pixels);
             ThrowReaderException(CorruptImageError,
               "UnrecognizedImageCompression");
           }
@@ -1257,7 +1298,7 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
             SetPixelGreen(image,ScaleShortToQuantum((unsigned short) green),q);
             SetPixelBlue(image,ScaleShortToQuantum((unsigned short) blue),q);
             SetPixelAlpha(image,OpaqueAlpha,q);
-            if (image->matte != MagickFalse)
+            if (image->alpha_trait == BlendPixelTrait)
               SetPixelAlpha(image,
                 ScaleShortToQuantum((unsigned short) opacity),q);
             q+=GetPixelChannels(image);
@@ -1277,11 +1318,13 @@ static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
       }
       default:
       {
-        pixels=(unsigned char *) RelinquishMagickMemory(pixels);
+        if (mapped == MagickFalse)
+          pixels=(unsigned char *) RelinquishMagickMemory(pixels);
         ThrowReaderException(CorruptImageError,"ImproperImageHeader");
       }
     }
-    pixels=(unsigned char *) RelinquishMagickMemory(pixels);
+    if (mapped == MagickFalse)
+      pixels=(unsigned char *) RelinquishMagickMemory(pixels);
     if (EOFBlob(image) != MagickFalse)
       {
         ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
@@ -1514,8 +1557,8 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
     /*
       Initialize BMP raster file header.
     */
-    if (IsRGBColorspace(image->colorspace) == MagickFalse)
-      (void) TransformImageColorspace(image,RGBColorspace,exception);
+    if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
+      (void) TransformImageColorspace(image,sRGBColorspace,exception);
     (void) ResetMagickMemory(&bmp_info,0,sizeof(bmp_info));
     bmp_info.file_size=14+12;
     if (type > 2)
@@ -1541,7 +1584,7 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
         if (image_info->compression == RLECompression)
           bmp_info.bits_per_pixel=8;
         bmp_info.number_colors=1U << bmp_info.bits_per_pixel;
-        if (image->matte != MagickFalse)
+        if (image->alpha_trait == BlendPixelTrait)
           (void) SetImageStorageClass(image,DirectClass,exception);
         else
           if ((size_t) bmp_info.number_colors < image->colors)
@@ -1564,9 +1607,9 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
         */
         bmp_info.number_colors=0;
         bmp_info.bits_per_pixel=(unsigned short)
-          ((type > 3) && (image->matte != MagickFalse) ? 32 : 24);
+          ((type > 3) && (image->alpha_trait == BlendPixelTrait) ? 32 : 24);
         bmp_info.compression=(unsigned int) ((type > 3) &&
-          (image->matte != MagickFalse) ?  BI_BITFIELDS : BI_RGB);
+          (image->alpha_trait == BlendPixelTrait) ?  BI_BITFIELDS : BI_RGB);
       }
     bytes_per_line=4*((image->columns*bmp_info.bits_per_pixel+31)/32);
     bmp_info.ba_offset=0;
@@ -1577,7 +1620,7 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
     if (type == 2)
       bmp_info.size=12;
     else
-      if ((type == 3) || ((image->matte == MagickFalse) &&
+      if ((type == 3) || ((image->alpha_trait != BlendPixelTrait) &&
           (have_color_info == MagickFalse)))
         {
           type=3;
@@ -1599,8 +1642,8 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
           bmp_info.file_size+=extra_size;
           bmp_info.offset_bits+=extra_size;
         }
-    bmp_info.width=(ssize_t) image->columns;
-    bmp_info.height=(ssize_t) image->rows;
+    bmp_info.width=(int) image->columns;
+    bmp_info.height=(int) image->rows;
     bmp_info.planes=1;
     bmp_info.image_size=(unsigned int) (bytes_per_line*image->rows);
     bmp_info.file_size+=bmp_info.image_size;
@@ -1611,14 +1654,14 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
       case UndefinedResolution:
       case PixelsPerInchResolution:
       {
-        bmp_info.x_pixels=(unsigned int) (100.0*image->x_resolution/2.54);
-        bmp_info.y_pixels=(unsigned int) (100.0*image->y_resolution/2.54);
+        bmp_info.x_pixels=(unsigned int) (100.0*image->resolution.x/2.54);
+        bmp_info.y_pixels=(unsigned int) (100.0*image->resolution.y/2.54);
         break;
       }
       case PixelsPerCentimeterResolution:
       {
-        bmp_info.x_pixels=(unsigned int) (100.0*image->x_resolution);
-        bmp_info.y_pixels=(unsigned int) (100.0*image->y_resolution);
+        bmp_info.x_pixels=(unsigned int) (100.0*image->resolution.x);
+        bmp_info.y_pixels=(unsigned int) (100.0*image->resolution.y);
         break;
       }
     }
@@ -1686,10 +1729,12 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
       }
       case 4:
       {
+        ssize_t
+          offset;
+
         size_t
           byte,
-          nibble,
-          offset;
+          nibble;
 
         /*
           Convert PseudoClass image to a BMP monochrome image.
@@ -1863,7 +1908,7 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
             "   Storage class=PseudoClass");
         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
           "   Image depth=%.20g",(double) image->depth);
-        if (image->matte != MagickFalse)
+        if (image->alpha_trait == BlendPixelTrait)
           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
             "   Matte=True");
         else
@@ -1937,7 +1982,7 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
         (void) WriteBlobLSBLong(image,bmp_info.number_colors);
         (void) WriteBlobLSBLong(image,bmp_info.colors_important);
       }
-    if ((type > 3) && ((image->matte != MagickFalse) ||
+    if ((type > 3) && ((image->alpha_trait == BlendPixelTrait) ||
         (have_color_info != MagickFalse)))
       {
         /*
@@ -1947,34 +1992,34 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
         (void) WriteBlobLSBLong(image,0x0000ff00U);  /* Green mask */
         (void) WriteBlobLSBLong(image,0x000000ffU);  /* Blue mask */
         (void) WriteBlobLSBLong(image,0xff000000U);  /* Alpha mask */
-        (void) WriteBlobLSBLong(image,0x00000001U);  /* CSType==Calib. RGB */
+        (void) WriteBlobLSBLong(image,0x73524742U);  /* sRGB */
         (void) WriteBlobLSBLong(image,(unsigned int)
-          image->chromaticity.red_primary.x*0x3ffffff);
+          (image->chromaticity.red_primary.x*0x40000000));
         (void) WriteBlobLSBLong(image,(unsigned int)
-          image->chromaticity.red_primary.y*0x3ffffff);
+          (image->chromaticity.red_primary.y*0x40000000));
         (void) WriteBlobLSBLong(image,(unsigned int)
-          (1.000f-(image->chromaticity.red_primary.x+
-          image->chromaticity.red_primary.y)*0x3ffffff));
+          ((1.000f-(image->chromaticity.red_primary.x+
+          image->chromaticity.red_primary.y))*0x40000000));
         (void) WriteBlobLSBLong(image,(unsigned int)
-          image->chromaticity.green_primary.x*0x3ffffff);
+          (image->chromaticity.green_primary.x*0x40000000));
         (void) WriteBlobLSBLong(image,(unsigned int)
-          image->chromaticity.green_primary.y*0x3ffffff);
+          (image->chromaticity.green_primary.y*0x40000000));
         (void) WriteBlobLSBLong(image,(unsigned int)
-          (1.000f-(image->chromaticity.green_primary.x+
-          image->chromaticity.green_primary.y)*0x3ffffff));
+          ((1.000f-(image->chromaticity.green_primary.x+
+          image->chromaticity.green_primary.y))*0x40000000));
         (void) WriteBlobLSBLong(image,(unsigned int)
-          image->chromaticity.blue_primary.x*0x3ffffff);
+          (image->chromaticity.blue_primary.x*0x40000000));
         (void) WriteBlobLSBLong(image,(unsigned int)
-          image->chromaticity.blue_primary.y*0x3ffffff);
+          (image->chromaticity.blue_primary.y*0x40000000));
         (void) WriteBlobLSBLong(image,(unsigned int)
-          (1.000f-(image->chromaticity.blue_primary.x+
-          image->chromaticity.blue_primary.y)*0x3ffffff));
+          ((1.000f-(image->chromaticity.blue_primary.x+
+          image->chromaticity.blue_primary.y))*0x40000000));
         (void) WriteBlobLSBLong(image,(unsigned int)
-          bmp_info.gamma_scale.x*0xffff);
+          (bmp_info.gamma_scale.x*0x10000));
         (void) WriteBlobLSBLong(image,(unsigned int)
-          bmp_info.gamma_scale.y*0xffff);
+          (bmp_info.gamma_scale.y*0x10000));
         (void) WriteBlobLSBLong(image,(unsigned int)
-          bmp_info.gamma_scale.z*0xffff);
+          (bmp_info.gamma_scale.z*0x10000));
         if ((image->rendering_intent != UndefinedIntent) ||
             (profile != (StringInfo *) NULL))
           {
@@ -2033,9 +2078,9 @@ static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
         q=bmp_colormap;
         for (i=0; i < (ssize_t) MagickMin((ssize_t) image->colors,(ssize_t) bmp_info.number_colors); i++)
         {
-          *q++=ScaleQuantumToChar(image->colormap[i].blue);
-          *q++=ScaleQuantumToChar(image->colormap[i].green);
-          *q++=ScaleQuantumToChar(image->colormap[i].red);
+          *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].blue));
+          *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].green));
+          *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].red));
           if (type > 2)
             *q++=(unsigned char) 0x0;
         }