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