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