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