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