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