Home | History | Annotate | Download | only in coders
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %                            BBBB   M   M  PPPP                               %
      7 %                            B   B  MM MM  P   P                              %
      8 %                            BBBB   M M M  PPPP                               %
      9 %                            B   B  M   M  P                                  %
     10 %                            BBBB   M   M  P                                  %
     11 %                                                                             %
     12 %                                                                             %
     13 %             Read/Write Microsoft Windows Bitmap Image Format                %
     14 %                                                                             %
     15 %                              Software Design                                %
     16 %                                   Cristy                                    %
     17 %                            Glenn Randers-Pehrson                            %
     18 %                               December 2001                                 %
     19 %                                                                             %
     20 %                                                                             %
     21 %  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
     22 %  dedicated to making software imaging solutions freely available.           %
     23 %                                                                             %
     24 %  You may not use this file except in compliance with the License.  You may  %
     25 %  obtain a copy of the License at                                            %
     26 %                                                                             %
     27 %    http://www.imagemagick.org/script/license.php                            %
     28 %                                                                             %
     29 %  Unless required by applicable law or agreed to in writing, software        %
     30 %  distributed under the License is distributed on an "AS IS" BASIS,          %
     31 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
     32 %  See the License for the specific language governing permissions and        %
     33 %  limitations under the License.                                             %
     34 %                                                                             %
     35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     36 %
     37 %
     38 */
     39 
     40 /*
     42   Include declarations.
     43 */
     44 #include "MagickCore/studio.h"
     45 #include "MagickCore/blob.h"
     46 #include "MagickCore/blob-private.h"
     47 #include "MagickCore/cache.h"
     48 #include "MagickCore/colormap-private.h"
     49 #include "MagickCore/color-private.h"
     50 #include "MagickCore/colormap.h"
     51 #include "MagickCore/colorspace.h"
     52 #include "MagickCore/colorspace-private.h"
     53 #include "MagickCore/exception.h"
     54 #include "MagickCore/exception-private.h"
     55 #include "MagickCore/image.h"
     56 #include "MagickCore/image-private.h"
     57 #include "MagickCore/list.h"
     58 #include "MagickCore/log.h"
     59 #include "MagickCore/magick.h"
     60 #include "MagickCore/memory_.h"
     61 #include "MagickCore/monitor.h"
     62 #include "MagickCore/monitor-private.h"
     63 #include "MagickCore/option.h"
     64 #include "MagickCore/pixel-accessor.h"
     65 #include "MagickCore/profile.h"
     66 #include "MagickCore/quantum-private.h"
     67 #include "MagickCore/static.h"
     68 #include "MagickCore/string_.h"
     69 #include "MagickCore/module.h"
     70 #include "MagickCore/transform.h"
     71 
     72 /*
     74   Macro definitions (from Windows wingdi.h).
     75 */
     76 #undef BI_JPEG
     77 #define BI_JPEG  4
     78 #undef BI_PNG
     79 #define BI_PNG  5
     80 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__MINGW32__) || defined(__MINGW64__)
     81 #undef BI_RGB
     82 #define BI_RGB  0
     83 #undef BI_RLE8
     84 #define BI_RLE8  1
     85 #undef BI_RLE4
     86 #define BI_RLE4  2
     87 #undef BI_BITFIELDS
     88 #define BI_BITFIELDS  3
     89 
     90 #undef LCS_CALIBRATED_RBG
     91 #define LCS_CALIBRATED_RBG  0
     92 #undef LCS_sRGB
     93 #define LCS_sRGB  1
     94 #undef LCS_WINDOWS_COLOR_SPACE
     95 #define LCS_WINDOWS_COLOR_SPACE  2
     96 #undef PROFILE_LINKED
     97 #define PROFILE_LINKED  3
     98 #undef PROFILE_EMBEDDED
     99 #define PROFILE_EMBEDDED  4
    100 
    101 #undef LCS_GM_BUSINESS
    102 #define LCS_GM_BUSINESS  1  /* Saturation */
    103 #undef LCS_GM_GRAPHICS
    104 #define LCS_GM_GRAPHICS  2  /* Relative */
    105 #undef LCS_GM_IMAGES
    106 #define LCS_GM_IMAGES  4  /* Perceptual */
    107 #undef LCS_GM_ABS_COLORIMETRIC
    108 #define LCS_GM_ABS_COLORIMETRIC  8  /* Absolute */
    109 #endif
    110 
    111 /*
    113   Typedef declarations.
    114 */
    115 typedef struct _BMPInfo
    116 {
    117   unsigned long
    118     file_size,
    119     ba_offset,
    120     offset_bits,
    121     size;
    122 
    123   ssize_t
    124     width,
    125     height;
    126 
    127   unsigned short
    128     planes,
    129     bits_per_pixel;
    130 
    131   unsigned long
    132     compression,
    133     image_size,
    134     x_pixels,
    135     y_pixels,
    136     number_colors,
    137     red_mask,
    138     green_mask,
    139     blue_mask,
    140     alpha_mask,
    141     colors_important;
    142 
    143   long
    144     colorspace;
    145 
    146   PrimaryInfo
    147     red_primary,
    148     green_primary,
    149     blue_primary,
    150     gamma_scale;
    151 } BMPInfo;
    152 
    153 /*
    155   Forward declarations.
    156 */
    157 static MagickBooleanType
    158   WriteBMPImage(const ImageInfo *,Image *,ExceptionInfo *);
    159 
    160 /*
    162 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    163 %                                                                             %
    164 %                                                                             %
    165 %                                                                             %
    166 %   D e c o d e I m a g e                                                     %
    167 %                                                                             %
    168 %                                                                             %
    169 %                                                                             %
    170 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    171 %
    172 %  DecodeImage unpacks the packed image pixels into runlength-encoded
    173 %  pixel packets.
    174 %
    175 %  The format of the DecodeImage method is:
    176 %
    177 %      MagickBooleanType DecodeImage(Image *image,
    178 %        const size_t compression,unsigned char *pixels)
    179 %
    180 %  A description of each parameter follows:
    181 %
    182 %    o image: the address of a structure of type Image.
    183 %
    184 %    o compression:  Zero means uncompressed.  A value of 1 means the
    185 %      compressed pixels are runlength encoded for a 256-color bitmap.
    186 %      A value of 2 means a 16-color bitmap.  A value of 3 means bitfields
    187 %      encoding.
    188 %
    189 %    o pixels:  The address of a byte (8 bits) array of pixel data created by
    190 %      the decoding process.
    191 %
    192 */
    193 static MagickBooleanType DecodeImage(Image *image,const size_t compression,
    194   unsigned char *pixels)
    195 {
    196   int
    197     count;
    198 
    199   register ssize_t
    200     i,
    201     x;
    202 
    203   register unsigned char
    204     *p,
    205     *q;
    206 
    207   ssize_t
    208     y;
    209 
    210   unsigned char
    211     byte;
    212 
    213   assert(image != (Image *) NULL);
    214   assert(image->signature == MagickCoreSignature);
    215   if (image->debug != MagickFalse)
    216     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    217   assert(pixels != (unsigned char *) NULL);
    218   (void) ResetMagickMemory(pixels,0,(size_t) image->columns*image->rows*
    219     sizeof(*pixels));
    220   byte=0;
    221   x=0;
    222   p=pixels;
    223   q=pixels+(size_t) image->columns*image->rows;
    224   for (y=0; y < (ssize_t) image->rows; )
    225   {
    226     MagickBooleanType
    227       status;
    228 
    229     if ((p < pixels) || (p > q))
    230       break;
    231     count=ReadBlobByte(image);
    232     if (count == EOF)
    233       break;
    234     if (count != 0)
    235       {
    236         /*
    237           Encoded mode.
    238         */
    239         count=(int) MagickMin((ssize_t) count,(ssize_t) (q-p));
    240         byte=(unsigned char) ReadBlobByte(image);
    241         if (compression == BI_RLE8)
    242           {
    243             for (i=0; i < (ssize_t) count; i++)
    244               *p++=(unsigned char) byte;
    245           }
    246         else
    247           {
    248             for (i=0; i < (ssize_t) count; i++)
    249               *p++=(unsigned char)
    250                 ((i & 0x01) != 0 ? (byte & 0x0f) : ((byte >> 4) & 0x0f));
    251           }
    252         x+=count;
    253       }
    254     else
    255       {
    256         /*
    257           Escape mode.
    258         */
    259         count=ReadBlobByte(image);
    260         if (count == EOF)
    261           break;
    262         if (count == 0x01)
    263           return(MagickTrue);
    264         switch (count)
    265         {
    266           case 0x00:
    267           {
    268             /*
    269               End of line.
    270             */
    271             x=0;
    272             y++;
    273             p=pixels+y*image->columns;
    274             break;
    275           }
    276           case 0x02:
    277           {
    278             /*
    279               Delta mode.
    280             */
    281             x+=ReadBlobByte(image);
    282             y+=ReadBlobByte(image);
    283             p=pixels+y*image->columns+x;
    284             break;
    285           }
    286           default:
    287           {
    288             /*
    289               Absolute mode.
    290             */
    291             count=(int) MagickMin((ssize_t) count,(ssize_t) (q-p));
    292             if (compression == BI_RLE8)
    293               for (i=0; i < (ssize_t) count; i++)
    294                 *p++=(unsigned char) ReadBlobByte(image);
    295             else
    296               for (i=0; i < (ssize_t) count; i++)
    297               {
    298                 if ((i & 0x01) == 0)
    299                   byte=(unsigned char) ReadBlobByte(image);
    300                 *p++=(unsigned char)
    301                   ((i & 0x01) != 0 ? (byte & 0x0f) : ((byte >> 4) & 0x0f));
    302               }
    303             x+=count;
    304             /*
    305               Read pad byte.
    306             */
    307             if (compression == BI_RLE8)
    308               {
    309                 if ((count & 0x01) != 0)
    310                   (void) ReadBlobByte(image);
    311               }
    312             else
    313               if (((count & 0x03) == 1) || ((count & 0x03) == 2))
    314                 (void) ReadBlobByte(image);
    315             break;
    316           }
    317         }
    318       }
    319     status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
    320       image->rows);
    321     if (status == MagickFalse)
    322       break;
    323   }
    324   (void) ReadBlobByte(image);  /* end of line */
    325   (void) ReadBlobByte(image);
    326   return(y < (ssize_t) image->rows ? MagickFalse : MagickTrue);
    327 }
    328 
    329 /*
    331 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    332 %                                                                             %
    333 %                                                                             %
    334 %                                                                             %
    335 %   E n c o d e I m a g e                                                     %
    336 %                                                                             %
    337 %                                                                             %
    338 %                                                                             %
    339 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    340 %
    341 %  EncodeImage compresses pixels using a runlength encoded format.
    342 %
    343 %  The format of the EncodeImage method is:
    344 %
    345 %    static MagickBooleanType EncodeImage(Image *image,
    346 %      const size_t bytes_per_line,const unsigned char *pixels,
    347 %      unsigned char *compressed_pixels)
    348 %
    349 %  A description of each parameter follows:
    350 %
    351 %    o image:  The image.
    352 %
    353 %    o bytes_per_line: the number of bytes in a scanline of compressed pixels
    354 %
    355 %    o pixels:  The address of a byte (8 bits) array of pixel data created by
    356 %      the compression process.
    357 %
    358 %    o compressed_pixels:  The address of a byte (8 bits) array of compressed
    359 %      pixel data.
    360 %
    361 */
    362 static size_t EncodeImage(Image *image,const size_t bytes_per_line,
    363   const unsigned char *pixels,unsigned char *compressed_pixels)
    364 {
    365   MagickBooleanType
    366     status;
    367 
    368   register const unsigned char
    369     *p;
    370 
    371   register ssize_t
    372     i,
    373     x;
    374 
    375   register unsigned char
    376     *q;
    377 
    378   ssize_t
    379     y;
    380 
    381   /*
    382     Runlength encode pixels.
    383   */
    384   assert(image != (Image *) NULL);
    385   assert(image->signature == MagickCoreSignature);
    386   if (image->debug != MagickFalse)
    387     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    388   assert(pixels != (const unsigned char *) NULL);
    389   assert(compressed_pixels != (unsigned char *) NULL);
    390   p=pixels;
    391   q=compressed_pixels;
    392   i=0;
    393   for (y=0; y < (ssize_t) image->rows; y++)
    394   {
    395     for (x=0; x < (ssize_t) bytes_per_line; x+=i)
    396     {
    397       /*
    398         Determine runlength.
    399       */
    400       for (i=1; ((x+i) < (ssize_t) bytes_per_line); i++)
    401         if ((i == 255) || (*(p+i) != *p))
    402           break;
    403       *q++=(unsigned char) i;
    404       *q++=(*p);
    405       p+=i;
    406     }
    407     /*
    408       End of line.
    409     */
    410     *q++=(unsigned char) 0x00;
    411     *q++=(unsigned char) 0x00;
    412     status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
    413       image->rows);
    414     if (status == MagickFalse)
    415       break;
    416   }
    417   /*
    418     End of bitmap.
    419   */
    420   *q++=(unsigned char) 0x00;
    421   *q++=(unsigned char) 0x01;
    422   return((size_t) (q-compressed_pixels));
    423 }
    424 
    425 /*
    427 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    428 %                                                                             %
    429 %                                                                             %
    430 %                                                                             %
    431 %   I s B M P                                                                 %
    432 %                                                                             %
    433 %                                                                             %
    434 %                                                                             %
    435 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    436 %
    437 %  IsBMP() returns MagickTrue if the image format type, identified by the
    438 %  magick string, is BMP.
    439 %
    440 %  The format of the IsBMP method is:
    441 %
    442 %      MagickBooleanType IsBMP(const unsigned char *magick,const size_t length)
    443 %
    444 %  A description of each parameter follows:
    445 %
    446 %    o magick: compare image format pattern against these bytes.
    447 %
    448 %    o length: Specifies the length of the magick string.
    449 %
    450 */
    451 static MagickBooleanType IsBMP(const unsigned char *magick,const size_t length)
    452 {
    453   if (length < 2)
    454     return(MagickFalse);
    455   if ((LocaleNCompare((char *) magick,"BA",2) == 0) ||
    456       (LocaleNCompare((char *) magick,"BM",2) == 0) ||
    457       (LocaleNCompare((char *) magick,"IC",2) == 0) ||
    458       (LocaleNCompare((char *) magick,"PI",2) == 0) ||
    459       (LocaleNCompare((char *) magick,"CI",2) == 0) ||
    460       (LocaleNCompare((char *) magick,"CP",2) == 0))
    461     return(MagickTrue);
    462   return(MagickFalse);
    463 }
    464 
    465 /*
    467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    468 %                                                                             %
    469 %                                                                             %
    470 %                                                                             %
    471 %   R e a d B M P I m a g e                                                   %
    472 %                                                                             %
    473 %                                                                             %
    474 %                                                                             %
    475 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    476 %
    477 %  ReadBMPImage() reads a Microsoft Windows bitmap image file, Version
    478 %  2, 3 (for Windows or NT), or 4, and  returns it.  It allocates the memory
    479 %  necessary for the new Image structure and returns a pointer to the new
    480 %  image.
    481 %
    482 %  The format of the ReadBMPImage method is:
    483 %
    484 %      image=ReadBMPImage(image_info)
    485 %
    486 %  A description of each parameter follows:
    487 %
    488 %    o image_info: the image info.
    489 %
    490 %    o exception: return any errors or warnings in this structure.
    491 %
    492 */
    493 
    494 static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
    495 {
    496   BMPInfo
    497     bmp_info;
    498 
    499   Image
    500     *image;
    501 
    502   MagickBooleanType
    503     status;
    504 
    505   MagickOffsetType
    506     offset,
    507     start_position;
    508 
    509   MemoryInfo
    510     *pixel_info;
    511 
    512   Quantum
    513     index;
    514 
    515   register Quantum
    516     *q;
    517 
    518   register ssize_t
    519     i,
    520     x;
    521 
    522   register unsigned char
    523     *p;
    524 
    525   size_t
    526     bit,
    527     blue,
    528     bytes_per_line,
    529     green,
    530     length,
    531     red;
    532 
    533   ssize_t
    534     count,
    535     y;
    536 
    537   unsigned char
    538     magick[12],
    539     *pixels;
    540 
    541   /*
    542     Open image file.
    543   */
    544   assert(image_info != (const ImageInfo *) NULL);
    545   assert(image_info->signature == MagickCoreSignature);
    546   if (image_info->debug != MagickFalse)
    547     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
    548       image_info->filename);
    549   assert(exception != (ExceptionInfo *) NULL);
    550   assert(exception->signature == MagickCoreSignature);
    551   image=AcquireImage(image_info,exception);
    552   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
    553   if (status == MagickFalse)
    554     {
    555       image=DestroyImageList(image);
    556       return((Image *) NULL);
    557     }
    558   /*
    559     Determine if this a BMP file.
    560   */
    561   (void) ResetMagickMemory(&bmp_info,0,sizeof(bmp_info));
    562   bmp_info.ba_offset=0;
    563   start_position=0;
    564   count=ReadBlob(image,2,magick);
    565   if (count != 2)
    566     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    567   do
    568   {
    569     PixelInfo
    570       quantum_bits;
    571 
    572     PixelPacket
    573       shift;
    574 
    575     size_t
    576       profile_data,
    577       profile_size;
    578 
    579     /*
    580       Verify BMP identifier.
    581     */
    582     if (bmp_info.ba_offset == 0)
    583       start_position=TellBlob(image)-2;
    584     bmp_info.ba_offset=0;
    585     while (LocaleNCompare((char *) magick,"BA",2) == 0)
    586     {
    587       bmp_info.file_size=ReadBlobLSBLong(image);
    588       bmp_info.ba_offset=ReadBlobLSBLong(image);
    589       bmp_info.offset_bits=ReadBlobLSBLong(image);
    590       count=ReadBlob(image,2,magick);
    591       if (count != 2)
    592         break;
    593     }
    594     if (image->debug != MagickFalse)
    595       (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Magick: %c%c",
    596         magick[0],magick[1]);
    597     if ((count != 2) || ((LocaleNCompare((char *) magick,"BM",2) != 0) &&
    598         (LocaleNCompare((char *) magick,"CI",2) != 0)))
    599       ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    600     bmp_info.file_size=ReadBlobLSBLong(image);
    601     (void) ReadBlobLSBLong(image);
    602     bmp_info.offset_bits=ReadBlobLSBLong(image);
    603     bmp_info.size=ReadBlobLSBLong(image);
    604     if (image->debug != MagickFalse)
    605       (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  BMP size: %lu",
    606         bmp_info.size);
    607     if (bmp_info.size == 12)
    608       {
    609         /*
    610           OS/2 BMP image file.
    611         */
    612         (void) CopyMagickString(image->magick,"BMP2",MagickPathExtent);
    613         bmp_info.width=(ssize_t) ((short) ReadBlobLSBShort(image));
    614         bmp_info.height=(ssize_t) ((short) ReadBlobLSBShort(image));
    615         bmp_info.planes=ReadBlobLSBShort(image);
    616         bmp_info.bits_per_pixel=ReadBlobLSBShort(image);
    617         bmp_info.x_pixels=0;
    618         bmp_info.y_pixels=0;
    619         bmp_info.number_colors=0;
    620         bmp_info.compression=BI_RGB;
    621         bmp_info.image_size=0;
    622         bmp_info.alpha_mask=0;
    623         if (image->debug != MagickFalse)
    624           {
    625             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    626               "  Format: OS/2 Bitmap");
    627             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    628               "  Geometry: %.20gx%.20g",(double) bmp_info.width,(double)
    629               bmp_info.height);
    630           }
    631       }
    632     else
    633       {
    634         /*
    635           Microsoft Windows BMP image file.
    636         */
    637         if (bmp_info.size < 40)
    638           ThrowReaderException(CorruptImageError,"NonOS2HeaderSizeError");
    639         bmp_info.width=(ssize_t) ReadBlobLSBSignedLong(image);
    640         bmp_info.height=(ssize_t) ReadBlobLSBSignedLong(image);
    641         bmp_info.planes=ReadBlobLSBShort(image);
    642         bmp_info.bits_per_pixel=ReadBlobLSBShort(image);
    643         bmp_info.compression=ReadBlobLSBLong(image);
    644         bmp_info.image_size=ReadBlobLSBLong(image);
    645         bmp_info.x_pixels=ReadBlobLSBLong(image);
    646         bmp_info.y_pixels=ReadBlobLSBLong(image);
    647         bmp_info.number_colors=ReadBlobLSBLong(image);
    648         bmp_info.colors_important=ReadBlobLSBLong(image);
    649         profile_data=0;
    650         profile_size=0;
    651         if (image->debug != MagickFalse)
    652           {
    653             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    654               "  Format: MS Windows bitmap");
    655             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    656               "  Geometry: %.20gx%.20g",(double) bmp_info.width,(double)
    657               bmp_info.height);
    658             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    659               "  Bits per pixel: %.20g",(double) bmp_info.bits_per_pixel);
    660             switch ((int) bmp_info.compression)
    661             {
    662               case BI_RGB:
    663               {
    664                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    665                   "  Compression: BI_RGB");
    666                 break;
    667               }
    668               case BI_RLE4:
    669               {
    670                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    671                   "  Compression: BI_RLE4");
    672                 break;
    673               }
    674               case BI_RLE8:
    675               {
    676                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    677                   "  Compression: BI_RLE8");
    678                 break;
    679               }
    680               case BI_BITFIELDS:
    681               {
    682                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    683                   "  Compression: BI_BITFIELDS");
    684                 break;
    685               }
    686               case BI_PNG:
    687               {
    688                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    689                   "  Compression: BI_PNG");
    690                 break;
    691               }
    692               case BI_JPEG:
    693               {
    694                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    695                   "  Compression: BI_JPEG");
    696                 break;
    697               }
    698               default:
    699               {
    700                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    701                   "  Compression: UNKNOWN (%lu)",bmp_info.compression);
    702               }
    703             }
    704             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    705               "  Number of colors: %lu",bmp_info.number_colors);
    706           }
    707         bmp_info.red_mask=ReadBlobLSBLong(image);
    708         bmp_info.green_mask=ReadBlobLSBLong(image);
    709         bmp_info.blue_mask=ReadBlobLSBLong(image);
    710         if (bmp_info.size > 40)
    711           {
    712             double
    713               gamma;
    714 
    715             /*
    716               Read color management information.
    717             */
    718             bmp_info.alpha_mask=ReadBlobLSBLong(image);
    719             bmp_info.colorspace=ReadBlobLSBSignedLong(image);
    720             /*
    721               Decode 2^30 fixed point formatted CIE primaries.
    722             */
    723 #           define BMP_DENOM ((double) 0x40000000)
    724             bmp_info.red_primary.x=(double) ReadBlobLSBLong(image)/BMP_DENOM;
    725             bmp_info.red_primary.y=(double) ReadBlobLSBLong(image)/BMP_DENOM;
    726             bmp_info.red_primary.z=(double) ReadBlobLSBLong(image)/BMP_DENOM;
    727             bmp_info.green_primary.x=(double) ReadBlobLSBLong(image)/BMP_DENOM;
    728             bmp_info.green_primary.y=(double) ReadBlobLSBLong(image)/BMP_DENOM;
    729             bmp_info.green_primary.z=(double) ReadBlobLSBLong(image)/BMP_DENOM;
    730             bmp_info.blue_primary.x=(double) ReadBlobLSBLong(image)/BMP_DENOM;
    731             bmp_info.blue_primary.y=(double) ReadBlobLSBLong(image)/BMP_DENOM;
    732             bmp_info.blue_primary.z=(double) ReadBlobLSBLong(image)/BMP_DENOM;
    733 
    734             gamma=bmp_info.red_primary.x+bmp_info.red_primary.y+
    735               bmp_info.red_primary.z;
    736             gamma=PerceptibleReciprocal(gamma);
    737             bmp_info.red_primary.x*=gamma;
    738             bmp_info.red_primary.y*=gamma;
    739             image->chromaticity.red_primary.x=bmp_info.red_primary.x;
    740             image->chromaticity.red_primary.y=bmp_info.red_primary.y;
    741 
    742             gamma=bmp_info.green_primary.x+bmp_info.green_primary.y+
    743               bmp_info.green_primary.z;
    744             gamma=PerceptibleReciprocal(gamma);
    745             bmp_info.green_primary.x*=gamma;
    746             bmp_info.green_primary.y*=gamma;
    747             image->chromaticity.green_primary.x=bmp_info.green_primary.x;
    748             image->chromaticity.green_primary.y=bmp_info.green_primary.y;
    749 
    750             gamma=bmp_info.blue_primary.x+bmp_info.blue_primary.y+
    751               bmp_info.blue_primary.z;
    752             gamma=PerceptibleReciprocal(gamma);
    753             bmp_info.blue_primary.x*=gamma;
    754             bmp_info.blue_primary.y*=gamma;
    755             image->chromaticity.blue_primary.x=bmp_info.blue_primary.x;
    756             image->chromaticity.blue_primary.y=bmp_info.blue_primary.y;
    757 
    758             /*
    759               Decode 16^16 fixed point formatted gamma_scales.
    760             */
    761             bmp_info.gamma_scale.x=(double) ReadBlobLSBLong(image)/0x10000;
    762             bmp_info.gamma_scale.y=(double) ReadBlobLSBLong(image)/0x10000;
    763             bmp_info.gamma_scale.z=(double) ReadBlobLSBLong(image)/0x10000;
    764             /*
    765               Compute a single gamma from the BMP 3-channel gamma.
    766             */
    767             image->gamma=(bmp_info.gamma_scale.x+bmp_info.gamma_scale.y+
    768               bmp_info.gamma_scale.z)/3.0;
    769           }
    770         else
    771           (void) CopyMagickString(image->magick,"BMP3",MagickPathExtent);
    772 
    773         if (bmp_info.size > 108)
    774           {
    775             size_t
    776               intent;
    777 
    778             /*
    779               Read BMP Version 5 color management information.
    780             */
    781             intent=ReadBlobLSBLong(image);
    782             switch ((int) intent)
    783             {
    784               case LCS_GM_BUSINESS:
    785               {
    786                 image->rendering_intent=SaturationIntent;
    787                 break;
    788               }
    789               case LCS_GM_GRAPHICS:
    790               {
    791                 image->rendering_intent=RelativeIntent;
    792                 break;
    793               }
    794               case LCS_GM_IMAGES:
    795               {
    796                 image->rendering_intent=PerceptualIntent;
    797                 break;
    798               }
    799               case LCS_GM_ABS_COLORIMETRIC:
    800               {
    801                 image->rendering_intent=AbsoluteIntent;
    802                 break;
    803               }
    804             }
    805             profile_data=ReadBlobLSBLong(image);
    806             profile_size=ReadBlobLSBLong(image);
    807             (void) profile_data;
    808             (void) profile_size;
    809             (void) ReadBlobLSBLong(image);  /* Reserved byte */
    810           }
    811       }
    812     if ((MagickSizeType) bmp_info.file_size > GetBlobSize(image))
    813       (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError,
    814         "LengthAndFilesizeDoNotMatch","`%s'",image->filename);
    815     else
    816       if ((MagickSizeType) bmp_info.file_size < GetBlobSize(image))
    817         (void) ThrowMagickException(exception,GetMagickModule(),
    818           CorruptImageWarning,"LengthAndFilesizeDoNotMatch","`%s'",
    819           image->filename);
    820     if (bmp_info.width <= 0)
    821       ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
    822     if (bmp_info.height == 0)
    823       ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
    824     if (bmp_info.planes != 1)
    825       ThrowReaderException(CorruptImageError,"StaticPlanesValueNotEqualToOne");
    826     if ((bmp_info.bits_per_pixel != 1) && (bmp_info.bits_per_pixel != 4) &&
    827         (bmp_info.bits_per_pixel != 8) && (bmp_info.bits_per_pixel != 16) &&
    828         (bmp_info.bits_per_pixel != 24) && (bmp_info.bits_per_pixel != 32))
    829       ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
    830     if (bmp_info.bits_per_pixel < 16 &&
    831         bmp_info.number_colors > (1U << bmp_info.bits_per_pixel))
    832       ThrowReaderException(CorruptImageError,"UnrecognizedNumberOfColors");
    833     if ((bmp_info.compression == 1) && (bmp_info.bits_per_pixel != 8))
    834       ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
    835     if ((bmp_info.compression == 2) && (bmp_info.bits_per_pixel != 4))
    836       ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
    837     if ((bmp_info.compression == 3) && (bmp_info.bits_per_pixel < 16))
    838       ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
    839     switch (bmp_info.compression)
    840     {
    841       case BI_RGB:
    842         image->compression=NoCompression;
    843         break;
    844       case BI_RLE8:
    845       case BI_RLE4:
    846         image->compression=RLECompression;
    847         break;
    848       case BI_BITFIELDS:
    849         break;
    850       case BI_JPEG:
    851         ThrowReaderException(CoderError,"JPEGCompressNotSupported");
    852       case BI_PNG:
    853         ThrowReaderException(CoderError,"PNGCompressNotSupported");
    854       default:
    855         ThrowReaderException(CorruptImageError,"UnrecognizedImageCompression");
    856     }
    857     image->columns=(size_t) MagickAbsoluteValue(bmp_info.width);
    858     image->rows=(size_t) MagickAbsoluteValue(bmp_info.height);
    859     image->depth=bmp_info.bits_per_pixel <= 8 ? bmp_info.bits_per_pixel : 8;
    860     image->alpha_trait=((bmp_info.alpha_mask != 0) &&
    861       (bmp_info.compression == BI_BITFIELDS)) ? BlendPixelTrait :
    862       UndefinedPixelTrait;
    863     if (bmp_info.bits_per_pixel < 16)
    864       {
    865         size_t
    866           one;
    867 
    868         image->storage_class=PseudoClass;
    869         image->colors=bmp_info.number_colors;
    870         one=1;
    871         if (image->colors == 0)
    872           image->colors=one << bmp_info.bits_per_pixel;
    873       }
    874     if (image->storage_class == PseudoClass)
    875       {
    876         unsigned char
    877           *bmp_colormap;
    878 
    879         size_t
    880           packet_size;
    881 
    882         /*
    883           Read BMP raster colormap.
    884         */
    885         if (image->debug != MagickFalse)
    886           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    887             "  Reading colormap of %.20g colors",(double) image->colors);
    888         if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
    889           ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    890         bmp_colormap=(unsigned char *) AcquireQuantumMemory((size_t)
    891           image->colors,4*sizeof(*bmp_colormap));
    892         if (bmp_colormap == (unsigned char *) NULL)
    893           ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    894         if ((bmp_info.size == 12) || (bmp_info.size == 64))
    895           packet_size=3;
    896         else
    897           packet_size=4;
    898         offset=SeekBlob(image,start_position+14+bmp_info.size,SEEK_SET);
    899         if (offset < 0)
    900           ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    901         count=ReadBlob(image,packet_size*image->colors,bmp_colormap);
    902         if (count != (ssize_t) (packet_size*image->colors))
    903           ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
    904         p=bmp_colormap;
    905         for (i=0; i < (ssize_t) image->colors; i++)
    906         {
    907           image->colormap[i].blue=(MagickRealType) ScaleCharToQuantum(*p++);
    908           image->colormap[i].green=(MagickRealType) ScaleCharToQuantum(*p++);
    909           image->colormap[i].red=(MagickRealType) ScaleCharToQuantum(*p++);
    910           if (packet_size == 4)
    911             p++;
    912         }
    913         bmp_colormap=(unsigned char *) RelinquishMagickMemory(bmp_colormap);
    914       }
    915     image->resolution.x=(double) bmp_info.x_pixels/100.0;
    916     image->resolution.y=(double) bmp_info.y_pixels/100.0;
    917     image->units=PixelsPerCentimeterResolution;
    918     if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
    919       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
    920         break;
    921     status=SetImageExtent(image,image->columns,image->rows,exception);
    922     if (status == MagickFalse)
    923       return(DestroyImageList(image));
    924     /*
    925       Read image data.
    926     */
    927     offset=SeekBlob(image,start_position+bmp_info.offset_bits,SEEK_SET);
    928     if (offset < 0)
    929       ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    930     if (bmp_info.compression == BI_RLE4)
    931       bmp_info.bits_per_pixel<<=1;
    932     bytes_per_line=4*((image->columns*bmp_info.bits_per_pixel+31)/32);
    933     length=(size_t) bytes_per_line*image->rows;
    934     pixel_info=AcquireVirtualMemory((size_t) image->rows,
    935       MagickMax(bytes_per_line,image->columns+256UL)*sizeof(*pixels));
    936     if (pixel_info == (MemoryInfo *) NULL)
    937       ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    938     pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
    939     if ((bmp_info.compression == BI_RGB) ||
    940         (bmp_info.compression == BI_BITFIELDS))
    941       {
    942         if (image->debug != MagickFalse)
    943           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    944             "  Reading pixels (%.20g bytes)",(double) length);
    945         count=ReadBlob(image,length,pixels);
    946         if (count != (ssize_t) length)
    947           {
    948             pixel_info=RelinquishVirtualMemory(pixel_info);
    949             ThrowReaderException(CorruptImageError,
    950               "InsufficientImageDataInFile");
    951           }
    952       }
    953     else
    954       {
    955         /*
    956           Convert run-length encoded raster pixels.
    957         */
    958         status=DecodeImage(image,bmp_info.compression,pixels);
    959         if (status == MagickFalse)
    960           {
    961             pixel_info=RelinquishVirtualMemory(pixel_info);
    962             ThrowReaderException(CorruptImageError,
    963               "UnableToRunlengthDecodeImage");
    964           }
    965       }
    966     /*
    967       Convert BMP raster image to pixel packets.
    968     */
    969     if (bmp_info.compression == BI_RGB)
    970       {
    971         /*
    972           We should ignore the alpha value in BMP3 files but there have been
    973           reports about 32 bit files with alpha. We do a quick check to see if
    974           the alpha channel contains a value that is not zero (default value).
    975           If we find a non zero value we asume the program that wrote the file
    976           wants to use the alpha channel.
    977         */
    978         if ((image->alpha_trait == UndefinedPixelTrait) && (bmp_info.size == 40) &&
    979             (bmp_info.bits_per_pixel == 32))
    980           {
    981             bytes_per_line=4*(image->columns);
    982             for (y=(ssize_t) image->rows-1; y >= 0; y--)
    983             {
    984               p=pixels+(image->rows-y-1)*bytes_per_line;
    985               for (x=0; x < (ssize_t) image->columns; x++)
    986               {
    987                 if (*(p+3) != 0)
    988                   {
    989                     image->alpha_trait=BlendPixelTrait;
    990                     y=-1;
    991                     break;
    992                   }
    993                 p+=4;
    994               }
    995             }
    996           }
    997         bmp_info.alpha_mask=image->alpha_trait != UndefinedPixelTrait ?
    998           0xff000000U : 0U;
    999         bmp_info.red_mask=0x00ff0000U;
   1000         bmp_info.green_mask=0x0000ff00U;
   1001         bmp_info.blue_mask=0x000000ffU;
   1002         if (bmp_info.bits_per_pixel == 16)
   1003           {
   1004             /*
   1005               RGB555.
   1006             */
   1007             bmp_info.red_mask=0x00007c00U;
   1008             bmp_info.green_mask=0x000003e0U;
   1009             bmp_info.blue_mask=0x0000001fU;
   1010           }
   1011       }
   1012     (void) ResetMagickMemory(&shift,0,sizeof(shift));
   1013     (void) ResetMagickMemory(&quantum_bits,0,sizeof(quantum_bits));
   1014     if ((bmp_info.bits_per_pixel == 16) || (bmp_info.bits_per_pixel == 32))
   1015       {
   1016         register size_t
   1017           sample;
   1018 
   1019         /*
   1020           Get shift and quantum bits info from bitfield masks.
   1021         */
   1022         if (bmp_info.red_mask != 0)
   1023           while (((bmp_info.red_mask << shift.red) & 0x80000000UL) == 0)
   1024             shift.red++;
   1025         if (bmp_info.green_mask != 0)
   1026           while (((bmp_info.green_mask << shift.green) & 0x80000000UL) == 0)
   1027             shift.green++;
   1028         if (bmp_info.blue_mask != 0)
   1029           while (((bmp_info.blue_mask << shift.blue) & 0x80000000UL) == 0)
   1030             shift.blue++;
   1031         if (bmp_info.alpha_mask != 0)
   1032           while (((bmp_info.alpha_mask << shift.alpha) & 0x80000000UL) == 0)
   1033             shift.alpha++;
   1034         sample=shift.red;
   1035         while (((bmp_info.red_mask << sample) & 0x80000000UL) != 0)
   1036           sample++;
   1037         quantum_bits.red=(MagickRealType) (sample-shift.red);
   1038         sample=shift.green;
   1039         while (((bmp_info.green_mask << sample) & 0x80000000UL) != 0)
   1040           sample++;
   1041         quantum_bits.green=(MagickRealType) (sample-shift.green);
   1042         sample=shift.blue;
   1043         while (((bmp_info.blue_mask << sample) & 0x80000000UL) != 0)
   1044           sample++;
   1045         quantum_bits.blue=(MagickRealType) (sample-shift.blue);
   1046         sample=shift.alpha;
   1047         while (((bmp_info.alpha_mask << sample) & 0x80000000UL) != 0)
   1048           sample++;
   1049         quantum_bits.alpha=(MagickRealType) (sample-shift.alpha);
   1050       }
   1051     switch (bmp_info.bits_per_pixel)
   1052     {
   1053       case 1:
   1054       {
   1055         /*
   1056           Convert bitmap scanline.
   1057         */
   1058         for (y=(ssize_t) image->rows-1; y >= 0; y--)
   1059         {
   1060           p=pixels+(image->rows-y-1)*bytes_per_line;
   1061           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
   1062           if (q == (Quantum *) NULL)
   1063             break;
   1064           for (x=0; x < ((ssize_t) image->columns-7); x+=8)
   1065           {
   1066             for (bit=0; bit < 8; bit++)
   1067             {
   1068               index=(Quantum) (((*p) & (0x80 >> bit)) != 0 ? 0x01 : 0x00);
   1069               SetPixelIndex(image,index,q);
   1070               q+=GetPixelChannels(image);
   1071             }
   1072             p++;
   1073           }
   1074           if ((image->columns % 8) != 0)
   1075             {
   1076               for (bit=0; bit < (image->columns % 8); bit++)
   1077               {
   1078                 index=(Quantum) (((*p) & (0x80 >> bit)) != 0 ? 0x01 : 0x00);
   1079                 SetPixelIndex(image,index,q);
   1080                 q+=GetPixelChannels(image);
   1081               }
   1082               p++;
   1083             }
   1084           if (SyncAuthenticPixels(image,exception) == MagickFalse)
   1085             break;
   1086           if (image->previous == (Image *) NULL)
   1087             {
   1088               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
   1089                 (image->rows-y),image->rows);
   1090               if (status == MagickFalse)
   1091                 break;
   1092             }
   1093         }
   1094         (void) SyncImage(image,exception);
   1095         break;
   1096       }
   1097       case 4:
   1098       {
   1099         /*
   1100           Convert PseudoColor scanline.
   1101         */
   1102         for (y=(ssize_t) image->rows-1; y >= 0; y--)
   1103         {
   1104           p=pixels+(image->rows-y-1)*bytes_per_line;
   1105           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
   1106           if (q == (Quantum *) NULL)
   1107             break;
   1108           for (x=0; x < ((ssize_t) image->columns-1); x+=2)
   1109           {
   1110             ValidateColormapValue(image,(*p >> 4) & 0x0f,&index,exception);
   1111             SetPixelIndex(image,index,q);
   1112             q+=GetPixelChannels(image);
   1113             ValidateColormapValue(image,*p & 0x0f,&index,exception);
   1114             SetPixelIndex(image,index,q);
   1115             q+=GetPixelChannels(image);
   1116             p++;
   1117           }
   1118           if ((image->columns % 2) != 0)
   1119             {
   1120               ValidateColormapValue(image,(*p >> 4) & 0xf,&index,exception);
   1121               SetPixelIndex(image,index,q);
   1122               q+=GetPixelChannels(image);
   1123               p++;
   1124               x++;
   1125             }
   1126           if (x < (ssize_t) image->columns)
   1127             break;
   1128           if (SyncAuthenticPixels(image,exception) == MagickFalse)
   1129             break;
   1130           if (image->previous == (Image *) NULL)
   1131             {
   1132               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
   1133                 (image->rows-y),image->rows);
   1134               if (status == MagickFalse)
   1135                 break;
   1136             }
   1137         }
   1138         (void) SyncImage(image,exception);
   1139         break;
   1140       }
   1141       case 8:
   1142       {
   1143         /*
   1144           Convert PseudoColor scanline.
   1145         */
   1146         if ((bmp_info.compression == BI_RLE8) ||
   1147             (bmp_info.compression == BI_RLE4))
   1148           bytes_per_line=image->columns;
   1149         for (y=(ssize_t) image->rows-1; y >= 0; y--)
   1150         {
   1151           p=pixels+(image->rows-y-1)*bytes_per_line;
   1152           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
   1153           if (q == (Quantum *) NULL)
   1154             break;
   1155           for (x=(ssize_t) image->columns; x != 0; --x)
   1156           {
   1157             ValidateColormapValue(image,*p++,&index,exception);
   1158             SetPixelIndex(image,index,q);
   1159             q+=GetPixelChannels(image);
   1160           }
   1161           if (x > 0)
   1162             break;
   1163           if (SyncAuthenticPixels(image,exception) == MagickFalse)
   1164             break;
   1165           offset=(MagickOffsetType) (image->rows-y-1);
   1166           if (image->previous == (Image *) NULL)
   1167             {
   1168               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
   1169                 (image->rows-y),image->rows);
   1170               if (status == MagickFalse)
   1171                 break;
   1172             }
   1173         }
   1174         (void) SyncImage(image,exception);
   1175         break;
   1176       }
   1177       case 16:
   1178       {
   1179         size_t
   1180           alpha,
   1181           pixel;
   1182 
   1183         /*
   1184           Convert bitfield encoded 16-bit PseudoColor scanline.
   1185         */
   1186         if (bmp_info.compression != BI_RGB &&
   1187             bmp_info.compression != BI_BITFIELDS)
   1188           {
   1189             pixel_info=RelinquishVirtualMemory(pixel_info);
   1190             ThrowReaderException(CorruptImageError,
   1191               "UnrecognizedImageCompression");
   1192           }
   1193         bytes_per_line=2*(image->columns+image->columns % 2);
   1194         image->storage_class=DirectClass;
   1195         for (y=(ssize_t) image->rows-1; y >= 0; y--)
   1196         {
   1197           p=pixels+(image->rows-y-1)*bytes_per_line;
   1198           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
   1199           if (q == (Quantum *) NULL)
   1200             break;
   1201           for (x=0; x < (ssize_t) image->columns; x++)
   1202           {
   1203             pixel=(size_t) (*p++);
   1204             pixel|=(*p++) << 8;
   1205             red=((pixel & bmp_info.red_mask) << shift.red) >> 16;
   1206             if (quantum_bits.red == 5)
   1207               red|=((red & 0xe000) >> 5);
   1208             if (quantum_bits.red <= 8)
   1209               red|=((red & 0xff00) >> 8);
   1210             green=((pixel & bmp_info.green_mask) << shift.green) >> 16;
   1211             if (quantum_bits.green == 5)
   1212               green|=((green & 0xe000) >> 5);
   1213             if (quantum_bits.green == 6)
   1214               green|=((green & 0xc000) >> 6);
   1215             if (quantum_bits.green <= 8)
   1216               green|=((green & 0xff00) >> 8);
   1217             blue=((pixel & bmp_info.blue_mask) << shift.blue) >> 16;
   1218             if (quantum_bits.blue == 5)
   1219               blue|=((blue & 0xe000) >> 5);
   1220             if (quantum_bits.blue <= 8)
   1221               blue|=((blue & 0xff00) >> 8);
   1222             SetPixelRed(image,ScaleShortToQuantum((unsigned short) red),q);
   1223             SetPixelGreen(image,ScaleShortToQuantum((unsigned short) green),q);
   1224             SetPixelBlue(image,ScaleShortToQuantum((unsigned short) blue),q);
   1225             SetPixelAlpha(image,OpaqueAlpha,q);
   1226             if (image->alpha_trait != UndefinedPixelTrait)
   1227               {
   1228                 alpha=((pixel & bmp_info.alpha_mask) << shift.alpha) >> 16;
   1229                 if (quantum_bits.alpha <= 8)
   1230                   alpha|=((alpha & 0xff00) >> 8);
   1231                 SetPixelAlpha(image,ScaleShortToQuantum(
   1232                   (unsigned short) alpha),q);
   1233               }
   1234             q+=GetPixelChannels(image);
   1235           }
   1236           if (SyncAuthenticPixels(image,exception) == MagickFalse)
   1237             break;
   1238           offset=(MagickOffsetType) (image->rows-y-1);
   1239           if (image->previous == (Image *) NULL)
   1240             {
   1241               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
   1242                 (image->rows-y),image->rows);
   1243               if (status == MagickFalse)
   1244                 break;
   1245             }
   1246         }
   1247         break;
   1248       }
   1249       case 24:
   1250       {
   1251         /*
   1252           Convert DirectColor scanline.
   1253         */
   1254         bytes_per_line=4*((image->columns*24+31)/32);
   1255         for (y=(ssize_t) image->rows-1; y >= 0; y--)
   1256         {
   1257           p=pixels+(image->rows-y-1)*bytes_per_line;
   1258           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
   1259           if (q == (Quantum *) NULL)
   1260             break;
   1261           for (x=0; x < (ssize_t) image->columns; x++)
   1262           {
   1263             SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
   1264             SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
   1265             SetPixelRed(image,ScaleCharToQuantum(*p++),q);
   1266             SetPixelAlpha(image,OpaqueAlpha,q);
   1267             q+=GetPixelChannels(image);
   1268           }
   1269           if (SyncAuthenticPixels(image,exception) == MagickFalse)
   1270             break;
   1271           offset=(MagickOffsetType) (image->rows-y-1);
   1272           if (image->previous == (Image *) NULL)
   1273             {
   1274               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
   1275                 (image->rows-y),image->rows);
   1276               if (status == MagickFalse)
   1277                 break;
   1278             }
   1279         }
   1280         break;
   1281       }
   1282       case 32:
   1283       {
   1284         /*
   1285           Convert bitfield encoded DirectColor scanline.
   1286         */
   1287         if ((bmp_info.compression != BI_RGB) &&
   1288             (bmp_info.compression != BI_BITFIELDS))
   1289           {
   1290             pixel_info=RelinquishVirtualMemory(pixel_info);
   1291             ThrowReaderException(CorruptImageError,
   1292               "UnrecognizedImageCompression");
   1293           }
   1294         bytes_per_line=4*(image->columns);
   1295         for (y=(ssize_t) image->rows-1; y >= 0; y--)
   1296         {
   1297           size_t
   1298             alpha,
   1299             pixel;
   1300 
   1301           p=pixels+(image->rows-y-1)*bytes_per_line;
   1302           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
   1303           if (q == (Quantum *) NULL)
   1304             break;
   1305           for (x=0; x < (ssize_t) image->columns; x++)
   1306           {
   1307             pixel=(size_t) (*p++);
   1308             pixel|=((size_t) *p++ << 8);
   1309             pixel|=((size_t) *p++ << 16);
   1310             pixel|=((size_t) *p++ << 24);
   1311             red=((pixel & bmp_info.red_mask) << shift.red) >> 16;
   1312             if (quantum_bits.red == 8)
   1313               red|=(red >> 8);
   1314             green=((pixel & bmp_info.green_mask) << shift.green) >> 16;
   1315             if (quantum_bits.green == 8)
   1316               green|=(green >> 8);
   1317             blue=((pixel & bmp_info.blue_mask) << shift.blue) >> 16;
   1318             if (quantum_bits.blue == 8)
   1319               blue|=(blue >> 8);
   1320             SetPixelRed(image,ScaleShortToQuantum((unsigned short) red),q);
   1321             SetPixelGreen(image,ScaleShortToQuantum((unsigned short) green),q);
   1322             SetPixelBlue(image,ScaleShortToQuantum((unsigned short) blue),q);
   1323             SetPixelAlpha(image,OpaqueAlpha,q);
   1324             if (image->alpha_trait != UndefinedPixelTrait)
   1325               {
   1326                 alpha=((pixel & bmp_info.alpha_mask) << shift.alpha) >> 16;
   1327                 if (quantum_bits.alpha == 8)
   1328                   alpha|=(alpha >> 8);
   1329                 SetPixelAlpha(image,ScaleShortToQuantum(
   1330                   (unsigned short) alpha),q);
   1331               }
   1332             q+=GetPixelChannels(image);
   1333           }
   1334           if (SyncAuthenticPixels(image,exception) == MagickFalse)
   1335             break;
   1336           offset=(MagickOffsetType) (image->rows-y-1);
   1337           if (image->previous == (Image *) NULL)
   1338             {
   1339               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
   1340                 (image->rows-y),image->rows);
   1341               if (status == MagickFalse)
   1342                 break;
   1343             }
   1344         }
   1345         break;
   1346       }
   1347       default:
   1348       {
   1349         pixel_info=RelinquishVirtualMemory(pixel_info);
   1350         ThrowReaderException(CorruptImageError,"ImproperImageHeader");
   1351       }
   1352     }
   1353     pixel_info=RelinquishVirtualMemory(pixel_info);
   1354     if (y > 0)
   1355       break;
   1356     if (EOFBlob(image) != MagickFalse)
   1357       {
   1358         ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
   1359           image->filename);
   1360         break;
   1361       }
   1362     if (bmp_info.height < 0)
   1363       {
   1364         Image
   1365           *flipped_image;
   1366 
   1367         /*
   1368           Correct image orientation.
   1369         */
   1370         flipped_image=FlipImage(image,exception);
   1371         if (flipped_image != (Image *) NULL)
   1372           {
   1373             DuplicateBlob(flipped_image,image);
   1374             image=DestroyImage(image);
   1375             image=flipped_image;
   1376           }
   1377       }
   1378     /*
   1379       Proceed to next image.
   1380     */
   1381     if (image_info->number_scenes != 0)
   1382       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
   1383         break;
   1384     *magick='\0';
   1385     if (bmp_info.ba_offset != 0)
   1386       {
   1387         offset=SeekBlob(image,(MagickOffsetType) bmp_info.ba_offset,SEEK_SET);
   1388         if (offset < 0)
   1389           ThrowReaderException(CorruptImageError,"ImproperImageHeader");
   1390       }
   1391     count=ReadBlob(image,2,magick);
   1392     if ((count == 2) && (IsBMP(magick,2) != MagickFalse))
   1393       {
   1394         /*
   1395           Acquire next image structure.
   1396         */
   1397         AcquireNextImage(image_info,image,exception);
   1398         if (GetNextImageInList(image) == (Image *) NULL)
   1399           {
   1400             image=DestroyImageList(image);
   1401             return((Image *) NULL);
   1402           }
   1403         image=SyncNextImageInList(image);
   1404         status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
   1405           GetBlobSize(image));
   1406         if (status == MagickFalse)
   1407           break;
   1408       }
   1409   } while (IsBMP(magick,2) != MagickFalse);
   1410   (void) CloseBlob(image);
   1411   return(GetFirstImageInList(image));
   1412 }
   1413 
   1414 /*
   1416 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1417 %                                                                             %
   1418 %                                                                             %
   1419 %                                                                             %
   1420 %   R e g i s t e r B M P I m a g e                                           %
   1421 %                                                                             %
   1422 %                                                                             %
   1423 %                                                                             %
   1424 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1425 %
   1426 %  RegisterBMPImage() adds attributes for the BMP image format to
   1427 %  the list of supported formats.  The attributes include the image format
   1428 %  tag, a method to read and/or write the format, whether the format
   1429 %  supports the saving of more than one frame to the same file or blob,
   1430 %  whether the format supports native in-memory I/O, and a brief
   1431 %  description of the format.
   1432 %
   1433 %  The format of the RegisterBMPImage method is:
   1434 %
   1435 %      size_t RegisterBMPImage(void)
   1436 %
   1437 */
   1438 ModuleExport size_t RegisterBMPImage(void)
   1439 {
   1440   MagickInfo
   1441     *entry;
   1442 
   1443   entry=AcquireMagickInfo("BMP","BMP","Microsoft Windows bitmap image");
   1444   entry->decoder=(DecodeImageHandler *) ReadBMPImage;
   1445   entry->encoder=(EncodeImageHandler *) WriteBMPImage;
   1446   entry->magick=(IsImageFormatHandler *) IsBMP;
   1447   entry->flags^=CoderAdjoinFlag;
   1448   entry->flags|=CoderSeekableStreamFlag;
   1449   (void) RegisterMagickInfo(entry);
   1450   entry=AcquireMagickInfo("BMP","BMP2","Microsoft Windows bitmap image (V2)");
   1451   entry->encoder=(EncodeImageHandler *) WriteBMPImage;
   1452   entry->magick=(IsImageFormatHandler *) IsBMP;
   1453   entry->flags^=CoderAdjoinFlag;
   1454   entry->flags|=CoderSeekableStreamFlag;
   1455   (void) RegisterMagickInfo(entry);
   1456   entry=AcquireMagickInfo("BMP","BMP3","Microsoft Windows bitmap image (V3)");
   1457   entry->encoder=(EncodeImageHandler *) WriteBMPImage;
   1458   entry->magick=(IsImageFormatHandler *) IsBMP;
   1459   entry->flags^=CoderAdjoinFlag;
   1460   entry->flags|=CoderSeekableStreamFlag;
   1461   (void) RegisterMagickInfo(entry);
   1462   return(MagickImageCoderSignature);
   1463 }
   1464 
   1465 /*
   1467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1468 %                                                                             %
   1469 %                                                                             %
   1470 %                                                                             %
   1471 %   U n r e g i s t e r B M P I m a g e                                       %
   1472 %                                                                             %
   1473 %                                                                             %
   1474 %                                                                             %
   1475 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1476 %
   1477 %  UnregisterBMPImage() removes format registrations made by the
   1478 %  BMP module from the list of supported formats.
   1479 %
   1480 %  The format of the UnregisterBMPImage method is:
   1481 %
   1482 %      UnregisterBMPImage(void)
   1483 %
   1484 */
   1485 ModuleExport void UnregisterBMPImage(void)
   1486 {
   1487   (void) UnregisterMagickInfo("BMP");
   1488   (void) UnregisterMagickInfo("BMP2");
   1489   (void) UnregisterMagickInfo("BMP3");
   1490 }
   1491 
   1492 /*
   1494 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1495 %                                                                             %
   1496 %                                                                             %
   1497 %                                                                             %
   1498 %   W r i t e B M P I m a g e                                                 %
   1499 %                                                                             %
   1500 %                                                                             %
   1501 %                                                                             %
   1502 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1503 %
   1504 %  WriteBMPImage() writes an image in Microsoft Windows bitmap encoded
   1505 %  image format, version 3 for Windows or (if the image has a matte channel)
   1506 %  version 4.
   1507 %
   1508 %  The format of the WriteBMPImage method is:
   1509 %
   1510 %      MagickBooleanType WriteBMPImage(const ImageInfo *image_info,
   1511 %        Image *image,ExceptionInfo *exception)
   1512 %
   1513 %  A description of each parameter follows.
   1514 %
   1515 %    o image_info: the image info.
   1516 %
   1517 %    o image:  The image.
   1518 %
   1519 %    o exception: return any errors or warnings in this structure.
   1520 %
   1521 */
   1522 static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
   1523   ExceptionInfo *exception)
   1524 {
   1525   BMPInfo
   1526     bmp_info;
   1527 
   1528   const char
   1529     *option;
   1530 
   1531   const StringInfo
   1532     *profile;
   1533 
   1534   MagickBooleanType
   1535     have_color_info,
   1536     status;
   1537 
   1538   MagickOffsetType
   1539     scene;
   1540 
   1541   MemoryInfo
   1542     *pixel_info;
   1543 
   1544   register const Quantum
   1545     *p;
   1546 
   1547   register ssize_t
   1548     i,
   1549     x;
   1550 
   1551   register unsigned char
   1552     *q;
   1553 
   1554   size_t
   1555     bytes_per_line,
   1556     type;
   1557 
   1558   ssize_t
   1559     y;
   1560 
   1561   unsigned char
   1562     *bmp_data,
   1563     *pixels;
   1564 
   1565   /*
   1566     Open output image file.
   1567   */
   1568   assert(image_info != (const ImageInfo *) NULL);
   1569   assert(image_info->signature == MagickCoreSignature);
   1570   assert(image != (Image *) NULL);
   1571   assert(image->signature == MagickCoreSignature);
   1572   if (image->debug != MagickFalse)
   1573     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   1574   assert(exception != (ExceptionInfo *) NULL);
   1575   assert(exception->signature == MagickCoreSignature);
   1576   status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
   1577   if (status == MagickFalse)
   1578     return(status);
   1579   type=4;
   1580   if (LocaleCompare(image_info->magick,"BMP2") == 0)
   1581     type=2;
   1582   else
   1583     if (LocaleCompare(image_info->magick,"BMP3") == 0)
   1584       type=3;
   1585 
   1586   option=GetImageOption(image_info,"bmp:format");
   1587   if (option != (char *) NULL)
   1588     {
   1589       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   1590           "  Format=%s",option);
   1591 
   1592       if (LocaleCompare(option,"bmp2") == 0)
   1593         type=2;
   1594       if (LocaleCompare(option,"bmp3") == 0)
   1595         type=3;
   1596       if (LocaleCompare(option,"bmp4") == 0)
   1597         type=4;
   1598     }
   1599 
   1600   scene=0;
   1601   do
   1602   {
   1603     /*
   1604       Initialize BMP raster file header.
   1605     */
   1606     (void) TransformImageColorspace(image,sRGBColorspace,exception);
   1607     (void) ResetMagickMemory(&bmp_info,0,sizeof(bmp_info));
   1608     bmp_info.file_size=14+12;
   1609     if (type > 2)
   1610       bmp_info.file_size+=28;
   1611     bmp_info.offset_bits=bmp_info.file_size;
   1612     bmp_info.compression=BI_RGB;
   1613     if ((image->storage_class == PseudoClass) && (image->colors > 256))
   1614       (void) SetImageStorageClass(image,DirectClass,exception);
   1615     if (image->storage_class != DirectClass)
   1616       {
   1617         /*
   1618           Colormapped BMP raster.
   1619         */
   1620         bmp_info.bits_per_pixel=8;
   1621         if (image->colors <= 2)
   1622           bmp_info.bits_per_pixel=1;
   1623         else
   1624           if (image->colors <= 16)
   1625             bmp_info.bits_per_pixel=4;
   1626           else
   1627             if (image->colors <= 256)
   1628               bmp_info.bits_per_pixel=8;
   1629         if (image_info->compression == RLECompression)
   1630           bmp_info.bits_per_pixel=8;
   1631         bmp_info.number_colors=1U << bmp_info.bits_per_pixel;
   1632         if (image->alpha_trait != UndefinedPixelTrait)
   1633           (void) SetImageStorageClass(image,DirectClass,exception);
   1634         else
   1635           if ((size_t) bmp_info.number_colors < image->colors)
   1636             (void) SetImageStorageClass(image,DirectClass,exception);
   1637           else
   1638             {
   1639               bmp_info.file_size+=3*(1UL << bmp_info.bits_per_pixel);
   1640               bmp_info.offset_bits+=3*(1UL << bmp_info.bits_per_pixel);
   1641               if (type > 2)
   1642                 {
   1643                   bmp_info.file_size+=(1UL << bmp_info.bits_per_pixel);
   1644                   bmp_info.offset_bits+=(1UL << bmp_info.bits_per_pixel);
   1645                 }
   1646             }
   1647       }
   1648     if (image->storage_class == DirectClass)
   1649       {
   1650         /*
   1651           Full color BMP raster.
   1652         */
   1653         bmp_info.number_colors=0;
   1654         bmp_info.bits_per_pixel=(unsigned short)
   1655           ((type > 3) && (image->alpha_trait != UndefinedPixelTrait) ? 32 : 24);
   1656         bmp_info.compression=(unsigned int) ((type > 3) &&
   1657           (image->alpha_trait != UndefinedPixelTrait) ?  BI_BITFIELDS : BI_RGB);
   1658         if ((type == 3) && (image->alpha_trait != UndefinedPixelTrait))
   1659           {
   1660             option=GetImageOption(image_info,"bmp3:alpha");
   1661             if (IsStringTrue(option))
   1662               bmp_info.bits_per_pixel=32;
   1663           }
   1664       }
   1665     bytes_per_line=4*((image->columns*bmp_info.bits_per_pixel+31)/32);
   1666     bmp_info.ba_offset=0;
   1667     profile=GetImageProfile(image,"icc");
   1668     have_color_info=(image->rendering_intent != UndefinedIntent) ||
   1669       (profile != (StringInfo *) NULL) || (image->gamma != 0.0) ?  MagickTrue :
   1670       MagickFalse;
   1671     if (type == 2)
   1672       bmp_info.size=12;
   1673     else
   1674       if ((type == 3) || ((image->alpha_trait == UndefinedPixelTrait) &&
   1675           (have_color_info == MagickFalse)))
   1676         {
   1677           type=3;
   1678           bmp_info.size=40;
   1679         }
   1680       else
   1681         {
   1682           int
   1683             extra_size;
   1684 
   1685           bmp_info.size=108;
   1686           extra_size=68;
   1687           if ((image->rendering_intent != UndefinedIntent) ||
   1688               (profile != (StringInfo *) NULL))
   1689             {
   1690               bmp_info.size=124;
   1691               extra_size+=16;
   1692             }
   1693           bmp_info.file_size+=extra_size;
   1694           bmp_info.offset_bits+=extra_size;
   1695         }
   1696     bmp_info.width=(ssize_t) image->columns;
   1697     bmp_info.height=(ssize_t) image->rows;
   1698     bmp_info.planes=1;
   1699     bmp_info.image_size=(unsigned int) (bytes_per_line*image->rows);
   1700     bmp_info.file_size+=bmp_info.image_size;
   1701     bmp_info.x_pixels=75*39;
   1702     bmp_info.y_pixels=75*39;
   1703     switch (image->units)
   1704     {
   1705       case UndefinedResolution:
   1706       case PixelsPerInchResolution:
   1707       {
   1708         bmp_info.x_pixels=(unsigned int) (100.0*image->resolution.x/2.54);
   1709         bmp_info.y_pixels=(unsigned int) (100.0*image->resolution.y/2.54);
   1710         break;
   1711       }
   1712       case PixelsPerCentimeterResolution:
   1713       {
   1714         bmp_info.x_pixels=(unsigned int) (100.0*image->resolution.x);
   1715         bmp_info.y_pixels=(unsigned int) (100.0*image->resolution.y);
   1716         break;
   1717       }
   1718     }
   1719     bmp_info.colors_important=bmp_info.number_colors;
   1720     /*
   1721       Convert MIFF to BMP raster pixels.
   1722     */
   1723     pixel_info=AcquireVirtualMemory((size_t) bmp_info.image_size,
   1724       sizeof(*pixels));
   1725     if (pixel_info == (MemoryInfo *) NULL)
   1726       ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
   1727     pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
   1728     (void) ResetMagickMemory(pixels,0,(size_t) bmp_info.image_size);
   1729     switch (bmp_info.bits_per_pixel)
   1730     {
   1731       case 1:
   1732       {
   1733         size_t
   1734           bit,
   1735           byte;
   1736 
   1737         /*
   1738           Convert PseudoClass image to a BMP monochrome image.
   1739         */
   1740         for (y=0; y < (ssize_t) image->rows; y++)
   1741         {
   1742           ssize_t
   1743             offset;
   1744 
   1745           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1746           if (p == (const Quantum *) NULL)
   1747             break;
   1748           q=pixels+(image->rows-y-1)*bytes_per_line;
   1749           bit=0;
   1750           byte=0;
   1751           for (x=0; x < (ssize_t) image->columns; x++)
   1752           {
   1753             byte<<=1;
   1754             byte|=GetPixelIndex(image,p) != 0 ? 0x01 : 0x00;
   1755             bit++;
   1756             if (bit == 8)
   1757               {
   1758                 *q++=(unsigned char) byte;
   1759                 bit=0;
   1760                 byte=0;
   1761               }
   1762              p+=GetPixelChannels(image);
   1763            }
   1764            if (bit != 0)
   1765              {
   1766                *q++=(unsigned char) (byte << (8-bit));
   1767                x++;
   1768              }
   1769           offset=(ssize_t) (image->columns+7)/8;
   1770           for (x=offset; x < (ssize_t) bytes_per_line; x++)
   1771             *q++=0x00;
   1772           if (image->previous == (Image *) NULL)
   1773             {
   1774               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
   1775                 image->rows);
   1776               if (status == MagickFalse)
   1777                 break;
   1778             }
   1779         }
   1780         break;
   1781       }
   1782       case 4:
   1783       {
   1784         size_t
   1785           byte,
   1786           nibble;
   1787 
   1788         ssize_t
   1789           offset;
   1790 
   1791         /*
   1792           Convert PseudoClass image to a BMP monochrome image.
   1793         */
   1794         for (y=0; y < (ssize_t) image->rows; y++)
   1795         {
   1796           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1797           if (p == (const Quantum *) NULL)
   1798             break;
   1799           q=pixels+(image->rows-y-1)*bytes_per_line;
   1800           nibble=0;
   1801           byte=0;
   1802           for (x=0; x < (ssize_t) image->columns; x++)
   1803           {
   1804             byte<<=4;
   1805             byte|=((size_t) GetPixelIndex(image,p) & 0x0f);
   1806             nibble++;
   1807             if (nibble == 2)
   1808               {
   1809                 *q++=(unsigned char) byte;
   1810                 nibble=0;
   1811                 byte=0;
   1812               }
   1813             p+=GetPixelChannels(image);
   1814           }
   1815           if (nibble != 0)
   1816             {
   1817               *q++=(unsigned char) (byte << 4);
   1818               x++;
   1819             }
   1820           offset=(ssize_t) (image->columns+1)/2;
   1821           for (x=offset; x < (ssize_t) bytes_per_line; x++)
   1822             *q++=0x00;
   1823           if (image->previous == (Image *) NULL)
   1824             {
   1825               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
   1826                 image->rows);
   1827               if (status == MagickFalse)
   1828                 break;
   1829             }
   1830         }
   1831         break;
   1832       }
   1833       case 8:
   1834       {
   1835         /*
   1836           Convert PseudoClass packet to BMP pixel.
   1837         */
   1838         for (y=0; y < (ssize_t) image->rows; y++)
   1839         {
   1840           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1841           if (p == (const Quantum *) NULL)
   1842             break;
   1843           q=pixels+(image->rows-y-1)*bytes_per_line;
   1844           for (x=0; x < (ssize_t) image->columns; x++)
   1845           {
   1846             *q++=(unsigned char) GetPixelIndex(image,p);
   1847             p+=GetPixelChannels(image);
   1848           }
   1849           for ( ; x < (ssize_t) bytes_per_line; x++)
   1850             *q++=0x00;
   1851           if (image->previous == (Image *) NULL)
   1852             {
   1853               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
   1854                 image->rows);
   1855               if (status == MagickFalse)
   1856                 break;
   1857             }
   1858         }
   1859         break;
   1860       }
   1861       case 24:
   1862       {
   1863         /*
   1864           Convert DirectClass packet to BMP BGR888.
   1865         */
   1866         for (y=0; y < (ssize_t) image->rows; y++)
   1867         {
   1868           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1869           if (p == (const Quantum *) NULL)
   1870             break;
   1871           q=pixels+(image->rows-y-1)*bytes_per_line;
   1872           for (x=0; x < (ssize_t) image->columns; x++)
   1873           {
   1874             *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
   1875             *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
   1876             *q++=ScaleQuantumToChar(GetPixelRed(image,p));
   1877             p+=GetPixelChannels(image);
   1878           }
   1879           for (x=3L*(ssize_t) image->columns; x < (ssize_t) bytes_per_line; x++)
   1880             *q++=0x00;
   1881           if (image->previous == (Image *) NULL)
   1882             {
   1883               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
   1884                 image->rows);
   1885               if (status == MagickFalse)
   1886                 break;
   1887             }
   1888         }
   1889         break;
   1890       }
   1891       case 32:
   1892       {
   1893         /*
   1894           Convert DirectClass packet to ARGB8888 pixel.
   1895         */
   1896         for (y=0; y < (ssize_t) image->rows; y++)
   1897         {
   1898           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1899           if (p == (const Quantum *) NULL)
   1900             break;
   1901           q=pixels+(image->rows-y-1)*bytes_per_line;
   1902           for (x=0; x < (ssize_t) image->columns; x++)
   1903           {
   1904             *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
   1905             *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
   1906             *q++=ScaleQuantumToChar(GetPixelRed(image,p));
   1907             *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
   1908             p+=GetPixelChannels(image);
   1909           }
   1910           if (image->previous == (Image *) NULL)
   1911             {
   1912               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
   1913                 image->rows);
   1914               if (status == MagickFalse)
   1915                 break;
   1916             }
   1917         }
   1918         break;
   1919       }
   1920     }
   1921     if ((type > 2) && (bmp_info.bits_per_pixel == 8))
   1922       if (image_info->compression != NoCompression)
   1923         {
   1924           MemoryInfo
   1925             *rle_info;
   1926 
   1927           /*
   1928             Convert run-length encoded raster pixels.
   1929           */
   1930           rle_info=AcquireVirtualMemory((size_t) (2*(bytes_per_line+2)+2),
   1931             (image->rows+2)*sizeof(*pixels));
   1932           if (rle_info == (MemoryInfo *) NULL)
   1933             {
   1934               pixel_info=RelinquishVirtualMemory(pixel_info);
   1935               ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
   1936             }
   1937           bmp_data=(unsigned char *) GetVirtualMemoryBlob(rle_info);
   1938           bmp_info.file_size-=bmp_info.image_size;
   1939           bmp_info.image_size=(unsigned int) EncodeImage(image,bytes_per_line,
   1940             pixels,bmp_data);
   1941           bmp_info.file_size+=bmp_info.image_size;
   1942           pixel_info=RelinquishVirtualMemory(pixel_info);
   1943           pixel_info=rle_info;
   1944           pixels=bmp_data;
   1945           bmp_info.compression=BI_RLE8;
   1946         }
   1947     /*
   1948       Write BMP for Windows, all versions, 14-byte header.
   1949     */
   1950     if (image->debug != MagickFalse)
   1951       {
   1952         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   1953           "   Writing BMP version %.20g datastream",(double) type);
   1954         if (image->storage_class == DirectClass)
   1955           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   1956             "   Storage class=DirectClass");
   1957         else
   1958           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   1959             "   Storage class=PseudoClass");
   1960         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   1961           "   Image depth=%.20g",(double) image->depth);
   1962         if (image->alpha_trait != UndefinedPixelTrait)
   1963           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   1964             "   Matte=True");
   1965         else
   1966           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   1967             "   Matte=MagickFalse");
   1968         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   1969           "   BMP bits_per_pixel=%.20g",(double) bmp_info.bits_per_pixel);
   1970         switch ((int) bmp_info.compression)
   1971         {
   1972            case BI_RGB:
   1973            {
   1974              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   1975                "   Compression=BI_RGB");
   1976              break;
   1977            }
   1978            case BI_RLE8:
   1979            {
   1980              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   1981                "   Compression=BI_RLE8");
   1982              break;
   1983            }
   1984            case BI_BITFIELDS:
   1985            {
   1986              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   1987                "   Compression=BI_BITFIELDS");
   1988              break;
   1989            }
   1990            default:
   1991            {
   1992              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   1993                "   Compression=UNKNOWN (%lu)",bmp_info.compression);
   1994              break;
   1995            }
   1996         }
   1997         if (bmp_info.number_colors == 0)
   1998           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   1999             "   Number_colors=unspecified");
   2000         else
   2001           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   2002             "   Number_colors=%lu",bmp_info.number_colors);
   2003       }
   2004     (void) WriteBlob(image,2,(unsigned char *) "BM");
   2005     (void) WriteBlobLSBLong(image,bmp_info.file_size);
   2006     (void) WriteBlobLSBLong(image,bmp_info.ba_offset);  /* always 0 */
   2007     (void) WriteBlobLSBLong(image,bmp_info.offset_bits);
   2008     if (type == 2)
   2009       {
   2010         /*
   2011           Write 12-byte version 2 bitmap header.
   2012         */
   2013         (void) WriteBlobLSBLong(image,bmp_info.size);
   2014         (void) WriteBlobLSBSignedShort(image,(signed short) bmp_info.width);
   2015         (void) WriteBlobLSBSignedShort(image,(signed short) bmp_info.height);
   2016         (void) WriteBlobLSBShort(image,bmp_info.planes);
   2017         (void) WriteBlobLSBShort(image,bmp_info.bits_per_pixel);
   2018       }
   2019     else
   2020       {
   2021         /*
   2022           Write 40-byte version 3+ bitmap header.
   2023         */
   2024         (void) WriteBlobLSBLong(image,bmp_info.size);
   2025         (void) WriteBlobLSBSignedLong(image,(signed int) bmp_info.width);
   2026         (void) WriteBlobLSBSignedLong(image,(signed int) bmp_info.height);
   2027         (void) WriteBlobLSBShort(image,bmp_info.planes);
   2028         (void) WriteBlobLSBShort(image,bmp_info.bits_per_pixel);
   2029         (void) WriteBlobLSBLong(image,bmp_info.compression);
   2030         (void) WriteBlobLSBLong(image,bmp_info.image_size);
   2031         (void) WriteBlobLSBLong(image,bmp_info.x_pixels);
   2032         (void) WriteBlobLSBLong(image,bmp_info.y_pixels);
   2033         (void) WriteBlobLSBLong(image,bmp_info.number_colors);
   2034         (void) WriteBlobLSBLong(image,bmp_info.colors_important);
   2035       }
   2036     if ((type > 3) && ((image->alpha_trait != UndefinedPixelTrait) ||
   2037         (have_color_info != MagickFalse)))
   2038       {
   2039         /*
   2040           Write the rest of the 108-byte BMP Version 4 header.
   2041         */
   2042         (void) WriteBlobLSBLong(image,0x00ff0000U);  /* Red mask */
   2043         (void) WriteBlobLSBLong(image,0x0000ff00U);  /* Green mask */
   2044         (void) WriteBlobLSBLong(image,0x000000ffU);  /* Blue mask */
   2045         (void) WriteBlobLSBLong(image,0xff000000U);  /* Alpha mask */
   2046         (void) WriteBlobLSBLong(image,0x73524742U);  /* sRGB */
   2047         (void) WriteBlobLSBLong(image,(unsigned int)
   2048           (image->chromaticity.red_primary.x*0x40000000));
   2049         (void) WriteBlobLSBLong(image,(unsigned int)
   2050           (image->chromaticity.red_primary.y*0x40000000));
   2051         (void) WriteBlobLSBLong(image,(unsigned int)
   2052           ((1.000f-(image->chromaticity.red_primary.x+
   2053           image->chromaticity.red_primary.y))*0x40000000));
   2054         (void) WriteBlobLSBLong(image,(unsigned int)
   2055           (image->chromaticity.green_primary.x*0x40000000));
   2056         (void) WriteBlobLSBLong(image,(unsigned int)
   2057           (image->chromaticity.green_primary.y*0x40000000));
   2058         (void) WriteBlobLSBLong(image,(unsigned int)
   2059           ((1.000f-(image->chromaticity.green_primary.x+
   2060           image->chromaticity.green_primary.y))*0x40000000));
   2061         (void) WriteBlobLSBLong(image,(unsigned int)
   2062           (image->chromaticity.blue_primary.x*0x40000000));
   2063         (void) WriteBlobLSBLong(image,(unsigned int)
   2064           (image->chromaticity.blue_primary.y*0x40000000));
   2065         (void) WriteBlobLSBLong(image,(unsigned int)
   2066           ((1.000f-(image->chromaticity.blue_primary.x+
   2067           image->chromaticity.blue_primary.y))*0x40000000));
   2068         (void) WriteBlobLSBLong(image,(unsigned int)
   2069           (bmp_info.gamma_scale.x*0x10000));
   2070         (void) WriteBlobLSBLong(image,(unsigned int)
   2071           (bmp_info.gamma_scale.y*0x10000));
   2072         (void) WriteBlobLSBLong(image,(unsigned int)
   2073           (bmp_info.gamma_scale.z*0x10000));
   2074         if ((image->rendering_intent != UndefinedIntent) ||
   2075             (profile != (StringInfo *) NULL))
   2076           {
   2077             ssize_t
   2078               intent;
   2079 
   2080             switch ((int) image->rendering_intent)
   2081             {
   2082               case SaturationIntent:
   2083               {
   2084                 intent=LCS_GM_BUSINESS;
   2085                 break;
   2086               }
   2087               case RelativeIntent:
   2088               {
   2089                 intent=LCS_GM_GRAPHICS;
   2090                 break;
   2091               }
   2092               case PerceptualIntent:
   2093               {
   2094                 intent=LCS_GM_IMAGES;
   2095                 break;
   2096               }
   2097               case AbsoluteIntent:
   2098               {
   2099                 intent=LCS_GM_ABS_COLORIMETRIC;
   2100                 break;
   2101               }
   2102               default:
   2103               {
   2104                 intent=0;
   2105                 break;
   2106               }
   2107             }
   2108             (void) WriteBlobLSBLong(image,(unsigned int) intent);
   2109             (void) WriteBlobLSBLong(image,0x00);  /* dummy profile data */
   2110             (void) WriteBlobLSBLong(image,0x00);  /* dummy profile length */
   2111             (void) WriteBlobLSBLong(image,0x00);  /* reserved */
   2112           }
   2113       }
   2114     if (image->storage_class == PseudoClass)
   2115       {
   2116         unsigned char
   2117           *bmp_colormap;
   2118 
   2119         /*
   2120           Dump colormap to file.
   2121         */
   2122         if (image->debug != MagickFalse)
   2123           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   2124             "  Colormap: %.20g entries",(double) image->colors);
   2125         bmp_colormap=(unsigned char *) AcquireQuantumMemory((size_t) (1UL <<
   2126           bmp_info.bits_per_pixel),4*sizeof(*bmp_colormap));
   2127         if (bmp_colormap == (unsigned char *) NULL)
   2128           ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
   2129         q=bmp_colormap;
   2130         for (i=0; i < (ssize_t) MagickMin((ssize_t) image->colors,(ssize_t) bmp_info.number_colors); i++)
   2131         {
   2132           *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].blue));
   2133           *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].green));
   2134           *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].red));
   2135           if (type > 2)
   2136             *q++=(unsigned char) 0x0;
   2137         }
   2138         for ( ; i < (ssize_t) (1UL << bmp_info.bits_per_pixel); i++)
   2139         {
   2140           *q++=(unsigned char) 0x00;
   2141           *q++=(unsigned char) 0x00;
   2142           *q++=(unsigned char) 0x00;
   2143           if (type > 2)
   2144             *q++=(unsigned char) 0x00;
   2145         }
   2146         if (type <= 2)
   2147           (void) WriteBlob(image,(size_t) (3*(1L << bmp_info.bits_per_pixel)),
   2148             bmp_colormap);
   2149         else
   2150           (void) WriteBlob(image,(size_t) (4*(1L << bmp_info.bits_per_pixel)),
   2151             bmp_colormap);
   2152         bmp_colormap=(unsigned char *) RelinquishMagickMemory(bmp_colormap);
   2153       }
   2154     if (image->debug != MagickFalse)
   2155       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   2156         "  Pixels:  %lu bytes",bmp_info.image_size);
   2157     (void) WriteBlob(image,(size_t) bmp_info.image_size,pixels);
   2158     pixel_info=RelinquishVirtualMemory(pixel_info);
   2159     if (GetNextImageInList(image) == (Image *) NULL)
   2160       break;
   2161     image=SyncNextImageInList(image);
   2162     status=SetImageProgress(image,SaveImagesTag,scene++,
   2163       GetImageListLength(image));
   2164     if (status == MagickFalse)
   2165       break;
   2166   } while (image_info->adjoin != MagickFalse);
   2167   (void) CloseBlob(image);
   2168   return(MagickTrue);
   2169 }
   2170