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