]> granicus.if.org Git - imagemagick/blob - coders/bmp.c
(no commit message)
[imagemagick] / coders / bmp.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %                            BBBB   M   M  PPPP                               %
7 %                            B   B  MM MM  P   P                              %
8 %                            BBBB   M M M  PPPP                               %
9 %                            B   B  M   M  P                                  %
10 %                            BBBB   M   M  P                                  %
11 %                                                                             %
12 %                                                                             %
13 %             Read/Write Microsoft Windows Bitmap Image Format                %
14 %                                                                             %
15 %                              Software Design                                %
16 %                                John Cristy                                  %
17 %                            Glenn Randers-Pehrson                            %
18 %                               December 2001                                 %
19 %                                                                             %
20 %                                                                             %
21 %  Copyright 1999-2010 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 ssize_t
510     x;
511
512   register PixelPacket
513     *q;
514
515   register ssize_t
516     i;
517
518   register unsigned char
519     *p;
520
521   ssize_t
522     count;
523
524   size_t
525     length;
526
527   unsigned char
528     magick[12],
529     *pixels;
530
531   size_t
532     bit,
533     blue,
534     bytes_per_line,
535     green,
536     opacity,
537     red;
538
539   /*
540     Open image file.
541   */
542   assert(image_info != (const ImageInfo *) NULL);
543   assert(image_info->signature == MagickSignature);
544   if (image_info->debug != MagickFalse)
545     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
546       image_info->filename);
547   assert(exception != (ExceptionInfo *) NULL);
548   assert(exception->signature == MagickSignature);
549   image=AcquireImage(image_info);
550   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
551   if (status == MagickFalse)
552     {
553       image=DestroyImageList(image);
554       return((Image *) NULL);
555     }
556   /*
557     Determine if this a BMP file.
558   */
559   (void) ResetMagickMemory(&bmp_info,0,sizeof(bmp_info));
560   bmp_info.ba_offset=0;
561   start_position=0;
562   count=ReadBlob(image,2,magick);
563   do
564   {
565     LongPixelPacket
566       shift;
567
568     PixelPacket
569       quantum_bits;
570
571     size_t
572       profile_data,
573       profile_size;
574
575     /*
576       Verify BMP identifier.
577     */
578     if (bmp_info.ba_offset == 0)
579       start_position=TellBlob(image)-2;
580     bmp_info.ba_offset=0;
581     while (LocaleNCompare((char *) magick,"BA",2) == 0)
582     {
583       bmp_info.file_size=ReadBlobLSBLong(image);
584       bmp_info.ba_offset=ReadBlobLSBLong(image);
585       bmp_info.offset_bits=ReadBlobLSBLong(image);
586       count=ReadBlob(image,2,magick);
587       if (count != 2)
588         break;
589     }
590     if (image->debug != MagickFalse)
591       (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Magick: %c%c",
592         magick[0],magick[1]);
593     if ((count == 0) || ((LocaleNCompare((char *) magick,"BM",2) != 0) &&
594         (LocaleNCompare((char *) magick,"CI",2) != 0)))
595       ThrowReaderException(CorruptImageError,"ImproperImageHeader");
596     bmp_info.file_size=ReadBlobLSBLong(image);
597     (void) ReadBlobLSBLong(image);
598     bmp_info.offset_bits=ReadBlobLSBLong(image);
599     bmp_info.size=ReadBlobLSBLong(image);
600     if (image->debug != MagickFalse)
601       (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  BMP size: %u",
602         bmp_info.size);
603     if (bmp_info.size == 12)
604       {
605         /*
606           OS/2 BMP image file.
607         */
608         bmp_info.width=(short) ReadBlobLSBShort(image);
609         bmp_info.height=(short) ReadBlobLSBShort(image);
610         bmp_info.planes=ReadBlobLSBShort(image);
611         bmp_info.bits_per_pixel=ReadBlobLSBShort(image);
612         bmp_info.x_pixels=0;
613         bmp_info.y_pixels=0;
614         bmp_info.number_colors=0;
615         bmp_info.compression=BI_RGB;
616         bmp_info.image_size=0;
617         bmp_info.alpha_mask=0;
618         if (image->debug != MagickFalse)
619           {
620             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
621               "  Format: OS/2 Bitmap");
622             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
623               "  Geometry: %.20gx%.20g",(double) bmp_info.width,(double)
624               bmp_info.height);
625           }
626       }
627     else
628       {
629         /*
630           Microsoft Windows BMP image file.
631         */
632         if (bmp_info.size < 40)
633           ThrowReaderException(CorruptImageError,"NonOS2HeaderSizeError");
634         bmp_info.width=(int) ReadBlobLSBLong(image);
635         bmp_info.height=(int) ReadBlobLSBLong(image);
636         bmp_info.planes=ReadBlobLSBShort(image);
637         bmp_info.bits_per_pixel=ReadBlobLSBShort(image);
638         bmp_info.compression=ReadBlobLSBLong(image);
639         bmp_info.image_size=ReadBlobLSBLong(image);
640         bmp_info.x_pixels=ReadBlobLSBLong(image);
641         bmp_info.y_pixels=ReadBlobLSBLong(image);
642         bmp_info.number_colors=ReadBlobLSBLong(image);
643         bmp_info.colors_important=ReadBlobLSBLong(image);
644         profile_data=0;
645         profile_size=0;
646         if (image->debug != MagickFalse)
647           {
648             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
649               "  Format: MS Windows bitmap");
650             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
651               "  Geometry: %.20gx%.20g",(double) bmp_info.width,(double)
652               bmp_info.height);
653             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
654               "  Bits per pixel: %.20g",(double) bmp_info.bits_per_pixel);
655             switch ((int) bmp_info.compression)
656             {
657               case BI_RGB:
658               {
659                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
660                   "  Compression: BI_RGB");
661                 break;
662               }
663               case BI_RLE4:
664               {
665                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
666                   "  Compression: BI_RLE4");
667                 break;
668               }
669               case BI_RLE8:
670               {
671                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
672                   "  Compression: BI_RLE8");
673                 break;
674               }
675               case BI_BITFIELDS:
676               {
677                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
678                   "  Compression: BI_BITFIELDS");
679                 break;
680               }
681               case BI_PNG:
682               {
683                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
684                   "  Compression: BI_PNG");
685                 break;
686               }
687               case BI_JPEG:
688               {
689                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
690                   "  Compression: BI_JPEG");
691                 break;
692               }
693               default:
694               {
695                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
696                   "  Compression: UNKNOWN (%u)",bmp_info.compression);
697               }
698             }
699             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
700               "  Number of colors: %u",bmp_info.number_colors);
701           }
702         bmp_info.red_mask=ReadBlobLSBLong(image);
703         bmp_info.green_mask=ReadBlobLSBLong(image);
704         bmp_info.blue_mask=ReadBlobLSBLong(image);
705         if (bmp_info.size > 40)
706           {
707             double
708               sum;
709
710             /*
711               Read color management information.
712             */
713             bmp_info.alpha_mask=ReadBlobLSBLong(image);
714             bmp_info.colorspace=(int) ReadBlobLSBLong(image);
715             /*
716               Decode 2^30 fixed point formatted CIE primaries.
717             */
718             bmp_info.red_primary.x=(double) ReadBlobLSBLong(image)/0x3ffffff;
719             bmp_info.red_primary.y=(double) ReadBlobLSBLong(image)/0x3ffffff;
720             bmp_info.red_primary.z=(double) ReadBlobLSBLong(image)/0x3ffffff;
721             bmp_info.green_primary.x=(double) ReadBlobLSBLong(image)/0x3ffffff;
722             bmp_info.green_primary.y=(double) ReadBlobLSBLong(image)/0x3ffffff;
723             bmp_info.green_primary.z=(double) ReadBlobLSBLong(image)/0x3ffffff;
724             bmp_info.blue_primary.x=(double) ReadBlobLSBLong(image)/0x3ffffff;
725             bmp_info.blue_primary.y=(double) ReadBlobLSBLong(image)/0x3ffffff;
726             bmp_info.blue_primary.z=(double) ReadBlobLSBLong(image)/0x3ffffff;
727             sum=bmp_info.red_primary.x+bmp_info.red_primary.y+
728               bmp_info.red_primary.z;
729             image->chromaticity.red_primary.x/=sum;
730             image->chromaticity.red_primary.y/=sum;
731             sum=bmp_info.green_primary.x+bmp_info.green_primary.y+
732               bmp_info.green_primary.z;
733             image->chromaticity.green_primary.x/=sum;
734             image->chromaticity.green_primary.y/=sum;
735             sum=bmp_info.blue_primary.x+bmp_info.blue_primary.y+
736               bmp_info.blue_primary.z;
737             image->chromaticity.blue_primary.x/=sum;
738             image->chromaticity.blue_primary.y/=sum;
739             /*
740               Decode 16^16 fixed point formatted gamma_scales.
741             */
742             bmp_info.gamma_scale.x=(double) ReadBlobLSBLong(image)/0xffff;
743             bmp_info.gamma_scale.y=(double) ReadBlobLSBLong(image)/0xffff;
744             bmp_info.gamma_scale.z=(double) ReadBlobLSBLong(image)/0xffff;
745             /*
746               Compute a single gamma from the BMP 3-channel gamma.
747             */
748             image->gamma=(bmp_info.gamma_scale.x+bmp_info.gamma_scale.y+
749               bmp_info.gamma_scale.z)/3.0;
750           }
751         if (bmp_info.size > 108)
752           {
753             size_t
754               intent;
755
756             /*
757               Read BMP Version 5 color management information.
758             */
759             intent=ReadBlobLSBLong(image);
760             switch ((int) intent)
761             {
762               case LCS_GM_BUSINESS:
763               {
764                 image->rendering_intent=SaturationIntent;
765                 break;
766               }
767               case LCS_GM_GRAPHICS:
768               {
769                 image->rendering_intent=RelativeIntent;
770                 break;
771               }
772               case LCS_GM_IMAGES:
773               {
774                 image->rendering_intent=PerceptualIntent;
775                 break;
776               }
777               case LCS_GM_ABS_COLORIMETRIC:
778               {
779                 image->rendering_intent=AbsoluteIntent;
780                 break;
781               }
782             }
783             profile_data=ReadBlobLSBLong(image);
784             profile_size=ReadBlobLSBLong(image);
785             (void) ReadBlobLSBLong(image);  /* Reserved byte */
786           }
787       }
788     if ((bmp_info.compression != BI_RGB) &&
789         ((MagickSizeType) bmp_info.file_size != GetBlobSize(image)))
790       (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError,
791         "LengthAndFilesizeDoNotMatch","`%s'",image->filename);
792     if (bmp_info.width <= 0)
793       ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
794     if (bmp_info.height == 0)
795       ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
796     if (bmp_info.planes != 1)
797       ThrowReaderException(CorruptImageError,"StaticPlanesValueNotEqualToOne");
798     if ((bmp_info.bits_per_pixel != 1) && (bmp_info.bits_per_pixel != 4) &&
799         (bmp_info.bits_per_pixel != 8) && (bmp_info.bits_per_pixel != 16) &&
800         (bmp_info.bits_per_pixel != 24) && (bmp_info.bits_per_pixel != 32))
801       ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
802     if (bmp_info.number_colors > (1U << bmp_info.bits_per_pixel))
803       {
804         if (bmp_info.bits_per_pixel < 24)
805           ThrowReaderException(CorruptImageError,"UnrecognizedNumberOfColors");
806         bmp_info.number_colors=0;
807       }
808     if ((bmp_info.compression == 1) && (bmp_info.bits_per_pixel != 8))
809       ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
810     if ((bmp_info.compression == 2) && (bmp_info.bits_per_pixel != 4))
811       ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
812     if ((bmp_info.compression == 3) && (bmp_info.bits_per_pixel < 16))
813       ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
814     switch (bmp_info.compression)
815     {
816       case BI_RGB:
817       case BI_RLE8:
818       case BI_RLE4:
819       case BI_BITFIELDS:
820         break;
821       case BI_JPEG:
822         ThrowReaderException(CoderError,"JPEGCompressNotSupported");
823       case BI_PNG:
824         ThrowReaderException(CoderError,"PNGCompressNotSupported");
825       default:
826         ThrowReaderException(CorruptImageError,"UnrecognizedImageCompression");
827     }
828     image->columns=(size_t) MagickAbsoluteValue(bmp_info.width);
829     image->rows=(size_t) MagickAbsoluteValue(bmp_info.height);
830     image->depth=bmp_info.bits_per_pixel <= 8 ? bmp_info.bits_per_pixel : 8;
831     if ((bmp_info.bits_per_pixel == 16) ||
832         (bmp_info.bits_per_pixel == 32))
833       image->matte=bmp_info.alpha_mask != 0 ? MagickTrue : MagickFalse;
834     if ((bmp_info.number_colors != 0) || (bmp_info.bits_per_pixel < 16))
835       {
836         size_t
837           one;
838
839         image->storage_class=PseudoClass;
840         image->colors=bmp_info.number_colors;
841         one=1;
842         if (image->colors == 0)
843           image->colors=one << bmp_info.bits_per_pixel;
844       }
845     if (image->storage_class == PseudoClass)
846       {
847         unsigned char
848           *bmp_colormap;
849
850         size_t
851           packet_size;
852
853         /*
854           Read BMP raster colormap.
855         */
856         if (image->debug != MagickFalse)
857           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
858             "  Reading colormap of %.20g colors",(double) image->colors);
859         if (AcquireImageColormap(image,image->colors) == MagickFalse)
860           ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
861         bmp_colormap=(unsigned char *) AcquireQuantumMemory((size_t)
862           image->colors,4*sizeof(*bmp_colormap));
863         if (bmp_colormap == (unsigned char *) NULL)
864           ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
865         if ((bmp_info.size == 12) || (bmp_info.size == 64))
866           packet_size=3;
867         else
868           packet_size=4;
869         offset=SeekBlob(image,start_position+14+bmp_info.size,SEEK_SET);
870         if (offset < 0)
871           ThrowReaderException(CorruptImageError,"ImproperImageHeader");
872         count=ReadBlob(image,packet_size*image->colors,bmp_colormap);
873         if (count != (ssize_t) (packet_size*image->colors))
874           ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
875         p=bmp_colormap;
876         for (i=0; i < (ssize_t) image->colors; i++)
877         {
878           image->colormap[i].blue=ScaleCharToQuantum(*p++);
879           image->colormap[i].green=ScaleCharToQuantum(*p++);
880           image->colormap[i].red=ScaleCharToQuantum(*p++);
881           if (packet_size == 4)
882             p++;
883         }
884         bmp_colormap=(unsigned char *) RelinquishMagickMemory(bmp_colormap);
885       }
886     if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
887       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
888         break;
889     /*
890       Read image data.
891     */
892     offset=SeekBlob(image,start_position+bmp_info.offset_bits,SEEK_SET);
893     if (offset < 0)
894       ThrowReaderException(CorruptImageError,"ImproperImageHeader");
895     if (bmp_info.compression == BI_RLE4)
896       bmp_info.bits_per_pixel<<=1;
897     bytes_per_line=4*((image->columns*bmp_info.bits_per_pixel+31)/32);
898     length=(size_t) bytes_per_line*image->rows;
899     pixels=(unsigned char *) AcquireQuantumMemory((size_t) image->rows,
900       MagickMax(bytes_per_line,image->columns+256UL)*sizeof(*pixels));
901     if (pixels == (unsigned char *) NULL)
902       ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
903     if ((bmp_info.compression == BI_RGB) ||
904         (bmp_info.compression == BI_BITFIELDS))
905       {
906         if (image->debug != MagickFalse)
907           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
908             "  Reading pixels (%.20g bytes)",(double) length);
909         count=ReadBlob(image,length,pixels);
910         if (count != (ssize_t) length)
911           {
912             pixels=(unsigned char *) RelinquishMagickMemory(pixels);
913             ThrowReaderException(CorruptImageError,
914               "InsufficientImageDataInFile");
915           }
916       }
917     else
918       {
919         /*
920           Convert run-length encoded raster pixels.
921         */
922         status=DecodeImage(image,bmp_info.compression,pixels);
923         if (status == MagickFalse)
924           {
925             pixels=(unsigned char *) RelinquishMagickMemory(pixels);
926             ThrowReaderException(CorruptImageError,
927               "UnableToRunlengthDecodeImage");
928           }
929       }
930     /*
931       Initialize image structure.
932     */
933     image->x_resolution=(double) bmp_info.x_pixels/100.0;
934     image->y_resolution=(double) bmp_info.y_pixels/100.0;
935     image->units=PixelsPerCentimeterResolution;
936     /*
937       Convert BMP raster image to pixel packets.
938     */
939     if (bmp_info.compression == BI_RGB)
940       {
941         bmp_info.alpha_mask=0;
942         bmp_info.red_mask=0x00ff0000U;
943         bmp_info.green_mask=0x0000ff00U;
944         bmp_info.blue_mask=0x000000ffU;
945         if (bmp_info.bits_per_pixel == 16)
946           {
947             /*
948               RGB555.
949             */
950             bmp_info.red_mask=0x00007c00U;
951             bmp_info.green_mask=0x000003e0U;
952             bmp_info.blue_mask=0x0000001fU;
953           }
954       }
955     if ((bmp_info.bits_per_pixel == 16) || (bmp_info.bits_per_pixel == 32))
956       {
957         register size_t
958           sample;
959
960         /*
961           Get shift and quantum bits info from bitfield masks.
962         */
963         (void) ResetMagickMemory(&shift,0,sizeof(shift));
964         (void) ResetMagickMemory(&quantum_bits,0,sizeof(quantum_bits));
965         if (bmp_info.red_mask != 0)
966           while (((bmp_info.red_mask << shift.red) & 0x80000000UL) == 0)
967             shift.red++;
968         if (bmp_info.green_mask != 0)
969           while (((bmp_info.green_mask << shift.green) & 0x80000000UL) == 0)
970             shift.green++;
971         if (bmp_info.blue_mask != 0)
972           while (((bmp_info.blue_mask << shift.blue) & 0x80000000UL) == 0)
973             shift.blue++;
974         if (bmp_info.alpha_mask != 0)
975           while (((bmp_info.alpha_mask << shift.opacity) & 0x80000000UL) == 0)
976             shift.opacity++;
977         sample=shift.red;
978         while (((bmp_info.red_mask << sample) & 0x80000000UL) != 0)
979           sample++;
980         quantum_bits.red=(Quantum) (sample-shift.red);
981         sample=shift.green;
982         while (((bmp_info.green_mask << sample) & 0x80000000UL) != 0)
983           sample++;
984         quantum_bits.green=(Quantum) (sample-shift.green);
985         sample=shift.blue;
986         while (((bmp_info.blue_mask << sample) & 0x80000000UL) != 0)
987           sample++;
988         quantum_bits.blue=(Quantum) (sample-shift.blue);
989         sample=shift.opacity;
990         while (((bmp_info.alpha_mask << sample) & 0x80000000UL) != 0)
991           sample++;
992         quantum_bits.opacity=(Quantum) (sample-shift.opacity);
993       }
994     switch (bmp_info.bits_per_pixel)
995     {
996       case 1:
997       {
998         /*
999           Convert bitmap scanline.
1000         */
1001         for (y=(ssize_t) image->rows-1; y >= 0; y--)
1002         {
1003           p=pixels+(image->rows-y-1)*bytes_per_line;
1004           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
1005           if (q == (PixelPacket *) NULL)
1006             break;
1007           indexes=GetAuthenticIndexQueue(image);
1008           for (x=0; x < ((ssize_t) image->columns-7); x+=8)
1009           {
1010             for (bit=0; bit < 8; bit++)
1011             {
1012               index=(IndexPacket) (((*p) & (0x80 >> bit)) != 0 ? 0x01 : 0x00);
1013               indexes[x+bit]=index;
1014               *q++=image->colormap[(ssize_t) index];
1015             }
1016             p++;
1017           }
1018           if ((image->columns % 8) != 0)
1019             {
1020               for (bit=0; bit < (image->columns % 8); bit++)
1021               {
1022                 index=(IndexPacket) (((*p) & (0x80 >> bit)) != 0 ? 0x01 : 0x00);
1023                 indexes[x+bit]=index;
1024                 *q++=image->colormap[(ssize_t) index];
1025               }
1026               p++;
1027             }
1028           if (SyncAuthenticPixels(image,exception) == MagickFalse)
1029             break;
1030           if (image->previous == (Image *) NULL)
1031             {
1032               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
1033                 image->rows);
1034               if (status == MagickFalse)
1035                 break;
1036             }
1037         }
1038         break;
1039       }
1040       case 4:
1041       {
1042         /*
1043           Convert PseudoColor scanline.
1044         */
1045         for (y=(ssize_t) image->rows-1; y >= 0; y--)
1046         {
1047           p=pixels+(image->rows-y-1)*bytes_per_line;
1048           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
1049           if (q == (PixelPacket *) NULL)
1050             break;
1051           indexes=GetAuthenticIndexQueue(image);
1052           for (x=0; x < ((ssize_t) image->columns-1); x+=2)
1053           {
1054             index=ConstrainColormapIndex(image,(*p >> 4) & 0x0f);
1055             indexes[x]=index;
1056             *q++=image->colormap[(ssize_t) index];
1057             index=ConstrainColormapIndex(image,*p & 0x0f);
1058             indexes[x+1]=index;
1059             *q++=image->colormap[(ssize_t) index];
1060             p++;
1061           }
1062           if ((image->columns % 2) != 0)
1063             {
1064               index=ConstrainColormapIndex(image,(*p >> 4) & 0xf);
1065               indexes[x]=index;
1066               *q++=image->colormap[(ssize_t) index];
1067               p++;
1068             }
1069           if (SyncAuthenticPixels(image,exception) == MagickFalse)
1070             break;
1071           if (image->previous == (Image *) NULL)
1072             {
1073               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
1074                 image->rows);
1075               if (status == MagickFalse)
1076                 break;
1077             }
1078         }
1079         break;
1080       }
1081       case 8:
1082       {
1083         /*
1084           Convert PseudoColor scanline.
1085         */
1086         if ((bmp_info.compression == BI_RLE8) ||
1087             (bmp_info.compression == BI_RLE4))
1088           bytes_per_line=image->columns;
1089         for (y=(ssize_t) image->rows-1; y >= 0; y--)
1090         {
1091           p=pixels+(image->rows-y-1)*bytes_per_line;
1092           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
1093           if (q == (PixelPacket *) NULL)
1094             break;
1095           indexes=GetAuthenticIndexQueue(image);
1096           for (x = (ssize_t)image->columns; x != 0; --x)
1097           {
1098             index=ConstrainColormapIndex(image,*p);
1099             *indexes++=index;
1100             *q=image->colormap[(ssize_t) index];
1101             p++;
1102             q++;
1103           }
1104           if (SyncAuthenticPixels(image,exception) == MagickFalse)
1105             break;
1106           offset=(MagickOffsetType) (image->rows-y-1);
1107           if (image->previous == (Image *) NULL)
1108             {
1109               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
1110                 image->rows);
1111               if (status == MagickFalse)
1112                 break;
1113             }
1114         }
1115         break;
1116       }
1117       case 16:
1118       {
1119         size_t
1120           pixel;
1121
1122         /*
1123           Convert bitfield encoded 16-bit PseudoColor scanline.
1124         */
1125         if (bmp_info.compression != BI_RGB &&
1126             bmp_info.compression != BI_BITFIELDS)
1127           {
1128             pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1129             ThrowReaderException(CorruptImageError,
1130               "UnrecognizedImageCompression");
1131           }
1132         bytes_per_line=2*(image->columns+image->columns % 2);
1133         image->storage_class=DirectClass;
1134         for (y=(ssize_t) image->rows-1; y >= 0; y--)
1135         {
1136           p=pixels+(image->rows-y-1)*bytes_per_line;
1137           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
1138           if (q == (PixelPacket *) NULL)
1139             break;
1140           for (x=0; x < (ssize_t) image->columns; x++)
1141           {
1142             pixel=(size_t) (*p++);
1143             pixel|=(*p++) << 8;
1144             red=((pixel & bmp_info.red_mask) << shift.red) >> 16;
1145             if (quantum_bits.red == 5)
1146               red|=((red & 0xe000) >> 5);
1147             if (quantum_bits.red <= 8)
1148               red|=((red & 0xff00) >> 8);
1149             green=((pixel & bmp_info.green_mask) << shift.green) >> 16;
1150             if (quantum_bits.green == 5)
1151               green|=((green & 0xe000) >> 5);
1152             if (quantum_bits.green == 6)
1153               green|=((green & 0xc000) >> 6);
1154             if (quantum_bits.green <= 8)
1155               green|=((green & 0xff00) >> 8);
1156             blue=((pixel & bmp_info.blue_mask) << shift.blue) >> 16;
1157             if (quantum_bits.blue == 5)
1158               blue|=((blue & 0xe000) >> 5);
1159             if (quantum_bits.blue <= 8)
1160               blue|=((blue & 0xff00) >> 8);
1161             opacity=((pixel & bmp_info.alpha_mask) << shift.opacity) >> 16;
1162             if (quantum_bits.opacity <= 8)
1163               opacity|=((opacity & 0xff00) >> 8);
1164             q->red=ScaleShortToQuantum((unsigned short) red);
1165             q->green=ScaleShortToQuantum((unsigned short) green);
1166             q->blue=ScaleShortToQuantum((unsigned short) blue);
1167             SetOpacityPixelComponent(q,OpaqueOpacity);
1168             if (image->matte != MagickFalse)
1169               q->opacity=ScaleShortToQuantum((unsigned short) (65535-opacity));
1170             q++;
1171           }
1172           if (SyncAuthenticPixels(image,exception) == MagickFalse)
1173             break;
1174           offset=(MagickOffsetType) (image->rows-y-1);
1175           if (image->previous == (Image *) NULL)
1176             {
1177               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
1178                 image->rows);
1179               if (status == MagickFalse)
1180                 break;
1181             }
1182         }
1183         break;
1184       }
1185       case 24:
1186       {
1187         /*
1188           Convert DirectColor scanline.
1189         */
1190         bytes_per_line=4*((image->columns*24+31)/32);
1191         for (y=(ssize_t) image->rows-1; y >= 0; y--)
1192         {
1193           p=pixels+(image->rows-y-1)*bytes_per_line;
1194           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
1195           if (q == (PixelPacket *) NULL)
1196             break;
1197           for (x=0; x < (ssize_t) image->columns; x++)
1198           {
1199             q->blue=ScaleCharToQuantum(*p++);
1200             q->green=ScaleCharToQuantum(*p++);
1201             q->red=ScaleCharToQuantum(*p++);
1202             SetOpacityPixelComponent(q,OpaqueOpacity);
1203             q++;
1204           }
1205           if (SyncAuthenticPixels(image,exception) == MagickFalse)
1206             break;
1207           offset=(MagickOffsetType) (image->rows-y-1);
1208           if (image->previous == (Image *) NULL)
1209             {
1210               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
1211                 image->rows);
1212               if (status == MagickFalse)
1213                 break;
1214             }
1215         }
1216         break;
1217       }
1218       case 32:
1219       {
1220         /*
1221           Convert bitfield encoded DirectColor scanline.
1222         */
1223         if ((bmp_info.compression != BI_RGB) &&
1224             (bmp_info.compression != BI_BITFIELDS))
1225           {
1226             pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1227             ThrowReaderException(CorruptImageError,
1228               "UnrecognizedImageCompression");
1229           }
1230         bytes_per_line=4*(image->columns);
1231         for (y=(ssize_t) image->rows-1; y >= 0; y--)
1232         {
1233           size_t
1234             pixel;
1235
1236           p=pixels+(image->rows-y-1)*bytes_per_line;
1237           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
1238           if (q == (PixelPacket *) NULL)
1239             break;
1240           for (x=0; x < (ssize_t) image->columns; x++)
1241           {
1242             pixel=(size_t) (*p++);
1243             pixel|=(*p++ << 8);
1244             pixel|=(*p++ << 16);
1245             pixel|=(*p++ << 24);
1246             red=((pixel & bmp_info.red_mask) << shift.red) >> 16;
1247             if (quantum_bits.red == 8)
1248               red|=(red >> 8);
1249             green=((pixel & bmp_info.green_mask) << shift.green) >> 16;
1250             if (quantum_bits.green == 8)
1251               green|=(green >> 8);
1252             blue=((pixel & bmp_info.blue_mask) << shift.blue) >> 16;
1253             if (quantum_bits.blue == 8)
1254               blue|=(blue >> 8);
1255             opacity=((pixel & bmp_info.alpha_mask) << shift.opacity) >> 16;
1256             if (quantum_bits.opacity == 8)
1257               opacity|=(opacity >> 8);
1258             q->red=ScaleShortToQuantum((unsigned short) red);
1259             q->green=ScaleShortToQuantum((unsigned short) green);
1260             q->blue=ScaleShortToQuantum((unsigned short) blue);
1261             SetOpacityPixelComponent(q,OpaqueOpacity);
1262             if (image->matte != MagickFalse)
1263               q->opacity=ScaleShortToQuantum((unsigned short) (65535-opacity));
1264             q++;
1265           }
1266           if (SyncAuthenticPixels(image,exception) == MagickFalse)
1267             break;
1268           offset=(MagickOffsetType) (image->rows-y-1);
1269           if (image->previous == (Image *) NULL)
1270             {
1271               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
1272                 image->rows);
1273               if (status == MagickFalse)
1274                 break;
1275             }
1276         }
1277         break;
1278       }
1279       default:
1280       {
1281         pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1282         ThrowReaderException(CorruptImageError,"ImproperImageHeader");
1283       }
1284     }
1285     pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1286     if (EOFBlob(image) != MagickFalse)
1287       {
1288         ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
1289           image->filename);
1290         break;
1291       }
1292     if (bmp_info.height < 0)
1293       {
1294         Image
1295           *flipped_image;
1296
1297         /*
1298           Correct image orientation.
1299         */
1300         flipped_image=FlipImage(image,exception);
1301         if (flipped_image != (Image *) NULL)
1302           {
1303             DuplicateBlob(flipped_image,image);
1304             image=DestroyImage(image);
1305             image=flipped_image;
1306           }
1307       }
1308     /*
1309       Proceed to next image.
1310     */
1311     if (image_info->number_scenes != 0)
1312       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1313         break;
1314     *magick='\0';
1315     if (bmp_info.ba_offset != 0)
1316       {
1317         offset=SeekBlob(image,(MagickOffsetType) bmp_info.ba_offset,SEEK_SET);
1318         if (offset < 0)
1319           ThrowReaderException(CorruptImageError,"ImproperImageHeader");
1320       }
1321     count=ReadBlob(image,2,magick);
1322     if ((count == 2) && (IsBMP(magick,2) != MagickFalse))
1323       {
1324         /*
1325           Acquire next image structure.
1326         */
1327         AcquireNextImage(image_info,image);
1328         if (GetNextImageInList(image) == (Image *) NULL)
1329           {
1330             image=DestroyImageList(image);
1331             return((Image *) NULL);
1332           }
1333         image=SyncNextImageInList(image);
1334         status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
1335           GetBlobSize(image));
1336         if (status == MagickFalse)
1337           break;
1338       }
1339   } while (IsBMP(magick,2) != MagickFalse);
1340   (void) CloseBlob(image);
1341   return(GetFirstImageInList(image));
1342 }
1343 \f
1344 /*
1345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1346 %                                                                             %
1347 %                                                                             %
1348 %                                                                             %
1349 %   R e g i s t e r B M P I m a g e                                           %
1350 %                                                                             %
1351 %                                                                             %
1352 %                                                                             %
1353 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1354 %
1355 %  RegisterBMPImage() adds attributes for the BMP image format to
1356 %  the list of supported formats.  The attributes include the image format
1357 %  tag, a method to read and/or write the format, whether the format
1358 %  supports the saving of more than one frame to the same file or blob,
1359 %  whether the format supports native in-memory I/O, and a brief
1360 %  description of the format.
1361 %
1362 %  The format of the RegisterBMPImage method is:
1363 %
1364 %      size_t RegisterBMPImage(void)
1365 %
1366 */
1367 ModuleExport size_t RegisterBMPImage(void)
1368 {
1369   MagickInfo
1370     *entry;
1371
1372   entry=SetMagickInfo("BMP");
1373   entry->decoder=(DecodeImageHandler *) ReadBMPImage;
1374   entry->encoder=(EncodeImageHandler *) WriteBMPImage;
1375   entry->magick=(IsImageFormatHandler *) IsBMP;
1376   entry->description=ConstantString("Microsoft Windows bitmap image");
1377   entry->module=ConstantString("BMP");
1378   entry->adjoin=MagickFalse;
1379   entry->seekable_stream=MagickTrue;
1380   (void) RegisterMagickInfo(entry);
1381   entry=SetMagickInfo("BMP2");
1382   entry->encoder=(EncodeImageHandler *) WriteBMPImage;
1383   entry->magick=(IsImageFormatHandler *) IsBMP;
1384   entry->description=ConstantString("Microsoft Windows bitmap image (V2)");
1385   entry->module=ConstantString("BMP");
1386   entry->adjoin=MagickFalse;
1387   entry->seekable_stream=MagickTrue;
1388   (void) RegisterMagickInfo(entry);
1389   entry=SetMagickInfo("BMP3");
1390   entry->encoder=(EncodeImageHandler *) WriteBMPImage;
1391   entry->magick=(IsImageFormatHandler *) IsBMP;
1392   entry->description=ConstantString("Microsoft Windows bitmap image (V3)");
1393   entry->module=ConstantString("BMP");
1394   entry->adjoin=MagickFalse;
1395   entry->seekable_stream=MagickTrue;
1396   (void) RegisterMagickInfo(entry);
1397   return(MagickImageCoderSignature);
1398 }
1399 \f
1400 /*
1401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1402 %                                                                             %
1403 %                                                                             %
1404 %                                                                             %
1405 %   U n r e g i s t e r B M P I m a g e                                       %
1406 %                                                                             %
1407 %                                                                             %
1408 %                                                                             %
1409 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1410 %
1411 %  UnregisterBMPImage() removes format registrations made by the
1412 %  BMP module from the list of supported formats.
1413 %
1414 %  The format of the UnregisterBMPImage method is:
1415 %
1416 %      UnregisterBMPImage(void)
1417 %
1418 */
1419 ModuleExport void UnregisterBMPImage(void)
1420 {
1421   (void) UnregisterMagickInfo("BMP");
1422   (void) UnregisterMagickInfo("BMP2");
1423   (void) UnregisterMagickInfo("BMP3");
1424 }
1425 \f
1426 /*
1427 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1428 %                                                                             %
1429 %                                                                             %
1430 %                                                                             %
1431 %   W r i t e B M P I m a g e                                                 %
1432 %                                                                             %
1433 %                                                                             %
1434 %                                                                             %
1435 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1436 %
1437 %  WriteBMPImage() writes an image in Microsoft Windows bitmap encoded
1438 %  image format, version 3 for Windows or (if the image has a matte channel)
1439 %  version 4.
1440 %
1441 %  The format of the WriteBMPImage method is:
1442 %
1443 %      MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image)
1444 %
1445 %  A description of each parameter follows.
1446 %
1447 %    o image_info: the image info.
1448 %
1449 %    o image:  The image.
1450 %
1451 */
1452 static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image)
1453 {
1454   BMPInfo
1455     bmp_info;
1456
1457   const StringInfo
1458     *profile;
1459
1460   ssize_t
1461     y;
1462
1463   MagickBooleanType
1464     have_color_info,
1465     status;
1466
1467   MagickOffsetType
1468     scene;
1469
1470   register const IndexPacket
1471     *indexes;
1472
1473   register const PixelPacket
1474     *p;
1475
1476   register ssize_t
1477     i,
1478     x;
1479
1480   register unsigned char
1481     *q;
1482
1483   unsigned char
1484     *bmp_data,
1485     *pixels;
1486
1487   size_t
1488     bytes_per_line,
1489     type;
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   status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
1501   if (status == MagickFalse)
1502     return(status);
1503   type=4;
1504   if (LocaleCompare(image_info->magick,"BMP2") == 0)
1505     type=2;
1506   else
1507     if (LocaleCompare(image_info->magick,"BMP3") == 0)
1508       type=3;
1509   scene=0;
1510   do
1511   {
1512     /*
1513       Initialize BMP raster file header.
1514     */
1515     if (image->colorspace != RGBColorspace)
1516       (void) TransformImageColorspace(image,RGBColorspace);
1517     (void) ResetMagickMemory(&bmp_info,0,sizeof(bmp_info));
1518     bmp_info.file_size=14+12;
1519     if (type > 2)
1520       bmp_info.file_size+=28;
1521     bmp_info.offset_bits=bmp_info.file_size;
1522     bmp_info.compression=BI_RGB;
1523     if ((image->storage_class == PseudoClass) && (image->colors > 256))
1524       (void) SetImageStorageClass(image,DirectClass);
1525     if (image->storage_class != DirectClass)
1526       {
1527         /*
1528           Colormapped BMP raster.
1529         */
1530         bmp_info.bits_per_pixel=8;
1531         if (image->colors <= 2)
1532           bmp_info.bits_per_pixel=1;
1533         else
1534           if (image->colors <= 16)
1535             bmp_info.bits_per_pixel=4;
1536           else
1537             if (image->colors <= 256)
1538               bmp_info.bits_per_pixel=8;
1539         if (image_info->compression == RLECompression)
1540           bmp_info.bits_per_pixel=8;
1541         bmp_info.number_colors=1U << bmp_info.bits_per_pixel;
1542         if (image->matte != MagickFalse)
1543           (void) SetImageStorageClass(image,DirectClass);
1544         else
1545           if ((size_t) bmp_info.number_colors < image->colors)
1546             (void) SetImageStorageClass(image,DirectClass);
1547           else
1548             {
1549               bmp_info.file_size+=3*(1UL << bmp_info.bits_per_pixel);
1550               bmp_info.offset_bits+=3*(1UL << bmp_info.bits_per_pixel);
1551               if (type > 2)
1552                 {
1553                   bmp_info.file_size+=(1UL << bmp_info.bits_per_pixel);
1554                   bmp_info.offset_bits+=(1UL << bmp_info.bits_per_pixel);
1555                 }
1556             }
1557       }
1558     if (image->storage_class == DirectClass)
1559       {
1560         /*
1561           Full color BMP raster.
1562         */
1563         bmp_info.number_colors=0;
1564         bmp_info.bits_per_pixel=(unsigned short)
1565           ((type > 3) && (image->matte != MagickFalse) ? 32 : 24);
1566         bmp_info.compression=(unsigned int) ((type > 3) &&
1567           (image->matte != MagickFalse) ?  BI_BITFIELDS : BI_RGB);
1568       }
1569     bytes_per_line=4*((image->columns*bmp_info.bits_per_pixel+31)/32);
1570     bmp_info.ba_offset=0;
1571     profile=GetImageProfile(image,"icc");
1572     have_color_info=(image->rendering_intent != UndefinedIntent) ||
1573       (profile != (StringInfo *) NULL) || (image->gamma != 0.0) ?  MagickTrue :
1574       MagickFalse;
1575     if (type == 2)
1576       bmp_info.size=12;
1577     else
1578       if ((type == 3) || ((image->matte == MagickFalse) &&
1579           (have_color_info == MagickFalse)))
1580         {
1581           type=3;
1582           bmp_info.size=40;
1583         }
1584       else
1585         {
1586           int
1587             extra_size;
1588
1589           bmp_info.size=108;
1590           extra_size=68;
1591           if ((image->rendering_intent != UndefinedIntent) ||
1592               (profile != (StringInfo *) NULL))
1593             {
1594               bmp_info.size=124;
1595               extra_size+=16;
1596             }
1597           bmp_info.file_size+=extra_size;
1598           bmp_info.offset_bits+=extra_size;
1599         }
1600     bmp_info.width=(ssize_t) image->columns;
1601     bmp_info.height=(ssize_t) image->rows;
1602     bmp_info.planes=1;
1603     bmp_info.image_size=(unsigned int) (bytes_per_line*image->rows);
1604     bmp_info.file_size+=bmp_info.image_size;
1605     bmp_info.x_pixels=75*39;
1606     bmp_info.y_pixels=75*39;
1607     switch (image->units)
1608     {
1609       case UndefinedResolution:
1610       case PixelsPerInchResolution:
1611       {
1612         bmp_info.x_pixels=(unsigned int) (100.0*image->x_resolution/2.54);
1613         bmp_info.y_pixels=(unsigned int) (100.0*image->y_resolution/2.54);
1614         break;
1615       }
1616       case PixelsPerCentimeterResolution:
1617       {
1618         bmp_info.x_pixels=(unsigned int) (100.0*image->x_resolution);
1619         bmp_info.y_pixels=(unsigned int) (100.0*image->y_resolution);
1620         break;
1621       }
1622     }
1623     bmp_info.colors_important=bmp_info.number_colors;
1624     /*
1625       Convert MIFF to BMP raster pixels.
1626     */
1627     pixels=(unsigned char *) AcquireQuantumMemory((size_t) bmp_info.image_size,
1628       sizeof(*pixels));
1629     if (pixels == (unsigned char *) NULL)
1630       ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1631     (void) ResetMagickMemory(pixels,0,(size_t) bmp_info.image_size);
1632     switch (bmp_info.bits_per_pixel)
1633     {
1634       case 1:
1635       {
1636         size_t
1637           bit,
1638           byte;
1639
1640         /*
1641           Convert PseudoClass image to a BMP monochrome image.
1642         */
1643         for (y=0; y < (ssize_t) image->rows; y++)
1644         {
1645           p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1646           if (p == (const PixelPacket *) NULL)
1647             break;
1648           indexes=GetVirtualIndexQueue(image);
1649           q=pixels+(image->rows-y-1)*bytes_per_line;
1650           bit=0;
1651           byte=0;
1652           for (x=0; x < (ssize_t) image->columns; x++)
1653           {
1654             byte<<=1;
1655             byte|=indexes[x] != 0 ? 0x01 : 0x00;
1656             bit++;
1657             if (bit == 8)
1658               {
1659                 *q++=(unsigned char) byte;
1660                 bit=0;
1661                 byte=0;
1662               }
1663            }
1664            if (bit != 0)
1665              {
1666                *q++=(unsigned char) (byte << (8-bit));
1667                x++;
1668              }
1669           for (x=(ssize_t) (image->columns+7)/8; x < (ssize_t) bytes_per_line; x++)
1670             *q++=0x00;
1671           if (image->previous == (Image *) NULL)
1672             {
1673               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1674                 image->rows);
1675               if (status == MagickFalse)
1676                 break;
1677             }
1678         }
1679         break;
1680       }
1681       case 4:
1682       {
1683         size_t
1684           nibble,
1685           byte;
1686
1687         /*
1688           Convert PseudoClass image to a BMP monochrome image.
1689         */
1690         for (y=0; y < (ssize_t) image->rows; y++)
1691         {
1692           p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1693           if (p == (const PixelPacket *) NULL)
1694             break;
1695           indexes=GetVirtualIndexQueue(image);
1696           q=pixels+(image->rows-y-1)*bytes_per_line;
1697           nibble=0;
1698           byte=0;
1699           for (x=0; x < (ssize_t) image->columns; x++)
1700           {
1701             byte<<=4;
1702             byte|=((size_t) indexes[x] & 0x0f);
1703             nibble++;
1704             if (nibble == 2)
1705               {
1706                 *q++=(unsigned char) byte;
1707                 nibble=0;
1708                 byte=0;
1709               }
1710            }
1711          if (nibble != 0)
1712            {
1713              *q++=(unsigned char) (byte << 4);
1714              x++;
1715            }
1716           for (x=(ssize_t) (image->columns+1)/2; x < (ssize_t) bytes_per_line; x++)
1717             *q++=0x00;
1718           if (image->previous == (Image *) NULL)
1719             {
1720               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1721                 image->rows);
1722               if (status == MagickFalse)
1723                 break;
1724             }
1725         }
1726         break;
1727       }
1728       case 8:
1729       {
1730         /*
1731           Convert PseudoClass packet to BMP pixel.
1732         */
1733         for (y=0; y < (ssize_t) image->rows; y++)
1734         {
1735           p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1736           if (p == (const PixelPacket *) NULL)
1737             break;
1738           indexes=GetVirtualIndexQueue(image);
1739           q=pixels+(image->rows-y-1)*bytes_per_line;
1740           for (x=0; x < (ssize_t) image->columns; x++)
1741             *q++=(unsigned char) indexes[x];
1742           for ( ; x < (ssize_t) bytes_per_line; x++)
1743             *q++=0x00;
1744           if (image->previous == (Image *) NULL)
1745             {
1746               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1747                 image->rows);
1748               if (status == MagickFalse)
1749                 break;
1750             }
1751         }
1752         break;
1753       }
1754       case 24:
1755       {
1756         /*
1757           Convert DirectClass packet to BMP BGR888.
1758         */
1759         for (y=0; y < (ssize_t) image->rows; y++)
1760         {
1761           p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1762           if (p == (const PixelPacket *) NULL)
1763             break;
1764           q=pixels+(image->rows-y-1)*bytes_per_line;
1765           for (x=0; x < (ssize_t) image->columns; x++)
1766           {
1767             *q++=ScaleQuantumToChar(GetBluePixelComponent(p));
1768             *q++=ScaleQuantumToChar(GetGreenPixelComponent(p));
1769             *q++=ScaleQuantumToChar(GetRedPixelComponent(p));
1770             p++;
1771           }
1772           for (x=3L*(ssize_t) image->columns; x < (ssize_t) bytes_per_line; x++)
1773             *q++=0x00;
1774           if (image->previous == (Image *) NULL)
1775             {
1776               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1777                 image->rows);
1778               if (status == MagickFalse)
1779                 break;
1780             }
1781         }
1782         break;
1783       }
1784       case 32:
1785       {
1786         /*
1787           Convert DirectClass packet to ARGB8888 pixel.
1788         */
1789         for (y=0; y < (ssize_t) image->rows; y++)
1790         {
1791           p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1792           if (p == (const PixelPacket *) NULL)
1793             break;
1794           q=pixels+(image->rows-y-1)*bytes_per_line;
1795           for (x=0; x < (ssize_t) image->columns; x++)
1796           {
1797             *q++=ScaleQuantumToChar(GetBluePixelComponent(p));
1798             *q++=ScaleQuantumToChar(GetGreenPixelComponent(p));
1799             *q++=ScaleQuantumToChar(GetRedPixelComponent(p));
1800             *q++=ScaleQuantumToChar(QuantumRange-GetOpacityPixelComponent(p));
1801             p++;
1802           }
1803           if (image->previous == (Image *) NULL)
1804             {
1805               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1806                 image->rows);
1807               if (status == MagickFalse)
1808                 break;
1809             }
1810         }
1811         break;
1812       }
1813     }
1814     if ((type > 2) && (bmp_info.bits_per_pixel == 8))
1815       if (image_info->compression != NoCompression)
1816         {
1817           size_t
1818             length;
1819
1820           /*
1821             Convert run-length encoded raster pixels.
1822           */
1823           length=(size_t) (2*(bytes_per_line+2)*(image->rows+2)+2);
1824           bmp_data=(unsigned char *) NULL;
1825           if (~length >= bytes_per_line)
1826             bmp_data=(unsigned char *) AcquireQuantumMemory(length+
1827               bytes_per_line,sizeof(*bmp_data));
1828           if (bmp_data == (unsigned char *) NULL)
1829             {
1830               pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1831               ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1832             }
1833           bmp_info.file_size-=bmp_info.image_size;
1834           bmp_info.image_size=(unsigned int) EncodeImage(image,bytes_per_line,
1835             pixels,bmp_data);
1836           bmp_info.file_size+=bmp_info.image_size;
1837           pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1838           pixels=bmp_data;
1839           bmp_info.compression=BI_RLE8;
1840         }
1841     /*
1842       Write BMP for Windows, all versions, 14-byte header.
1843     */
1844     if (image->debug != MagickFalse)
1845       {
1846         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1847           "   Writing BMP version %.20g datastream",(double) type);
1848         if (image->storage_class == DirectClass)
1849           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1850             "   Storage class=DirectClass");
1851         else
1852           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1853             "   Storage class=PseudoClass");
1854         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1855           "   Image depth=%.20g",(double) image->depth);
1856         if (image->matte != MagickFalse)
1857           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1858             "   Matte=True");
1859         else
1860           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1861             "   Matte=MagickFalse");
1862         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1863           "   BMP bits_per_pixel=%.20g",(double) bmp_info.bits_per_pixel);
1864         switch ((int) bmp_info.compression)
1865         {
1866            case BI_RGB:
1867            {
1868              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1869                "   Compression=BI_RGB");
1870              break;
1871            }
1872            case BI_RLE8:
1873            {
1874              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1875                "   Compression=BI_RLE8");
1876              break;
1877            }
1878            case BI_BITFIELDS:
1879            {
1880              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1881                "   Compression=BI_BITFIELDS");
1882              break;
1883            }
1884            default:
1885            {
1886              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1887                "   Compression=UNKNOWN (%u)",bmp_info.compression);
1888              break;
1889            }
1890         }
1891         if (bmp_info.number_colors == 0)
1892           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1893             "   Number_colors=unspecified");
1894         else
1895           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1896             "   Number_colors=%u",bmp_info.number_colors);
1897       }
1898     (void) WriteBlob(image,2,(unsigned char *) "BM");
1899     (void) WriteBlobLSBLong(image,bmp_info.file_size);
1900     (void) WriteBlobLSBLong(image,bmp_info.ba_offset);  /* always 0 */
1901     (void) WriteBlobLSBLong(image,bmp_info.offset_bits);
1902     if (type == 2)
1903       {
1904         /*
1905           Write 12-byte version 2 bitmap header.
1906         */
1907         (void) WriteBlobLSBLong(image,bmp_info.size);
1908         (void) WriteBlobLSBShort(image,(unsigned short) bmp_info.width);
1909         (void) WriteBlobLSBShort(image,(unsigned short) bmp_info.height);
1910         (void) WriteBlobLSBShort(image,bmp_info.planes);
1911         (void) WriteBlobLSBShort(image,bmp_info.bits_per_pixel);
1912       }
1913     else
1914       {
1915         /*
1916           Write 40-byte version 3+ bitmap header.
1917         */
1918         (void) WriteBlobLSBLong(image,bmp_info.size);
1919         (void) WriteBlobLSBLong(image,(unsigned int) bmp_info.width);
1920         (void) WriteBlobLSBLong(image,(unsigned int) bmp_info.height);
1921         (void) WriteBlobLSBShort(image,bmp_info.planes);
1922         (void) WriteBlobLSBShort(image,bmp_info.bits_per_pixel);
1923         (void) WriteBlobLSBLong(image,bmp_info.compression);
1924         (void) WriteBlobLSBLong(image,bmp_info.image_size);
1925         (void) WriteBlobLSBLong(image,bmp_info.x_pixels);
1926         (void) WriteBlobLSBLong(image,bmp_info.y_pixels);
1927         (void) WriteBlobLSBLong(image,bmp_info.number_colors);
1928         (void) WriteBlobLSBLong(image,bmp_info.colors_important);
1929       }
1930     if ((type > 3) && ((image->matte != MagickFalse) ||
1931         (have_color_info != MagickFalse)))
1932       {
1933         /*
1934           Write the rest of the 108-byte BMP Version 4 header.
1935         */
1936         (void) WriteBlobLSBLong(image,0x00ff0000U);  /* Red mask */
1937         (void) WriteBlobLSBLong(image,0x0000ff00U);  /* Green mask */
1938         (void) WriteBlobLSBLong(image,0x000000ffU);  /* Blue mask */
1939         (void) WriteBlobLSBLong(image,0xff000000U);  /* Alpha mask */
1940         (void) WriteBlobLSBLong(image,0x00000001U);  /* CSType==Calib. RGB */
1941         (void) WriteBlobLSBLong(image,(unsigned int)
1942           image->chromaticity.red_primary.x*0x3ffffff);
1943         (void) WriteBlobLSBLong(image,(unsigned int)
1944           image->chromaticity.red_primary.y*0x3ffffff);
1945         (void) WriteBlobLSBLong(image,(unsigned int)
1946           (1.000f-(image->chromaticity.red_primary.x+
1947           image->chromaticity.red_primary.y)*0x3ffffff));
1948         (void) WriteBlobLSBLong(image,(unsigned int)
1949           image->chromaticity.green_primary.x*0x3ffffff);
1950         (void) WriteBlobLSBLong(image,(unsigned int)
1951           image->chromaticity.green_primary.y*0x3ffffff);
1952         (void) WriteBlobLSBLong(image,(unsigned int)
1953           (1.000f-(image->chromaticity.green_primary.x+
1954           image->chromaticity.green_primary.y)*0x3ffffff));
1955         (void) WriteBlobLSBLong(image,(unsigned int)
1956           image->chromaticity.blue_primary.x*0x3ffffff);
1957         (void) WriteBlobLSBLong(image,(unsigned int)
1958           image->chromaticity.blue_primary.y*0x3ffffff);
1959         (void) WriteBlobLSBLong(image,(unsigned int)
1960           (1.000f-(image->chromaticity.blue_primary.x+
1961           image->chromaticity.blue_primary.y)*0x3ffffff));
1962         (void) WriteBlobLSBLong(image,(unsigned int)
1963           bmp_info.gamma_scale.x*0xffff);
1964         (void) WriteBlobLSBLong(image,(unsigned int)
1965           bmp_info.gamma_scale.y*0xffff);
1966         (void) WriteBlobLSBLong(image,(unsigned int)
1967           bmp_info.gamma_scale.z*0xffff);
1968         if ((image->rendering_intent != UndefinedIntent) ||
1969             (profile != (StringInfo *) NULL))
1970           {
1971             ssize_t
1972               intent;
1973
1974             switch ((int) image->rendering_intent)
1975             {
1976               case SaturationIntent:
1977               {
1978                 intent=LCS_GM_BUSINESS;
1979                 break;
1980               }
1981               case RelativeIntent:
1982               {
1983                 intent=LCS_GM_GRAPHICS;
1984                 break;
1985               }
1986               case PerceptualIntent:
1987               {
1988                 intent=LCS_GM_IMAGES;
1989                 break;
1990               }
1991               case AbsoluteIntent:
1992               {
1993                 intent=LCS_GM_ABS_COLORIMETRIC;
1994                 break;
1995               }
1996               default:
1997               {
1998                 intent=0;
1999                 break;
2000               }
2001             }
2002             (void) WriteBlobLSBLong(image,(unsigned int) intent);
2003             (void) WriteBlobLSBLong(image,0x00);  /* dummy profile data */
2004             (void) WriteBlobLSBLong(image,0x00);  /* dummy profile length */
2005             (void) WriteBlobLSBLong(image,0x00);  /* reserved */
2006           }
2007       }
2008     if (image->storage_class == PseudoClass)
2009       {
2010         unsigned char
2011           *bmp_colormap;
2012
2013         /*
2014           Dump colormap to file.
2015         */
2016         if (image->debug != MagickFalse)
2017           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2018             "  Colormap: %.20g entries",(double) image->colors);
2019         bmp_colormap=(unsigned char *) AcquireQuantumMemory((size_t) (1UL <<
2020           bmp_info.bits_per_pixel),4*sizeof(*bmp_colormap));
2021         if (bmp_colormap == (unsigned char *) NULL)
2022           ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2023         q=bmp_colormap;
2024         for (i=0; i < (ssize_t) MagickMin((ssize_t) image->colors,(ssize_t) bmp_info.number_colors); i++)
2025         {
2026           *q++=ScaleQuantumToChar(image->colormap[i].blue);
2027           *q++=ScaleQuantumToChar(image->colormap[i].green);
2028           *q++=ScaleQuantumToChar(image->colormap[i].red);
2029           if (type > 2)
2030             *q++=(unsigned char) 0x0;
2031         }
2032         for ( ; i < (ssize_t) (1UL << bmp_info.bits_per_pixel); i++)
2033         {
2034           *q++=(unsigned char) 0x00;
2035           *q++=(unsigned char) 0x00;
2036           *q++=(unsigned char) 0x00;
2037           if (type > 2)
2038             *q++=(unsigned char) 0x00;
2039         }
2040         if (type <= 2)
2041           (void) WriteBlob(image,(size_t) (3*(1L << bmp_info.bits_per_pixel)),
2042             bmp_colormap);
2043         else
2044           (void) WriteBlob(image,(size_t) (4*(1L << bmp_info.bits_per_pixel)),
2045             bmp_colormap);
2046         bmp_colormap=(unsigned char *) RelinquishMagickMemory(bmp_colormap);
2047       }
2048     if (image->debug != MagickFalse)
2049       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2050         "  Pixels:  %u bytes",bmp_info.image_size);
2051     (void) WriteBlob(image,(size_t) bmp_info.image_size,pixels);
2052     pixels=(unsigned char *) RelinquishMagickMemory(pixels);
2053     if (GetNextImageInList(image) == (Image *) NULL)
2054       break;
2055     image=SyncNextImageInList(image);
2056     status=SetImageProgress(image,SaveImagesTag,scene++,
2057       GetImageListLength(image));
2058     if (status == MagickFalse)
2059       break;
2060   } while (image_info->adjoin != MagickFalse);
2061   (void) CloseBlob(image);
2062   return(MagickTrue);
2063 }