Home | History | Annotate | Download | only in coders
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %                            DDDD   IIIII  BBBB                               %
      7 %                            D   D    I    B   B                              %
      8 %                            D   D    I    BBBB                               %
      9 %                            D   D    I    B   B                              %
     10 %                            DDDD   IIIII  BBBB                               %
     11 %                                                                             %
     12 %                                                                             %
     13 %                   Read/Write Windows DIB Image Format                       %
     14 %                                                                             %
     15 %                              Software Design                                %
     16 %                                   Cristy                                    %
     17 %                                 July 1992                                   %
     18 %                                                                             %
     19 %                                                                             %
     20 %  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
     21 %  dedicated to making software imaging solutions freely available.           %
     22 %                                                                             %
     23 %  You may not use this file except in compliance with the License.  You may  %
     24 %  obtain a copy of the License at                                            %
     25 %                                                                             %
     26 %    http://www.imagemagick.org/script/license.php                            %
     27 %                                                                             %
     28 %  Unless required by applicable law or agreed to in writing, software        %
     29 %  distributed under the License is distributed on an "AS IS" BASIS,          %
     30 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
     31 %  See the License for the specific language governing permissions and        %
     32 %  limitations under the License.                                             %
     33 %                                                                             %
     34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     35 %
     36 %
     37 */
     38 
     39 /*
     41   Include declarations.
     42 */
     43 #include "MagickCore/studio.h"
     44 #include "MagickCore/attribute.h"
     45 #include "MagickCore/blob.h"
     46 #include "MagickCore/blob-private.h"
     47 #include "MagickCore/cache.h"
     48 #include "MagickCore/color.h"
     49 #include "MagickCore/color-private.h"
     50 #include "MagickCore/colormap.h"
     51 #include "MagickCore/colormap-private.h"
     52 #include "MagickCore/colorspace.h"
     53 #include "MagickCore/colorspace-private.h"
     54 #include "MagickCore/draw.h"
     55 #include "MagickCore/exception.h"
     56 #include "MagickCore/exception-private.h"
     57 #include "MagickCore/geometry.h"
     58 #include "MagickCore/image.h"
     59 #include "MagickCore/image-private.h"
     60 #include "MagickCore/list.h"
     61 #include "MagickCore/log.h"
     62 #include "MagickCore/magick.h"
     63 #include "MagickCore/memory_.h"
     64 #include "MagickCore/monitor.h"
     65 #include "MagickCore/monitor-private.h"
     66 #include "MagickCore/pixel-accessor.h"
     67 #include "MagickCore/quantum-private.h"
     68 #include "MagickCore/static.h"
     69 #include "MagickCore/string_.h"
     70 #include "MagickCore/module.h"
     71 #include "MagickCore/transform.h"
     72 
     73 /*
     75   Typedef declarations.
     76 */
     77 typedef struct _DIBInfo
     78 {
     79   size_t
     80     size;
     81 
     82   ssize_t
     83     width,
     84     height;
     85 
     86   unsigned short
     87     planes,
     88     bits_per_pixel;
     89 
     90   size_t
     91     compression,
     92     image_size,
     93     x_pixels,
     94     y_pixels,
     95     number_colors,
     96     red_mask,
     97     green_mask,
     98     blue_mask,
     99     alpha_mask,
    100     colors_important;
    101 
    102   ssize_t
    103     colorspace;
    104 
    105   PointInfo
    106     red_primary,
    107     green_primary,
    108     blue_primary,
    109     gamma_scale;
    110 } DIBInfo;
    111 
    112 /*
    114   Forward declarations.
    115 */
    116 static MagickBooleanType
    117   WriteDIBImage(const ImageInfo *,Image *,ExceptionInfo *);
    118 
    119 /*
    121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    122 %                                                                             %
    123 %                                                                             %
    124 %                                                                             %
    125 %   D e c o d e I m a g e                                                     %
    126 %                                                                             %
    127 %                                                                             %
    128 %                                                                             %
    129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    130 %
    131 %  DecodeImage unpacks the packed image pixels into runlength-encoded
    132 %  pixel packets.
    133 %
    134 %  The format of the DecodeImage method is:
    135 %
    136 %      MagickBooleanType DecodeImage(Image *image,
    137 %        const MagickBooleanType compression,unsigned char *pixels)
    138 %
    139 %  A description of each parameter follows:
    140 %
    141 %    o image: the address of a structure of type Image.
    142 %
    143 %    o compression:  A value of 1 means the compressed pixels are runlength
    144 %      encoded for a 256-color bitmap.  A value of 2 means a 16-color bitmap.
    145 %
    146 %    o pixels:  The address of a byte (8 bits) array of pixel data created by
    147 %      the decoding process.
    148 %
    149 */
    150 static MagickBooleanType DecodeImage(Image *image,
    151   const MagickBooleanType compression,unsigned char *pixels)
    152 {
    153 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__MINGW32__) || defined(__MINGW64__)
    154 #define BI_RGB  0
    155 #define BI_RLE8  1
    156 #define BI_RLE4  2
    157 #define BI_BITFIELDS  3
    158 #undef BI_JPEG
    159 #define BI_JPEG  4
    160 #undef BI_PNG
    161 #define BI_PNG  5
    162 #endif
    163 
    164   int
    165     count;
    166 
    167   ssize_t
    168     y;
    169 
    170   register ssize_t
    171     i,
    172     x;
    173 
    174   register unsigned char
    175     *p,
    176     *q;
    177 
    178   unsigned char
    179     byte;
    180 
    181   assert(image != (Image *) NULL);
    182   assert(image->signature == MagickCoreSignature);
    183   if (image->debug != MagickFalse)
    184     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    185   assert(pixels != (unsigned char *) NULL);
    186   (void) ResetMagickMemory(pixels,0,(size_t) image->columns*image->rows*
    187     sizeof(*pixels));
    188   byte=0;
    189   x=0;
    190   p=pixels;
    191   q=pixels+(size_t) image->columns*image->rows;
    192   for (y=0; y < (ssize_t) image->rows; )
    193   {
    194     if ((p < pixels) || (p >= q))
    195       break;
    196     count=ReadBlobByte(image);
    197     if (count == EOF)
    198       break;
    199     if (count != 0)
    200       {
    201         count=(int) MagickMin((size_t) count,(size_t) (q-p));
    202         /*
    203           Encoded mode.
    204         */
    205         byte=(unsigned char) ReadBlobByte(image);
    206         if (compression == BI_RLE8)
    207           {
    208             for (i=0; i < count; i++)
    209               *p++=(unsigned char) byte;
    210           }
    211         else
    212           {
    213             for (i=0; i < count; i++)
    214               *p++=(unsigned char)
    215                 ((i & 0x01) != 0 ? (byte & 0x0f) : ((byte >> 4) & 0x0f));
    216           }
    217         x+=count;
    218       }
    219     else
    220       {
    221         /*
    222           Escape mode.
    223         */
    224         count=ReadBlobByte(image);
    225         if (count == 0x01)
    226           return(MagickTrue);
    227         switch (count)
    228         {
    229           case 0x00:
    230           {
    231             /*
    232               End of line.
    233             */
    234             x=0;
    235             y++;
    236             p=pixels+y*image->columns;
    237             break;
    238           }
    239           case 0x02:
    240           {
    241             /*
    242               Delta mode.
    243             */
    244             x+=ReadBlobByte(image);
    245             y+=ReadBlobByte(image);
    246             p=pixels+y*image->columns+x;
    247             break;
    248           }
    249           default:
    250           {
    251             /*
    252               Absolute mode.
    253             */
    254             count=(int) MagickMin((size_t) count,(size_t) (q-p));
    255             if (compression == BI_RLE8)
    256               for (i=0; i < count; i++)
    257                 *p++=(unsigned char) ReadBlobByte(image);
    258             else
    259               for (i=0; i < count; i++)
    260               {
    261                 if ((i & 0x01) == 0)
    262                   byte=(unsigned char) ReadBlobByte(image);
    263                 *p++=(unsigned char)
    264                   ((i & 0x01) != 0 ? (byte & 0x0f) : ((byte >> 4) & 0x0f));
    265               }
    266             x+=count;
    267             /*
    268               Read pad byte.
    269             */
    270             if (compression == BI_RLE8)
    271               {
    272                 if ((count & 0x01) != 0)
    273                   (void) ReadBlobByte(image);
    274               }
    275             else
    276               if (((count & 0x03) == 1) || ((count & 0x03) == 2))
    277                 (void) ReadBlobByte(image);
    278             break;
    279           }
    280         }
    281       }
    282     if (SetImageProgress(image,LoadImageTag,y,image->rows) == MagickFalse)
    283       break;
    284   }
    285   (void) ReadBlobByte(image);  /* end of line */
    286   (void) ReadBlobByte(image);
    287   return(MagickTrue);
    288 }
    289 
    290 /*
    292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    293 %                                                                             %
    294 %                                                                             %
    295 %                                                                             %
    296 %   E n c o d e I m a g e                                                     %
    297 %                                                                             %
    298 %                                                                             %
    299 %                                                                             %
    300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    301 %
    302 %  EncodeImage compresses pixels using a runlength encoded format.
    303 %
    304 %  The format of the EncodeImage method is:
    305 %
    306 %    static MagickBooleanType EncodeImage(Image *image,
    307 %      const size_t bytes_per_line,const unsigned char *pixels,
    308 %      unsigned char *compressed_pixels)
    309 %
    310 %  A description of each parameter follows:
    311 %
    312 %    o image:  The image.
    313 %
    314 %    o bytes_per_line: the number of bytes in a scanline of compressed pixels
    315 %
    316 %    o pixels:  The address of a byte (8 bits) array of pixel data created by
    317 %      the compression process.
    318 %
    319 %    o compressed_pixels:  The address of a byte (8 bits) array of compressed
    320 %      pixel data.
    321 %
    322 */
    323 static size_t EncodeImage(Image *image,const size_t bytes_per_line,
    324   const unsigned char *pixels,unsigned char *compressed_pixels)
    325 {
    326   ssize_t
    327     y;
    328 
    329   register const unsigned char
    330     *p;
    331 
    332   register ssize_t
    333     i,
    334     x;
    335 
    336   register unsigned char
    337     *q;
    338 
    339   /*
    340     Runlength encode pixels.
    341   */
    342   assert(image != (Image *) NULL);
    343   assert(image->signature == MagickCoreSignature);
    344   if (image->debug != MagickFalse)
    345     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    346   assert(pixels != (const unsigned char *) NULL);
    347   assert(compressed_pixels != (unsigned char *) NULL);
    348   p=pixels;
    349   q=compressed_pixels;
    350   i=0;
    351   for (y=0; y < (ssize_t) image->rows; y++)
    352   {
    353     for (x=0; x < (ssize_t) bytes_per_line; x+=i)
    354     {
    355       /*
    356         Determine runlength.
    357       */
    358       for (i=1; ((x+i) < (ssize_t) bytes_per_line); i++)
    359         if ((*(p+i) != *p) || (i == 255))
    360           break;
    361       *q++=(unsigned char) i;
    362       *q++=(*p);
    363       p+=i;
    364     }
    365     /*
    366       End of line.
    367     */
    368     *q++=0x00;
    369     *q++=0x00;
    370     if (SetImageProgress(image,LoadImageTag,y,image->rows) == MagickFalse)
    371       break;
    372   }
    373   /*
    374     End of bitmap.
    375   */
    376   *q++=0;
    377   *q++=0x01;
    378   return((size_t) (q-compressed_pixels));
    379 }
    380 
    381 /*
    383 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    384 %                                                                             %
    385 %                                                                             %
    386 %                                                                             %
    387 %   I s D I B                                                                 %
    388 %                                                                             %
    389 %                                                                             %
    390 %                                                                             %
    391 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    392 %
    393 %  IsDIB() returns MagickTrue if the image format type, identified by the
    394 %  magick string, is DIB.
    395 %
    396 %  The format of the IsDIB method is:
    397 %
    398 %      MagickBooleanType IsDIB(const unsigned char *magick,const size_t length)
    399 %
    400 %  A description of each parameter follows:
    401 %
    402 %    o magick: compare image format pattern against these bytes.
    403 %
    404 %    o length: Specifies the length of the magick string.
    405 %
    406 */
    407 static MagickBooleanType IsDIB(const unsigned char *magick,const size_t length)
    408 {
    409   if (length < 2)
    410     return(MagickFalse);
    411   if (memcmp(magick,"\050\000",2) == 0)
    412     return(MagickTrue);
    413   return(MagickFalse);
    414 }
    415 
    416 /*
    418 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    419 %                                                                             %
    420 %                                                                             %
    421 %                                                                             %
    422 %   R e a d D I B I m a g e                                                   %
    423 %                                                                             %
    424 %                                                                             %
    425 %                                                                             %
    426 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    427 %
    428 %  ReadDIBImage() reads a Microsoft Windows bitmap image file and
    429 %  returns it.  It allocates the memory necessary for the new Image structure
    430 %  and returns a pointer to the new image.
    431 %
    432 %  The format of the ReadDIBImage method is:
    433 %
    434 %      image=ReadDIBImage(image_info)
    435 %
    436 %  A description of each parameter follows:
    437 %
    438 %    o image_info: the image info.
    439 %
    440 %    o exception: return any errors or warnings in this structure.
    441 %
    442 */
    443 static Image *ReadDIBImage(const ImageInfo *image_info,ExceptionInfo *exception)
    444 {
    445   DIBInfo
    446     dib_info;
    447 
    448   Image
    449     *image;
    450 
    451   MagickBooleanType
    452     status;
    453 
    454   MemoryInfo
    455     *pixel_info;
    456 
    457   Quantum
    458     index;
    459 
    460   register ssize_t
    461     x;
    462 
    463   register Quantum
    464     *q;
    465 
    466   register ssize_t
    467     i;
    468 
    469   register unsigned char
    470     *p;
    471 
    472   size_t
    473     bytes_per_line,
    474     length;
    475 
    476   ssize_t
    477     bit,
    478     count,
    479     y;
    480 
    481 
    482   unsigned char
    483     *pixels;
    484 
    485   /*
    486     Open image file.
    487   */
    488   assert(image_info != (const ImageInfo *) NULL);
    489   assert(image_info->signature == MagickCoreSignature);
    490   if (image_info->debug != MagickFalse)
    491     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
    492       image_info->filename);
    493   assert(exception != (ExceptionInfo *) NULL);
    494   assert(exception->signature == MagickCoreSignature);
    495   image=AcquireImage(image_info,exception);
    496   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
    497   if (status == MagickFalse)
    498     {
    499       image=DestroyImageList(image);
    500       return((Image *) NULL);
    501     }
    502   /*
    503     Determine if this a DIB file.
    504   */
    505   (void) ResetMagickMemory(&dib_info,0,sizeof(dib_info));
    506   dib_info.size=ReadBlobLSBLong(image);
    507   if (dib_info.size != 40)
    508     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    509   /*
    510     Microsoft Windows 3.X DIB image file.
    511   */
    512   dib_info.width=ReadBlobLSBSignedLong(image);
    513   dib_info.height=ReadBlobLSBSignedLong(image);
    514   dib_info.planes=ReadBlobLSBShort(image);
    515   dib_info.bits_per_pixel=ReadBlobLSBShort(image);
    516   if (dib_info.bits_per_pixel > 32)
    517     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    518   dib_info.compression=ReadBlobLSBLong(image);
    519   dib_info.image_size=ReadBlobLSBLong(image);
    520   dib_info.x_pixels=ReadBlobLSBLong(image);
    521   dib_info.y_pixels=ReadBlobLSBLong(image);
    522   dib_info.number_colors=ReadBlobLSBLong(image);
    523   dib_info.colors_important=ReadBlobLSBLong(image);
    524   if ((dib_info.bits_per_pixel != 1) && (dib_info.bits_per_pixel != 4) &&
    525       (dib_info.bits_per_pixel != 8) && (dib_info.bits_per_pixel != 16) &&
    526       (dib_info.bits_per_pixel != 24) && (dib_info.bits_per_pixel != 32))
    527     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    528   if ((dib_info.compression == BI_BITFIELDS) &&
    529       ((dib_info.bits_per_pixel == 16) || (dib_info.bits_per_pixel == 32)))
    530     {
    531       dib_info.red_mask=ReadBlobLSBLong(image);
    532       dib_info.green_mask=ReadBlobLSBLong(image);
    533       dib_info.blue_mask=ReadBlobLSBLong(image);
    534     }
    535   if (EOFBlob(image) != MagickFalse)
    536     ThrowReaderException(CorruptImageError,"UnexpectedEndOfFile");
    537   if (dib_info.width <= 0)
    538     ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
    539   if (dib_info.height == 0)
    540     ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
    541   if (dib_info.planes != 1)
    542     ThrowReaderException(CorruptImageError,"StaticPlanesValueNotEqualToOne");
    543   if ((dib_info.bits_per_pixel != 1) && (dib_info.bits_per_pixel != 4) &&
    544       (dib_info.bits_per_pixel != 8) && (dib_info.bits_per_pixel != 16) &&
    545       (dib_info.bits_per_pixel != 24) && (dib_info.bits_per_pixel != 32))
    546     ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
    547   if (dib_info.bits_per_pixel < 16 &&
    548       dib_info.number_colors > (size_t) (1UL << dib_info.bits_per_pixel))
    549     ThrowReaderException(CorruptImageError,"UnrecognizedNumberOfColors");
    550   if ((dib_info.compression == 1) && (dib_info.bits_per_pixel != 8))
    551     ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
    552   if ((dib_info.compression == 2) && (dib_info.bits_per_pixel != 4))
    553     ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
    554   if ((dib_info.compression == 3) && (dib_info.bits_per_pixel < 16))
    555     ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
    556   switch (dib_info.compression)
    557   {
    558     case BI_RGB:
    559     case BI_RLE8:
    560     case BI_RLE4:
    561     case BI_BITFIELDS:
    562       break;
    563     case BI_JPEG:
    564       ThrowReaderException(CoderError,"JPEGCompressNotSupported");
    565     case BI_PNG:
    566       ThrowReaderException(CoderError,"PNGCompressNotSupported");
    567     default:
    568       ThrowReaderException(CorruptImageError,"UnrecognizedImageCompression");
    569   }
    570   image->columns=(size_t) MagickAbsoluteValue(dib_info.width);
    571   image->rows=(size_t) MagickAbsoluteValue(dib_info.height);
    572   image->depth=8;
    573   image->alpha_trait=dib_info.bits_per_pixel == 32 ? BlendPixelTrait :
    574     UndefinedPixelTrait;
    575   if ((dib_info.number_colors > 256) || (dib_info.colors_important > 256))
    576     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    577   if ((dib_info.number_colors != 0) || (dib_info.bits_per_pixel < 16))
    578     {
    579       size_t
    580         one;
    581 
    582       image->storage_class=PseudoClass;
    583       image->colors=dib_info.number_colors;
    584       one=1;
    585       if (image->colors == 0)
    586         image->colors=one << dib_info.bits_per_pixel;
    587     }
    588   if (image_info->size)
    589     {
    590       RectangleInfo
    591         geometry;
    592 
    593       MagickStatusType
    594         flags;
    595 
    596       flags=ParseAbsoluteGeometry(image_info->size,&geometry);
    597       if (flags & WidthValue)
    598         if ((geometry.width != 0) && (geometry.width < image->columns))
    599           image->columns=geometry.width;
    600       if (flags & HeightValue)
    601         if ((geometry.height != 0) && (geometry.height < image->rows))
    602           image->rows=geometry.height;
    603     }
    604   status=SetImageExtent(image,image->columns,image->rows,exception);
    605   if (status == MagickFalse)
    606     return(DestroyImageList(image));
    607   if (image->storage_class == PseudoClass)
    608     {
    609       size_t
    610         length,
    611         packet_size;
    612 
    613       unsigned char
    614         *dib_colormap;
    615 
    616       /*
    617         Read DIB raster colormap.
    618       */
    619       if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
    620         ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    621       length=(size_t) image->colors;
    622       dib_colormap=(unsigned char *) AcquireQuantumMemory(length,
    623         4*sizeof(*dib_colormap));
    624       if (dib_colormap == (unsigned char *) NULL)
    625         ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    626       packet_size=4;
    627       count=ReadBlob(image,packet_size*image->colors,dib_colormap);
    628       if (count != (ssize_t) (packet_size*image->colors))
    629         ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
    630       p=dib_colormap;
    631       for (i=0; i < (ssize_t) image->colors; i++)
    632       {
    633         image->colormap[i].blue=ScaleCharToQuantum(*p++);
    634         image->colormap[i].green=ScaleCharToQuantum(*p++);
    635         image->colormap[i].red=ScaleCharToQuantum(*p++);
    636         if (packet_size == 4)
    637           p++;
    638       }
    639       dib_colormap=(unsigned char *) RelinquishMagickMemory(dib_colormap);
    640     }
    641   /*
    642     Read image data.
    643   */
    644   if (dib_info.compression == BI_RLE4)
    645     dib_info.bits_per_pixel<<=1;
    646   bytes_per_line=4*((image->columns*dib_info.bits_per_pixel+31)/32);
    647   length=bytes_per_line*image->rows;
    648   pixel_info=AcquireVirtualMemory((size_t) image->rows,MagickMax(
    649     bytes_per_line,image->columns+256UL)*sizeof(*pixels));
    650   if (pixel_info == (MemoryInfo *) NULL)
    651     ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    652   pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
    653   if ((dib_info.compression == BI_RGB) ||
    654       (dib_info.compression == BI_BITFIELDS))
    655     {
    656       count=ReadBlob(image,length,pixels);
    657       if (count != (ssize_t) (length))
    658         ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
    659     }
    660   else
    661     {
    662       /*
    663         Convert run-length encoded raster pixels.
    664       */
    665       status=DecodeImage(image,dib_info.compression ? MagickTrue : MagickFalse,
    666         pixels);
    667       if (status == MagickFalse)
    668         ThrowReaderException(CorruptImageError,"UnableToRunlengthDecodeImage");
    669     }
    670   /*
    671     Initialize image structure.
    672   */
    673   image->units=PixelsPerCentimeterResolution;
    674   image->resolution.x=(double) dib_info.x_pixels/100.0;
    675   image->resolution.y=(double) dib_info.y_pixels/100.0;
    676   /*
    677     Convert DIB raster image to pixel packets.
    678   */
    679   switch (dib_info.bits_per_pixel)
    680   {
    681     case 1:
    682     {
    683       /*
    684         Convert bitmap scanline.
    685       */
    686       for (y=(ssize_t) image->rows-1; y >= 0; y--)
    687       {
    688         p=pixels+(image->rows-y-1)*bytes_per_line;
    689         q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
    690         if (q == (Quantum *) NULL)
    691           break;
    692         for (x=0; x < ((ssize_t) image->columns-7); x+=8)
    693         {
    694           for (bit=0; bit < 8; bit++)
    695           {
    696             index=(Quantum) ((*p) & (0x80 >> bit) ? 0x01 : 0x00);
    697             SetPixelIndex(image,index,q);
    698             q+=GetPixelChannels(image);
    699           }
    700           p++;
    701         }
    702         if ((image->columns % 8) != 0)
    703           {
    704             for (bit=0; bit < (ssize_t) (image->columns % 8); bit++)
    705             {
    706               index=(Quantum) ((*p) & (0x80 >> bit) ? 0x01 : 0x00);
    707               SetPixelIndex(image,index,q);
    708               q+=GetPixelChannels(image);
    709             }
    710             p++;
    711           }
    712         if (SyncAuthenticPixels(image,exception) == MagickFalse)
    713           break;
    714         if (image->previous == (Image *) NULL)
    715           {
    716             status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
    717               image->rows);
    718             if (status == MagickFalse)
    719               break;
    720           }
    721       }
    722       (void) SyncImage(image,exception);
    723       break;
    724     }
    725     case 4:
    726     {
    727       /*
    728         Convert PseudoColor scanline.
    729       */
    730       for (y=(ssize_t) image->rows-1; y >= 0; y--)
    731       {
    732         p=pixels+(image->rows-y-1)*bytes_per_line;
    733         q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
    734         if (q == (Quantum *) NULL)
    735           break;
    736         for (x=0; x < ((ssize_t) image->columns-1); x+=2)
    737         {
    738           index=ConstrainColormapIndex(image,(*p >> 4) & 0xf,exception);
    739           SetPixelIndex(image,index,q);
    740           q+=GetPixelChannels(image);
    741           index=ConstrainColormapIndex(image,*p & 0xf,exception);
    742           SetPixelIndex(image,index,q);
    743           p++;
    744           q+=GetPixelChannels(image);
    745         }
    746         if ((image->columns % 2) != 0)
    747           {
    748             index=ConstrainColormapIndex(image,(*p >> 4) & 0xf,exception);
    749             SetPixelIndex(image,index,q);
    750             q+=GetPixelChannels(image);
    751             p++;
    752           }
    753         if (SyncAuthenticPixels(image,exception) == MagickFalse)
    754           break;
    755         if (image->previous == (Image *) NULL)
    756           {
    757             status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
    758               image->rows);
    759             if (status == MagickFalse)
    760               break;
    761           }
    762       }
    763       (void) SyncImage(image,exception);
    764       break;
    765     }
    766     case 8:
    767     {
    768       /*
    769         Convert PseudoColor scanline.
    770       */
    771       if ((dib_info.compression == BI_RLE8) ||
    772           (dib_info.compression == BI_RLE4))
    773         bytes_per_line=image->columns;
    774       for (y=(ssize_t) image->rows-1; y >= 0; y--)
    775       {
    776         p=pixels+(image->rows-y-1)*bytes_per_line;
    777         q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
    778         if (q == (Quantum *) NULL)
    779           break;
    780         for (x=0; x < (ssize_t) image->columns; x++)
    781         {
    782           index=ConstrainColormapIndex(image,*p,exception);
    783           SetPixelIndex(image,index,q);
    784           p++;
    785           q+=GetPixelChannels(image);
    786         }
    787         if (SyncAuthenticPixels(image,exception) == MagickFalse)
    788           break;
    789         if (image->previous == (Image *) NULL)
    790           {
    791             status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
    792               image->rows);
    793             if (status == MagickFalse)
    794               break;
    795           }
    796       }
    797       (void) SyncImage(image,exception);
    798       break;
    799     }
    800     case 16:
    801     {
    802       unsigned short
    803         word;
    804 
    805       /*
    806         Convert PseudoColor scanline.
    807       */
    808       image->storage_class=DirectClass;
    809       if (dib_info.compression == BI_RLE8)
    810         bytes_per_line=2*image->columns;
    811       for (y=(ssize_t) image->rows-1; y >= 0; y--)
    812       {
    813         p=pixels+(image->rows-y-1)*bytes_per_line;
    814         q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
    815         if (q == (Quantum *) NULL)
    816           break;
    817         for (x=0; x < (ssize_t) image->columns; x++)
    818         {
    819           word=(*p++);
    820           word|=(*p++ << 8);
    821           if (dib_info.red_mask == 0)
    822             {
    823               SetPixelRed(image,ScaleCharToQuantum(ScaleColor5to8(
    824                 (unsigned char) ((word >> 10) & 0x1f))),q);
    825               SetPixelGreen(image,ScaleCharToQuantum(ScaleColor5to8(
    826                 (unsigned char) ((word >> 5) & 0x1f))),q);
    827               SetPixelBlue(image,ScaleCharToQuantum(ScaleColor5to8(
    828                 (unsigned char) (word & 0x1f))),q);
    829             }
    830           else
    831             {
    832               SetPixelRed(image,ScaleCharToQuantum(ScaleColor5to8(
    833                 (unsigned char) ((word >> 11) & 0x1f))),q);
    834               SetPixelGreen(image,ScaleCharToQuantum(ScaleColor6to8(
    835                 (unsigned char) ((word >> 5) & 0x3f))),q);
    836               SetPixelBlue(image,ScaleCharToQuantum(ScaleColor5to8(
    837                 (unsigned char) (word & 0x1f))),q);
    838             }
    839           q+=GetPixelChannels(image);
    840         }
    841         if (SyncAuthenticPixels(image,exception) == MagickFalse)
    842           break;
    843         if (image->previous == (Image *) NULL)
    844           {
    845             status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
    846               image->rows);
    847             if (status == MagickFalse)
    848               break;
    849           }
    850       }
    851       break;
    852     }
    853     case 24:
    854     case 32:
    855     {
    856       /*
    857         Convert DirectColor scanline.
    858       */
    859       for (y=(ssize_t) image->rows-1; y >= 0; y--)
    860       {
    861         p=pixels+(image->rows-y-1)*bytes_per_line;
    862         q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
    863         if (q == (Quantum *) NULL)
    864           break;
    865         for (x=0; x < (ssize_t) image->columns; x++)
    866         {
    867           SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
    868           SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
    869           SetPixelRed(image,ScaleCharToQuantum(*p++),q);
    870           if (image->alpha_trait != UndefinedPixelTrait)
    871             SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
    872           q+=GetPixelChannels(image);
    873         }
    874         if (SyncAuthenticPixels(image,exception) == MagickFalse)
    875           break;
    876         if (image->previous == (Image *) NULL)
    877           {
    878             status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
    879               image->rows);
    880             if (status == MagickFalse)
    881               break;
    882           }
    883       }
    884       break;
    885     }
    886     default:
    887       ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    888   }
    889   pixel_info=RelinquishVirtualMemory(pixel_info);
    890   if (EOFBlob(image) != MagickFalse)
    891     ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
    892       image->filename);
    893   if (dib_info.height < 0)
    894     {
    895       Image
    896         *flipped_image;
    897 
    898       /*
    899         Correct image orientation.
    900       */
    901       flipped_image=FlipImage(image,exception);
    902       if (flipped_image != (Image *) NULL)
    903         {
    904           DuplicateBlob(flipped_image,image);
    905           image=DestroyImage(image);
    906           image=flipped_image;
    907         }
    908     }
    909   (void) CloseBlob(image);
    910   return(GetFirstImageInList(image));
    911 }
    912 
    913 /*
    915 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    916 %                                                                             %
    917 %                                                                             %
    918 %                                                                             %
    919 %   R e g i s t e r D I B I m a g e                                           %
    920 %                                                                             %
    921 %                                                                             %
    922 %                                                                             %
    923 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    924 %
    925 %  RegisterDIBImage() adds attributes for the DIB image format to
    926 %  the list of supported formats.  The attributes include the image format
    927 %  tag, a method to read and/or write the format, whether the format
    928 %  supports the saving of more than one frame to the same file or blob,
    929 %  whether the format supports native in-memory I/O, and a brief
    930 %  description of the format.
    931 %
    932 %  The format of the RegisterDIBImage method is:
    933 %
    934 %      size_t RegisterDIBImage(void)
    935 %
    936 */
    937 ModuleExport size_t RegisterDIBImage(void)
    938 {
    939   MagickInfo
    940     *entry;
    941 
    942   entry=AcquireMagickInfo("DIB","DIB",
    943     "Microsoft Windows 3.X Packed Device-Independent Bitmap");
    944   entry->decoder=(DecodeImageHandler *) ReadDIBImage;
    945   entry->encoder=(EncodeImageHandler *) WriteDIBImage;
    946   entry->magick=(IsImageFormatHandler *) IsDIB;
    947   entry->flags^=CoderAdjoinFlag;
    948   entry->flags|=CoderStealthFlag;
    949   (void) RegisterMagickInfo(entry);
    950   return(MagickImageCoderSignature);
    951 }
    952 
    953 /*
    955 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    956 %                                                                             %
    957 %                                                                             %
    958 %                                                                             %
    959 %   U n r e g i s t e r D I B I m a g e                                       %
    960 %                                                                             %
    961 %                                                                             %
    962 %                                                                             %
    963 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    964 %
    965 %  UnregisterDIBImage() removes format registrations made by the
    966 %  DIB module from the list of supported formats.
    967 %
    968 %  The format of the UnregisterDIBImage method is:
    969 %
    970 %      UnregisterDIBImage(void)
    971 %
    972 */
    973 ModuleExport void UnregisterDIBImage(void)
    974 {
    975   (void) UnregisterMagickInfo("DIB");
    976 }
    977 
    978 /*
    980 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    981 %                                                                             %
    982 %                                                                             %
    983 %                                                                             %
    984 %   W r i t e D I B I m a g e                                                 %
    985 %                                                                             %
    986 %                                                                             %
    987 %                                                                             %
    988 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    989 %
    990 %  WriteDIBImage() writes an image in Microsoft Windows bitmap encoded
    991 %  image format.
    992 %
    993 %  The format of the WriteDIBImage method is:
    994 %
    995 %      MagickBooleanType WriteDIBImage(const ImageInfo *image_info,
    996 %        Image *image,ExceptionInfo *exception)
    997 %
    998 %  A description of each parameter follows.
    999 %
   1000 %    o image_info: the image info.
   1001 %
   1002 %    o image:  The image.
   1003 %
   1004 %    o exception: return any errors or warnings in this structure.
   1005 %
   1006 */
   1007 static MagickBooleanType WriteDIBImage(const ImageInfo *image_info,Image *image,
   1008   ExceptionInfo *exception)
   1009 {
   1010   DIBInfo
   1011     dib_info;
   1012 
   1013   MagickBooleanType
   1014     status;
   1015 
   1016   register const Quantum
   1017     *p;
   1018 
   1019   register ssize_t
   1020     i,
   1021     x;
   1022 
   1023   register unsigned char
   1024     *q;
   1025 
   1026   size_t
   1027     bytes_per_line;
   1028 
   1029   ssize_t
   1030     y;
   1031 
   1032   unsigned char
   1033     *dib_data,
   1034     *pixels;
   1035 
   1036   /*
   1037     Open output image file.
   1038   */
   1039   assert(image_info != (const ImageInfo *) NULL);
   1040   assert(image_info->signature == MagickCoreSignature);
   1041   assert(image != (Image *) NULL);
   1042   assert(image->signature == MagickCoreSignature);
   1043   if (image->debug != MagickFalse)
   1044     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   1045   assert(exception != (ExceptionInfo *) NULL);
   1046   assert(exception->signature == MagickCoreSignature);
   1047   status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
   1048   if (status == MagickFalse)
   1049     return(status);
   1050   /*
   1051     Initialize DIB raster file header.
   1052   */
   1053   (void) TransformImageColorspace(image,sRGBColorspace,exception);
   1054   if (image->storage_class == DirectClass)
   1055     {
   1056       /*
   1057         Full color DIB raster.
   1058       */
   1059       dib_info.number_colors=0;
   1060       dib_info.bits_per_pixel=(unsigned short) (image->alpha_trait ? 32 : 24);
   1061     }
   1062   else
   1063     {
   1064       /*
   1065         Colormapped DIB raster.
   1066       */
   1067       dib_info.bits_per_pixel=8;
   1068       if (image_info->depth > 8)
   1069         dib_info.bits_per_pixel=16;
   1070       if (SetImageMonochrome(image,exception) != MagickFalse)
   1071         dib_info.bits_per_pixel=1;
   1072       dib_info.number_colors=(dib_info.bits_per_pixel == 16) ? 0 :
   1073         (1UL << dib_info.bits_per_pixel);
   1074     }
   1075   bytes_per_line=4*((image->columns*dib_info.bits_per_pixel+31)/32);
   1076   dib_info.size=40;
   1077   dib_info.width=(ssize_t) image->columns;
   1078   dib_info.height=(ssize_t) image->rows;
   1079   dib_info.planes=1;
   1080   dib_info.compression=(size_t) (dib_info.bits_per_pixel == 16 ?
   1081     BI_BITFIELDS : BI_RGB);
   1082   dib_info.image_size=bytes_per_line*image->rows;
   1083   dib_info.x_pixels=75*39;
   1084   dib_info.y_pixels=75*39;
   1085   switch (image->units)
   1086   {
   1087     case UndefinedResolution:
   1088     case PixelsPerInchResolution:
   1089     {
   1090       dib_info.x_pixels=(size_t) (100.0*image->resolution.x/2.54);
   1091       dib_info.y_pixels=(size_t) (100.0*image->resolution.y/2.54);
   1092       break;
   1093     }
   1094     case PixelsPerCentimeterResolution:
   1095     {
   1096       dib_info.x_pixels=(size_t) (100.0*image->resolution.x);
   1097       dib_info.y_pixels=(size_t) (100.0*image->resolution.y);
   1098       break;
   1099     }
   1100   }
   1101   dib_info.colors_important=dib_info.number_colors;
   1102   /*
   1103     Convert MIFF to DIB raster pixels.
   1104   */
   1105   pixels=(unsigned char *) AcquireQuantumMemory(dib_info.image_size,
   1106     sizeof(*pixels));
   1107   if (pixels == (unsigned char *) NULL)
   1108     ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
   1109   (void) ResetMagickMemory(pixels,0,dib_info.image_size);
   1110   switch (dib_info.bits_per_pixel)
   1111   {
   1112     case 1:
   1113     {
   1114       register unsigned char
   1115         bit,
   1116         byte;
   1117 
   1118       /*
   1119         Convert PseudoClass image to a DIB monochrome image.
   1120       */
   1121       for (y=0; y < (ssize_t) image->rows; y++)
   1122       {
   1123         p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1124         if (p == (const Quantum *) NULL)
   1125           break;
   1126         q=pixels+(image->rows-y-1)*bytes_per_line;
   1127         bit=0;
   1128         byte=0;
   1129         for (x=0; x < (ssize_t) image->columns; x++)
   1130         {
   1131           byte<<=1;
   1132           byte|=GetPixelIndex(image,p) != 0 ? 0x01 : 0x00;
   1133           bit++;
   1134           if (bit == 8)
   1135             {
   1136               *q++=byte;
   1137               bit=0;
   1138               byte=0;
   1139             }
   1140            p+=GetPixelChannels(image);
   1141          }
   1142          if (bit != 0)
   1143            {
   1144              *q++=(unsigned char) (byte << (8-bit));
   1145              x++;
   1146            }
   1147         for (x=(ssize_t) (image->columns+7)/8; x < (ssize_t) bytes_per_line; x++)
   1148           *q++=0x00;
   1149         status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
   1150           image->rows);
   1151         if (status == MagickFalse)
   1152           break;
   1153       }
   1154       break;
   1155     }
   1156     case 8:
   1157     {
   1158       /*
   1159         Convert PseudoClass packet to DIB pixel.
   1160       */
   1161       for (y=0; y < (ssize_t) image->rows; y++)
   1162       {
   1163         p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1164         if (p == (const Quantum *) NULL)
   1165           break;
   1166         q=pixels+(image->rows-y-1)*bytes_per_line;
   1167         for (x=0; x < (ssize_t) image->columns; x++)
   1168         {
   1169           *q++=(unsigned char) GetPixelIndex(image,p);
   1170           p+=GetPixelChannels(image);
   1171         }
   1172         for ( ; x < (ssize_t) bytes_per_line; x++)
   1173           *q++=0x00;
   1174         status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
   1175           image->rows);
   1176         if (status == MagickFalse)
   1177           break;
   1178       }
   1179       break;
   1180     }
   1181     case 16:
   1182     {
   1183       unsigned short
   1184         word;
   1185       /*
   1186         Convert PseudoClass packet to DIB pixel.
   1187       */
   1188       for (y=0; y < (ssize_t) image->rows; y++)
   1189       {
   1190         p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1191         if (p == (const Quantum *) NULL)
   1192           break;
   1193         q=pixels+(image->rows-y-1)*bytes_per_line;
   1194         for (x=0; x < (ssize_t) image->columns; x++)
   1195         {
   1196           word=(unsigned short) ((ScaleColor8to5((unsigned char)
   1197             ScaleQuantumToChar(GetPixelRed(image,p))) << 11) | (ScaleColor8to6(
   1198             (unsigned char) ScaleQuantumToChar(GetPixelGreen(image,p))) << 5) |
   1199             (ScaleColor8to5((unsigned char) ScaleQuantumToChar((unsigned char)
   1200             GetPixelBlue(image,p)) << 0)));
   1201           *q++=(unsigned char)(word & 0xff);
   1202           *q++=(unsigned char)(word >> 8);
   1203           p+=GetPixelChannels(image);
   1204         }
   1205         for (x=(ssize_t) (2*image->columns); x < (ssize_t) bytes_per_line; x++)
   1206           *q++=0x00;
   1207         status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
   1208           image->rows);
   1209         if (status == MagickFalse)
   1210           break;
   1211       }
   1212       break;
   1213     }
   1214     case 24:
   1215     case 32:
   1216     {
   1217       /*
   1218         Convert DirectClass packet to DIB RGB pixel.
   1219       */
   1220       for (y=0; y < (ssize_t) image->rows; y++)
   1221       {
   1222         p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1223         if (p == (const Quantum *) NULL)
   1224           break;
   1225         q=pixels+(image->rows-y-1)*bytes_per_line;
   1226         for (x=0; x < (ssize_t) image->columns; x++)
   1227         {
   1228           *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
   1229           *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
   1230           *q++=ScaleQuantumToChar(GetPixelRed(image,p));
   1231           if (image->alpha_trait != UndefinedPixelTrait)
   1232             *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
   1233           p+=GetPixelChannels(image);
   1234         }
   1235         if (dib_info.bits_per_pixel == 24)
   1236           for (x=(ssize_t) (3*image->columns); x < (ssize_t) bytes_per_line; x++)
   1237             *q++=0x00;
   1238         status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
   1239           image->rows);
   1240         if (status == MagickFalse)
   1241           break;
   1242       }
   1243       break;
   1244     }
   1245   }
   1246   if (dib_info.bits_per_pixel == 8)
   1247     if (image_info->compression != NoCompression)
   1248       {
   1249         size_t
   1250           length;
   1251 
   1252         /*
   1253           Convert run-length encoded raster pixels.
   1254         */
   1255         length=2UL*(bytes_per_line+2UL)+2UL;
   1256         dib_data=(unsigned char *) AcquireQuantumMemory(length,
   1257           (image->rows+2UL)*sizeof(*dib_data));
   1258         if (dib_data == (unsigned char *) NULL)
   1259           {
   1260             pixels=(unsigned char *) RelinquishMagickMemory(pixels);
   1261             ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
   1262           }
   1263         dib_info.image_size=(size_t) EncodeImage(image,bytes_per_line,
   1264           pixels,dib_data);
   1265         pixels=(unsigned char *) RelinquishMagickMemory(pixels);
   1266         pixels=dib_data;
   1267         dib_info.compression = BI_RLE8;
   1268       }
   1269   /*
   1270     Write DIB header.
   1271   */
   1272   (void) WriteBlobLSBLong(image,(unsigned int) dib_info.size);
   1273   (void) WriteBlobLSBLong(image,dib_info.width);
   1274   (void) WriteBlobLSBLong(image,(unsigned short) dib_info.height);
   1275   (void) WriteBlobLSBShort(image,(unsigned short) dib_info.planes);
   1276   (void) WriteBlobLSBShort(image,dib_info.bits_per_pixel);
   1277   (void) WriteBlobLSBLong(image,(unsigned int) dib_info.compression);
   1278   (void) WriteBlobLSBLong(image,(unsigned int) dib_info.image_size);
   1279   (void) WriteBlobLSBLong(image,(unsigned int) dib_info.x_pixels);
   1280   (void) WriteBlobLSBLong(image,(unsigned int) dib_info.y_pixels);
   1281   (void) WriteBlobLSBLong(image,(unsigned int) dib_info.number_colors);
   1282   (void) WriteBlobLSBLong(image,(unsigned int) dib_info.colors_important);
   1283   if (image->storage_class == PseudoClass)
   1284     {
   1285       if (dib_info.bits_per_pixel <= 8)
   1286         {
   1287           unsigned char
   1288             *dib_colormap;
   1289 
   1290           /*
   1291             Dump colormap to file.
   1292           */
   1293           dib_colormap=(unsigned char *) AcquireQuantumMemory((size_t)
   1294             (1UL << dib_info.bits_per_pixel),4*sizeof(*dib_colormap));
   1295           if (dib_colormap == (unsigned char *) NULL)
   1296             ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
   1297           q=dib_colormap;
   1298           for (i=0; i < (ssize_t) MagickMin(image->colors,dib_info.number_colors); i++)
   1299           {
   1300             *q++=ScaleQuantumToChar(image->colormap[i].blue);
   1301             *q++=ScaleQuantumToChar(image->colormap[i].green);
   1302             *q++=ScaleQuantumToChar(image->colormap[i].red);
   1303             *q++=(Quantum) 0x0;
   1304           }
   1305           for ( ; i < (ssize_t) (1L << dib_info.bits_per_pixel); i++)
   1306           {
   1307             *q++=(Quantum) 0x0;
   1308             *q++=(Quantum) 0x0;
   1309             *q++=(Quantum) 0x0;
   1310             *q++=(Quantum) 0x0;
   1311           }
   1312           (void) WriteBlob(image,(size_t) (4*(1 << dib_info.bits_per_pixel)),
   1313             dib_colormap);
   1314           dib_colormap=(unsigned char *) RelinquishMagickMemory(dib_colormap);
   1315         }
   1316       else
   1317         if ((dib_info.bits_per_pixel == 16) &&
   1318             (dib_info.compression == BI_BITFIELDS))
   1319           {
   1320             (void) WriteBlobLSBLong(image,0xf800);
   1321             (void) WriteBlobLSBLong(image,0x07e0);
   1322             (void) WriteBlobLSBLong(image,0x001f);
   1323           }
   1324     }
   1325   (void) WriteBlob(image,dib_info.image_size,pixels);
   1326   pixels=(unsigned char *) RelinquishMagickMemory(pixels);
   1327   (void) CloseBlob(image);
   1328   return(MagickTrue);
   1329 }
   1330