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