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