]> granicus.if.org Git - imagemagick/blob - coders/bmp.c
Allow BMP2 and BMP3 as decoders.
[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-2018 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://www.imagemagick.org/script/license.php                           %
28 %                                                                             %
29 %  Unless required by applicable law or agreed to in writing, software        %
30 %  distributed under the License is distributed on an "AS IS" BASIS,          %
31 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
32 %  See the License for the specific language governing permissions and        %
33 %  limitations under the License.                                             %
34 %                                                                             %
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 %
37 %
38 */
39 \f
40 /*
41   Include declarations.
42 */
43 #include "MagickCore/studio.h"
44 #include "MagickCore/blob.h"
45 #include "MagickCore/blob-private.h"
46 #include "MagickCore/cache.h"
47 #include "MagickCore/colormap-private.h"
48 #include "MagickCore/color-private.h"
49 #include "MagickCore/colormap.h"
50 #include "MagickCore/colorspace.h"
51 #include "MagickCore/colorspace-private.h"
52 #include "MagickCore/exception.h"
53 #include "MagickCore/exception-private.h"
54 #include "MagickCore/image.h"
55 #include "MagickCore/image-private.h"
56 #include "MagickCore/list.h"
57 #include "MagickCore/log.h"
58 #include "MagickCore/magick.h"
59 #include "MagickCore/memory_.h"
60 #include "MagickCore/monitor.h"
61 #include "MagickCore/monitor-private.h"
62 #include "MagickCore/option.h"
63 #include "MagickCore/pixel-accessor.h"
64 #include "MagickCore/profile.h"
65 #include "MagickCore/quantum-private.h"
66 #include "MagickCore/static.h"
67 #include "MagickCore/string_.h"
68 #include "MagickCore/module.h"
69 #include "MagickCore/transform.h"
70 \f
71 /*
72   Macro definitions (from Windows wingdi.h).
73 */
74 #undef BI_JPEG
75 #define BI_JPEG  4
76 #undef BI_PNG
77 #define BI_PNG  5
78 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__MINGW32__)
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     start_position;
524
525   MemoryInfo
526     *pixel_info;
527
528   Quantum
529     index;
530
531   register Quantum
532     *q;
533
534   register ssize_t
535     i,
536     x;
537
538   register unsigned char
539     *p;
540
541   size_t
542     bit,
543     bytes_per_line,
544     length;
545
546   ssize_t
547     count,
548     y;
549
550   unsigned char
551     magick[12],
552     *pixels;
553
554   unsigned int
555     blue,
556     green,
557     offset_bits,
558     red;
559
560   /*
561     Open image file.
562   */
563   assert(image_info != (const ImageInfo *) NULL);
564   assert(image_info->signature == MagickCoreSignature);
565   if (image_info->debug != MagickFalse)
566     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
567       image_info->filename);
568   assert(exception != (ExceptionInfo *) NULL);
569   assert(exception->signature == MagickCoreSignature);
570   image=AcquireImage(image_info,exception);
571   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
572   if (status == MagickFalse)
573     {
574       image=DestroyImageList(image);
575       return((Image *) NULL);
576     }
577   /*
578     Determine if this a BMP file.
579   */
580   (void) memset(&bmp_info,0,sizeof(bmp_info));
581   bmp_info.ba_offset=0;
582   start_position=0;
583   offset_bits=0;
584   count=ReadBlob(image,2,magick);
585   if (count != 2)
586     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
587   do
588   {
589     PixelInfo
590       quantum_bits;
591
592     PixelPacket
593       shift;
594
595     /*
596       Verify BMP identifier.
597     */
598     if (bmp_info.ba_offset == 0)
599       start_position=TellBlob(image)-2;
600     bmp_info.ba_offset=0;
601     while (LocaleNCompare((char *) magick,"BA",2) == 0)
602     {
603       bmp_info.file_size=ReadBlobLSBLong(image);
604       bmp_info.ba_offset=ReadBlobLSBLong(image);
605       bmp_info.offset_bits=ReadBlobLSBLong(image);
606       count=ReadBlob(image,2,magick);
607       if (count != 2)
608         break;
609     }
610     if (image->debug != MagickFalse)
611       (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Magick: %c%c",
612         magick[0],magick[1]);
613     if ((count != 2) || ((LocaleNCompare((char *) magick,"BM",2) != 0) &&
614         (LocaleNCompare((char *) magick,"CI",2) != 0)))
615       ThrowReaderException(CorruptImageError,"ImproperImageHeader");
616     bmp_info.file_size=ReadBlobLSBLong(image);
617     (void) ReadBlobLSBLong(image);
618     bmp_info.offset_bits=ReadBlobLSBLong(image);
619     bmp_info.size=ReadBlobLSBLong(image);
620     if (image->debug != MagickFalse)
621       (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  BMP size: %u",
622         bmp_info.size);
623     if (bmp_info.size == 12)
624       {
625         /*
626           OS/2 BMP image file.
627         */
628         (void) CopyMagickString(image->magick,"BMP2",MagickPathExtent);
629         bmp_info.width=(ssize_t) ((short) ReadBlobLSBShort(image));
630         bmp_info.height=(ssize_t) ((short) ReadBlobLSBShort(image));
631         bmp_info.planes=ReadBlobLSBShort(image);
632         bmp_info.bits_per_pixel=ReadBlobLSBShort(image);
633         bmp_info.x_pixels=0;
634         bmp_info.y_pixels=0;
635         bmp_info.number_colors=0;
636         bmp_info.compression=BI_RGB;
637         bmp_info.image_size=0;
638         bmp_info.alpha_mask=0;
639         if (image->debug != MagickFalse)
640           {
641             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
642               "  Format: OS/2 Bitmap");
643             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
644               "  Geometry: %.20gx%.20g",(double) bmp_info.width,(double)
645               bmp_info.height);
646           }
647       }
648     else
649       {
650         /*
651           Microsoft Windows BMP image file.
652         */
653         if (bmp_info.size < 40)
654           ThrowReaderException(CorruptImageError,"NonOS2HeaderSizeError");
655         bmp_info.width=(ssize_t) ReadBlobLSBSignedLong(image);
656         bmp_info.height=(ssize_t) ReadBlobLSBSignedLong(image);
657         bmp_info.planes=ReadBlobLSBShort(image);
658         bmp_info.bits_per_pixel=ReadBlobLSBShort(image);
659         bmp_info.compression=ReadBlobLSBLong(image);
660         bmp_info.image_size=ReadBlobLSBLong(image);
661         bmp_info.x_pixels=ReadBlobLSBLong(image);
662         bmp_info.y_pixels=ReadBlobLSBLong(image);
663         bmp_info.number_colors=ReadBlobLSBLong(image);
664         bmp_info.colors_important=ReadBlobLSBLong(image);
665         if (image->debug != MagickFalse)
666           {
667             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
668               "  Format: MS Windows bitmap");
669             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
670               "  Geometry: %.20gx%.20g",(double) bmp_info.width,(double)
671               bmp_info.height);
672             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
673               "  Bits per pixel: %.20g",(double) bmp_info.bits_per_pixel);
674             switch (bmp_info.compression)
675             {
676               case BI_RGB:
677               {
678                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
679                   "  Compression: BI_RGB");
680                 break;
681               }
682               case BI_RLE4:
683               {
684                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
685                   "  Compression: BI_RLE4");
686                 break;
687               }
688               case BI_RLE8:
689               {
690                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
691                   "  Compression: BI_RLE8");
692                 break;
693               }
694               case BI_BITFIELDS:
695               {
696                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
697                   "  Compression: BI_BITFIELDS");
698                 break;
699               }
700               case BI_PNG:
701               {
702                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
703                   "  Compression: BI_PNG");
704                 break;
705               }
706               case BI_JPEG:
707               {
708                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
709                   "  Compression: BI_JPEG");
710                 break;
711               }
712               default:
713               {
714                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
715                   "  Compression: UNKNOWN (%u)",bmp_info.compression);
716               }
717             }
718             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
719               "  Number of colors: %u",bmp_info.number_colors);
720           }
721         bmp_info.red_mask=ReadBlobLSBLong(image);
722         bmp_info.green_mask=ReadBlobLSBLong(image);
723         bmp_info.blue_mask=ReadBlobLSBLong(image);
724         if (bmp_info.size > 40)
725           {
726             double
727               gamma;
728
729             /*
730               Read color management information.
731             */
732             bmp_info.alpha_mask=ReadBlobLSBLong(image);
733             bmp_info.colorspace=ReadBlobLSBSignedLong(image);
734             /*
735               Decode 2^30 fixed point formatted CIE primaries.
736             */
737 #           define BMP_DENOM ((double) 0x40000000)
738             bmp_info.red_primary.x=(double) ReadBlobLSBLong(image)/BMP_DENOM;
739             bmp_info.red_primary.y=(double) ReadBlobLSBLong(image)/BMP_DENOM;
740             bmp_info.red_primary.z=(double) ReadBlobLSBLong(image)/BMP_DENOM;
741             bmp_info.green_primary.x=(double) ReadBlobLSBLong(image)/BMP_DENOM;
742             bmp_info.green_primary.y=(double) ReadBlobLSBLong(image)/BMP_DENOM;
743             bmp_info.green_primary.z=(double) ReadBlobLSBLong(image)/BMP_DENOM;
744             bmp_info.blue_primary.x=(double) ReadBlobLSBLong(image)/BMP_DENOM;
745             bmp_info.blue_primary.y=(double) ReadBlobLSBLong(image)/BMP_DENOM;
746             bmp_info.blue_primary.z=(double) ReadBlobLSBLong(image)/BMP_DENOM;
747
748             gamma=bmp_info.red_primary.x+bmp_info.red_primary.y+
749               bmp_info.red_primary.z;
750             gamma=PerceptibleReciprocal(gamma);
751             bmp_info.red_primary.x*=gamma;
752             bmp_info.red_primary.y*=gamma;
753             image->chromaticity.red_primary.x=bmp_info.red_primary.x;
754             image->chromaticity.red_primary.y=bmp_info.red_primary.y;
755
756             gamma=bmp_info.green_primary.x+bmp_info.green_primary.y+
757               bmp_info.green_primary.z;
758             gamma=PerceptibleReciprocal(gamma);
759             bmp_info.green_primary.x*=gamma;
760             bmp_info.green_primary.y*=gamma;
761             image->chromaticity.green_primary.x=bmp_info.green_primary.x;
762             image->chromaticity.green_primary.y=bmp_info.green_primary.y;
763
764             gamma=bmp_info.blue_primary.x+bmp_info.blue_primary.y+
765               bmp_info.blue_primary.z;
766             gamma=PerceptibleReciprocal(gamma);
767             bmp_info.blue_primary.x*=gamma;
768             bmp_info.blue_primary.y*=gamma;
769             image->chromaticity.blue_primary.x=bmp_info.blue_primary.x;
770             image->chromaticity.blue_primary.y=bmp_info.blue_primary.y;
771
772             /*
773               Decode 16^16 fixed point formatted gamma_scales.
774             */
775             bmp_info.gamma_scale.x=(double) ReadBlobLSBLong(image)/0x10000;
776             bmp_info.gamma_scale.y=(double) ReadBlobLSBLong(image)/0x10000;
777             bmp_info.gamma_scale.z=(double) ReadBlobLSBLong(image)/0x10000;
778             /*
779               Compute a single gamma from the BMP 3-channel gamma.
780             */
781             image->gamma=(bmp_info.gamma_scale.x+bmp_info.gamma_scale.y+
782               bmp_info.gamma_scale.z)/3.0;
783           }
784         else
785           (void) CopyMagickString(image->magick,"BMP3",MagickPathExtent);
786
787         if (bmp_info.size > 108)
788           {
789             size_t
790               intent;
791
792             /*
793               Read BMP Version 5 color management information.
794             */
795             intent=ReadBlobLSBLong(image);
796             switch ((int) intent)
797             {
798               case LCS_GM_BUSINESS:
799               {
800                 image->rendering_intent=SaturationIntent;
801                 break;
802               }
803               case LCS_GM_GRAPHICS:
804               {
805                 image->rendering_intent=RelativeIntent;
806                 break;
807               }
808               case LCS_GM_IMAGES:
809               {
810                 image->rendering_intent=PerceptualIntent;
811                 break;
812               }
813               case LCS_GM_ABS_COLORIMETRIC:
814               {
815                 image->rendering_intent=AbsoluteIntent;
816                 break;
817               }
818             }
819             (void) ReadBlobLSBLong(image);  /* Profile data */
820             (void) ReadBlobLSBLong(image);  /* Profile size */
821             (void) ReadBlobLSBLong(image);  /* Reserved byte */
822           }
823       }
824     if ((MagickSizeType) bmp_info.file_size > GetBlobSize(image))
825       (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError,
826         "LengthAndFilesizeDoNotMatch","`%s'",image->filename);
827     else
828       if ((MagickSizeType) bmp_info.file_size < GetBlobSize(image))
829         (void) ThrowMagickException(exception,GetMagickModule(),
830           CorruptImageWarning,"LengthAndFilesizeDoNotMatch","`%s'",
831           image->filename);
832     if (bmp_info.width <= 0)
833       ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
834     if (bmp_info.height == 0)
835       ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
836     if (bmp_info.planes != 1)
837       ThrowReaderException(CorruptImageError,"StaticPlanesValueNotEqualToOne");
838     if ((bmp_info.bits_per_pixel != 1) && (bmp_info.bits_per_pixel != 4) &&
839         (bmp_info.bits_per_pixel != 8) && (bmp_info.bits_per_pixel != 16) &&
840         (bmp_info.bits_per_pixel != 24) && (bmp_info.bits_per_pixel != 32))
841       ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
842     if (bmp_info.bits_per_pixel < 16 &&
843         bmp_info.number_colors > (1U << bmp_info.bits_per_pixel))
844       ThrowReaderException(CorruptImageError,"UnrecognizedNumberOfColors");
845     if ((bmp_info.compression == 1) && (bmp_info.bits_per_pixel != 8))
846       ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
847     if ((bmp_info.compression == 2) && (bmp_info.bits_per_pixel != 4))
848       ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
849     if ((bmp_info.compression == 3) && (bmp_info.bits_per_pixel < 16))
850       ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
851     switch (bmp_info.compression)
852     {
853       case BI_RGB:
854         image->compression=NoCompression;
855         break;
856       case BI_RLE8:
857       case BI_RLE4:
858         image->compression=RLECompression;
859         break;
860       case BI_BITFIELDS:
861         break;
862       case BI_JPEG:
863         ThrowReaderException(CoderError,"JPEGCompressNotSupported");
864       case BI_PNG:
865         ThrowReaderException(CoderError,"PNGCompressNotSupported");
866       default:
867         ThrowReaderException(CorruptImageError,"UnrecognizedImageCompression");
868     }
869     image->columns=(size_t) MagickAbsoluteValue(bmp_info.width);
870     image->rows=(size_t) MagickAbsoluteValue(bmp_info.height);
871     image->depth=bmp_info.bits_per_pixel <= 8 ? bmp_info.bits_per_pixel : 8;
872     image->alpha_trait=((bmp_info.alpha_mask != 0) &&
873       (bmp_info.compression == BI_BITFIELDS)) ? BlendPixelTrait :
874       UndefinedPixelTrait;
875     if (bmp_info.bits_per_pixel < 16)
876       {
877         size_t
878           one;
879
880         image->storage_class=PseudoClass;
881         image->colors=bmp_info.number_colors;
882         one=1;
883         if (image->colors == 0)
884           image->colors=one << bmp_info.bits_per_pixel;
885       }
886     image->resolution.x=(double) bmp_info.x_pixels/100.0;
887     image->resolution.y=(double) bmp_info.y_pixels/100.0;
888     image->units=PixelsPerCentimeterResolution;
889     if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
890       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
891         break;
892     status=SetImageExtent(image,image->columns,image->rows,exception);
893     if (status == MagickFalse)
894       return(DestroyImageList(image));
895     if (image->storage_class == PseudoClass)
896       {
897         unsigned char
898           *bmp_colormap;
899
900         size_t
901           packet_size;
902
903         /*
904           Read BMP raster colormap.
905         */
906         if (image->debug != MagickFalse)
907           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
908             "  Reading colormap of %.20g colors",(double) image->colors);
909         if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
910           ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
911         bmp_colormap=(unsigned char *) AcquireQuantumMemory((size_t)
912           image->colors,4*sizeof(*bmp_colormap));
913         if (bmp_colormap == (unsigned char *) NULL)
914           ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
915         if ((bmp_info.size == 12) || (bmp_info.size == 64))
916           packet_size=3;
917         else
918           packet_size=4;
919         offset=SeekBlob(image,start_position+14+bmp_info.size,SEEK_SET);
920         if (offset < 0)
921           {
922             bmp_colormap=(unsigned char *) RelinquishMagickMemory(bmp_colormap);
923             ThrowReaderException(CorruptImageError,"ImproperImageHeader");
924           }
925         count=ReadBlob(image,packet_size*image->colors,bmp_colormap);
926         if (count != (ssize_t) (packet_size*image->colors))
927           {
928             bmp_colormap=(unsigned char *) RelinquishMagickMemory(bmp_colormap);
929             ThrowReaderException(CorruptImageError,
930               "InsufficientImageDataInFile");
931           }
932         p=bmp_colormap;
933         for (i=0; i < (ssize_t) image->colors; i++)
934         {
935           image->colormap[i].blue=(MagickRealType) ScaleCharToQuantum(*p++);
936           image->colormap[i].green=(MagickRealType) ScaleCharToQuantum(*p++);
937           image->colormap[i].red=(MagickRealType) ScaleCharToQuantum(*p++);
938           if (packet_size == 4)
939             p++;
940         }
941         bmp_colormap=(unsigned char *) RelinquishMagickMemory(bmp_colormap);
942       }
943     /*
944       Read image data.
945     */
946     if (bmp_info.offset_bits == offset_bits)
947       ThrowReaderException(CorruptImageError,"ImproperImageHeader");
948     offset_bits=bmp_info.offset_bits;
949     offset=SeekBlob(image,start_position+bmp_info.offset_bits,SEEK_SET);
950     if (offset < 0)
951       ThrowReaderException(CorruptImageError,"ImproperImageHeader");
952     if (bmp_info.compression == BI_RLE4)
953       bmp_info.bits_per_pixel<<=1;
954     bytes_per_line=4*((image->columns*bmp_info.bits_per_pixel+31)/32);
955     length=(size_t) bytes_per_line*image->rows;
956     if (((MagickSizeType) length/8) > GetBlobSize(image))
957       ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
958     if ((bmp_info.compression == BI_RGB) ||
959         (bmp_info.compression == BI_BITFIELDS))
960       {
961         pixel_info=AcquireVirtualMemory((size_t) image->rows,
962           MagickMax(bytes_per_line,image->columns+256UL)*sizeof(*pixels));
963         if (pixel_info == (MemoryInfo *) NULL)
964           ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
965         pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
966         if (image->debug != MagickFalse)
967           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
968             "  Reading pixels (%.20g bytes)",(double) length);
969         count=ReadBlob(image,length,pixels);
970         if (count != (ssize_t) length)
971           {
972             pixel_info=RelinquishVirtualMemory(pixel_info);
973             ThrowReaderException(CorruptImageError,
974               "InsufficientImageDataInFile");
975           }
976       }
977     else
978       {
979         /*
980           Convert run-length encoded raster pixels.
981         */
982         pixel_info=AcquireVirtualMemory((size_t) image->rows,
983           MagickMax(bytes_per_line,image->columns+256UL)*sizeof(*pixels));
984         if (pixel_info == (MemoryInfo *) NULL)
985           ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
986         pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
987         status=DecodeImage(image,bmp_info.compression,pixels,
988           image->columns*image->rows);
989         if (status == MagickFalse)
990           {
991             pixel_info=RelinquishVirtualMemory(pixel_info);
992             ThrowReaderException(CorruptImageError,
993               "UnableToRunlengthDecodeImage");
994           }
995       }
996     /*
997       Convert BMP raster image to pixel packets.
998     */
999     if (bmp_info.compression == BI_RGB)
1000       {
1001         /*
1002           We should ignore the alpha value in BMP3 files but there have been
1003           reports about 32 bit files with alpha. We do a quick check to see if
1004           the alpha channel contains a value that is not zero (default value).
1005           If we find a non zero value we asume the program that wrote the file
1006           wants to use the alpha channel.
1007         */
1008         if ((image->alpha_trait == UndefinedPixelTrait) && (bmp_info.size == 40) &&
1009             (bmp_info.bits_per_pixel == 32))
1010           {
1011             bytes_per_line=4*(image->columns);
1012             for (y=(ssize_t) image->rows-1; y >= 0; y--)
1013             {
1014               p=pixels+(image->rows-y-1)*bytes_per_line;
1015               for (x=0; x < (ssize_t) image->columns; x++)
1016               {
1017                 if (*(p+3) != 0)
1018                   {
1019                     image->alpha_trait=BlendPixelTrait;
1020                     y=-1;
1021                     break;
1022                   }
1023                 p+=4;
1024               }
1025             }
1026           }
1027         bmp_info.alpha_mask=image->alpha_trait != UndefinedPixelTrait ?
1028           0xff000000U : 0U;
1029         bmp_info.red_mask=0x00ff0000U;
1030         bmp_info.green_mask=0x0000ff00U;
1031         bmp_info.blue_mask=0x000000ffU;
1032         if (bmp_info.bits_per_pixel == 16)
1033           {
1034             /*
1035               RGB555.
1036             */
1037             bmp_info.red_mask=0x00007c00U;
1038             bmp_info.green_mask=0x000003e0U;
1039             bmp_info.blue_mask=0x0000001fU;
1040           }
1041       }
1042     (void) memset(&shift,0,sizeof(shift));
1043     (void) memset(&quantum_bits,0,sizeof(quantum_bits));
1044     if ((bmp_info.bits_per_pixel == 16) || (bmp_info.bits_per_pixel == 32))
1045       {
1046         register unsigned int
1047           sample;
1048
1049         /*
1050           Get shift and quantum bits info from bitfield masks.
1051         */
1052         if (bmp_info.red_mask != 0)
1053           while (((bmp_info.red_mask << shift.red) & 0x80000000UL) == 0)
1054           {
1055             shift.red++;
1056             if (shift.red >= 32U)
1057               break;
1058           }
1059         if (bmp_info.green_mask != 0)
1060           while (((bmp_info.green_mask << shift.green) & 0x80000000UL) == 0)
1061           {
1062             shift.green++;
1063             if (shift.green >= 32U)
1064               break;
1065           }
1066         if (bmp_info.blue_mask != 0)
1067           while (((bmp_info.blue_mask << shift.blue) & 0x80000000UL) == 0)
1068           {
1069             shift.blue++;
1070             if (shift.blue >= 32U)
1071               break;
1072           }
1073         if (bmp_info.alpha_mask != 0)
1074           while (((bmp_info.alpha_mask << shift.alpha) & 0x80000000UL) == 0)
1075           {
1076             shift.alpha++;
1077             if (shift.alpha >= 32U)
1078               break;
1079           }
1080         sample=shift.red;
1081         while (((bmp_info.red_mask << sample) & 0x80000000UL) != 0)
1082         {
1083           sample++;
1084           if (sample >= 32U)
1085             break;
1086         }
1087         quantum_bits.red=(MagickRealType) (sample-shift.red);
1088         sample=shift.green;
1089         while (((bmp_info.green_mask << sample) & 0x80000000UL) != 0)
1090         {
1091           sample++;
1092           if (sample >= 32U)
1093             break;
1094         }
1095         quantum_bits.green=(MagickRealType) (sample-shift.green);
1096         sample=shift.blue;
1097         while (((bmp_info.blue_mask << sample) & 0x80000000UL) != 0)
1098         {
1099           sample++;
1100           if (sample >= 32U)
1101             break;
1102         }
1103         quantum_bits.blue=(MagickRealType) (sample-shift.blue);
1104         sample=shift.alpha;
1105         while (((bmp_info.alpha_mask << sample) & 0x80000000UL) != 0)
1106         {
1107           sample++;
1108           if (sample >= 32U)
1109             break;
1110         }
1111         quantum_bits.alpha=(MagickRealType) (sample-shift.alpha);
1112       }
1113     switch (bmp_info.bits_per_pixel)
1114     {
1115       case 1:
1116       {
1117         /*
1118           Convert bitmap scanline.
1119         */
1120         for (y=(ssize_t) image->rows-1; y >= 0; y--)
1121         {
1122           p=pixels+(image->rows-y-1)*bytes_per_line;
1123           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
1124           if (q == (Quantum *) NULL)
1125             break;
1126           for (x=0; x < ((ssize_t) image->columns-7); x+=8)
1127           {
1128             for (bit=0; bit < 8; bit++)
1129             {
1130               index=(Quantum) (((*p) & (0x80 >> bit)) != 0 ? 0x01 : 0x00);
1131               SetPixelIndex(image,index,q);
1132               q+=GetPixelChannels(image);
1133             }
1134             p++;
1135           }
1136           if ((image->columns % 8) != 0)
1137             {
1138               for (bit=0; bit < (image->columns % 8); bit++)
1139               {
1140                 index=(Quantum) (((*p) & (0x80 >> bit)) != 0 ? 0x01 : 0x00);
1141                 SetPixelIndex(image,index,q);
1142                 q+=GetPixelChannels(image);
1143               }
1144               p++;
1145             }
1146           if (SyncAuthenticPixels(image,exception) == MagickFalse)
1147             break;
1148           if (image->previous == (Image *) NULL)
1149             {
1150               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
1151                 (image->rows-y),image->rows);
1152               if (status == MagickFalse)
1153                 break;
1154             }
1155         }
1156         (void) SyncImage(image,exception);
1157         break;
1158       }
1159       case 4:
1160       {
1161         /*
1162           Convert PseudoColor scanline.
1163         */
1164         for (y=(ssize_t) image->rows-1; y >= 0; y--)
1165         {
1166           p=pixels+(image->rows-y-1)*bytes_per_line;
1167           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
1168           if (q == (Quantum *) NULL)
1169             break;
1170           for (x=0; x < ((ssize_t) image->columns-1); x+=2)
1171           {
1172             ValidateColormapValue(image,(ssize_t) ((*p >> 4) & 0x0f),&index,
1173               exception);
1174             SetPixelIndex(image,index,q);
1175             q+=GetPixelChannels(image);
1176             ValidateColormapValue(image,(ssize_t) (*p & 0x0f),&index,exception);
1177             SetPixelIndex(image,index,q);
1178             q+=GetPixelChannels(image);
1179             p++;
1180           }
1181           if ((image->columns % 2) != 0)
1182             {
1183               ValidateColormapValue(image,(ssize_t) ((*p >> 4) & 0xf),&index,
1184                 exception);
1185               SetPixelIndex(image,index,q);
1186               q+=GetPixelChannels(image);
1187               p++;
1188               x++;
1189             }
1190           if (x < (ssize_t) image->columns)
1191             break;
1192           if (SyncAuthenticPixels(image,exception) == MagickFalse)
1193             break;
1194           if (image->previous == (Image *) NULL)
1195             {
1196               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
1197                 (image->rows-y),image->rows);
1198               if (status == MagickFalse)
1199                 break;
1200             }
1201         }
1202         (void) SyncImage(image,exception);
1203         break;
1204       }
1205       case 8:
1206       {
1207         /*
1208           Convert PseudoColor scanline.
1209         */
1210         if ((bmp_info.compression == BI_RLE8) ||
1211             (bmp_info.compression == BI_RLE4))
1212           bytes_per_line=image->columns;
1213         for (y=(ssize_t) image->rows-1; y >= 0; y--)
1214         {
1215           p=pixels+(image->rows-y-1)*bytes_per_line;
1216           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
1217           if (q == (Quantum *) NULL)
1218             break;
1219           for (x=(ssize_t) image->columns; x != 0; --x)
1220           {
1221             ValidateColormapValue(image,(ssize_t) *p++,&index,exception);
1222             SetPixelIndex(image,index,q);
1223             q+=GetPixelChannels(image);
1224           }
1225           if (SyncAuthenticPixels(image,exception) == MagickFalse)
1226             break;
1227           offset=(MagickOffsetType) (image->rows-y-1);
1228           if (image->previous == (Image *) NULL)
1229             {
1230               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
1231                 (image->rows-y),image->rows);
1232               if (status == MagickFalse)
1233                 break;
1234             }
1235         }
1236         (void) SyncImage(image,exception);
1237         break;
1238       }
1239       case 16:
1240       {
1241         unsigned int
1242           alpha,
1243           pixel;
1244
1245         /*
1246           Convert bitfield encoded 16-bit PseudoColor scanline.
1247         */
1248         if ((bmp_info.compression != BI_RGB) &&
1249             (bmp_info.compression != BI_BITFIELDS))
1250           {
1251             pixel_info=RelinquishVirtualMemory(pixel_info);
1252             ThrowReaderException(CorruptImageError,
1253               "UnrecognizedImageCompression");
1254           }
1255         bytes_per_line=2*(image->columns+image->columns % 2);
1256         image->storage_class=DirectClass;
1257         for (y=(ssize_t) image->rows-1; y >= 0; y--)
1258         {
1259           p=pixels+(image->rows-y-1)*bytes_per_line;
1260           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
1261           if (q == (Quantum *) NULL)
1262             break;
1263           for (x=0; x < (ssize_t) image->columns; x++)
1264           {
1265             pixel=(unsigned int) (*p++);
1266             pixel|=(*p++) << 8;
1267             red=((pixel & bmp_info.red_mask) << shift.red) >> 16;
1268             if (quantum_bits.red == 5)
1269               red|=((red & 0xe000) >> 5);
1270             if (quantum_bits.red <= 8)
1271               red|=((red & 0xff00) >> 8);
1272             green=((pixel & bmp_info.green_mask) << shift.green) >> 16;
1273             if (quantum_bits.green == 5)
1274               green|=((green & 0xe000) >> 5);
1275             if (quantum_bits.green == 6)
1276               green|=((green & 0xc000) >> 6);
1277             if (quantum_bits.green <= 8)
1278               green|=((green & 0xff00) >> 8);
1279             blue=((pixel & bmp_info.blue_mask) << shift.blue) >> 16;
1280             if (quantum_bits.blue == 5)
1281               blue|=((blue & 0xe000) >> 5);
1282             if (quantum_bits.blue <= 8)
1283               blue|=((blue & 0xff00) >> 8);
1284             SetPixelRed(image,ScaleShortToQuantum((unsigned short) red),q);
1285             SetPixelGreen(image,ScaleShortToQuantum((unsigned short) green),q);
1286             SetPixelBlue(image,ScaleShortToQuantum((unsigned short) blue),q);
1287             SetPixelAlpha(image,OpaqueAlpha,q);
1288             if (image->alpha_trait != UndefinedPixelTrait)
1289               {
1290                 alpha=((pixel & bmp_info.alpha_mask) << shift.alpha) >> 16;
1291                 if (quantum_bits.alpha <= 8)
1292                   alpha|=((alpha & 0xff00) >> 8);
1293                 SetPixelAlpha(image,ScaleShortToQuantum(
1294                   (unsigned short) alpha),q);
1295               }
1296             q+=GetPixelChannels(image);
1297           }
1298           if (SyncAuthenticPixels(image,exception) == MagickFalse)
1299             break;
1300           offset=(MagickOffsetType) (image->rows-y-1);
1301           if (image->previous == (Image *) NULL)
1302             {
1303               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
1304                 (image->rows-y),image->rows);
1305               if (status == MagickFalse)
1306                 break;
1307             }
1308         }
1309         break;
1310       }
1311       case 24:
1312       {
1313         /*
1314           Convert DirectColor scanline.
1315         */
1316         bytes_per_line=4*((image->columns*24+31)/32);
1317         for (y=(ssize_t) image->rows-1; y >= 0; y--)
1318         {
1319           p=pixels+(image->rows-y-1)*bytes_per_line;
1320           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
1321           if (q == (Quantum *) NULL)
1322             break;
1323           for (x=0; x < (ssize_t) image->columns; x++)
1324           {
1325             SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
1326             SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
1327             SetPixelRed(image,ScaleCharToQuantum(*p++),q);
1328             SetPixelAlpha(image,OpaqueAlpha,q);
1329             q+=GetPixelChannels(image);
1330           }
1331           if (SyncAuthenticPixels(image,exception) == MagickFalse)
1332             break;
1333           offset=(MagickOffsetType) (image->rows-y-1);
1334           if (image->previous == (Image *) NULL)
1335             {
1336               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
1337                 (image->rows-y),image->rows);
1338               if (status == MagickFalse)
1339                 break;
1340             }
1341         }
1342         break;
1343       }
1344       case 32:
1345       {
1346         /*
1347           Convert bitfield encoded DirectColor scanline.
1348         */
1349         if ((bmp_info.compression != BI_RGB) &&
1350             (bmp_info.compression != BI_BITFIELDS))
1351           {
1352             pixel_info=RelinquishVirtualMemory(pixel_info);
1353             ThrowReaderException(CorruptImageError,
1354               "UnrecognizedImageCompression");
1355           }
1356         bytes_per_line=4*(image->columns);
1357         for (y=(ssize_t) image->rows-1; y >= 0; y--)
1358         {
1359           unsigned int
1360             alpha,
1361             pixel;
1362
1363           p=pixels+(image->rows-y-1)*bytes_per_line;
1364           q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
1365           if (q == (Quantum *) NULL)
1366             break;
1367           for (x=0; x < (ssize_t) image->columns; x++)
1368           {
1369             pixel=(unsigned int) (*p++);
1370             pixel|=((unsigned int) *p++ << 8);
1371             pixel|=((unsigned int) *p++ << 16);
1372             pixel|=((unsigned int) *p++ << 24);
1373             red=((pixel & bmp_info.red_mask) << shift.red) >> 16;
1374             if (quantum_bits.red == 8)
1375               red|=(red >> 8);
1376             green=((pixel & bmp_info.green_mask) << shift.green) >> 16;
1377             if (quantum_bits.green == 8)
1378               green|=(green >> 8);
1379             blue=((pixel & bmp_info.blue_mask) << shift.blue) >> 16;
1380             if (quantum_bits.blue == 8)
1381               blue|=(blue >> 8);
1382             SetPixelRed(image,ScaleShortToQuantum((unsigned short) red),q);
1383             SetPixelGreen(image,ScaleShortToQuantum((unsigned short) green),q);
1384             SetPixelBlue(image,ScaleShortToQuantum((unsigned short) blue),q);
1385             SetPixelAlpha(image,OpaqueAlpha,q);
1386             if (image->alpha_trait != UndefinedPixelTrait)
1387               {
1388                 alpha=((pixel & bmp_info.alpha_mask) << shift.alpha) >> 16;
1389                 if (quantum_bits.alpha == 8)
1390                   alpha|=(alpha >> 8);
1391                 SetPixelAlpha(image,ScaleShortToQuantum(
1392                   (unsigned short) alpha),q);
1393               }
1394             q+=GetPixelChannels(image);
1395           }
1396           if (SyncAuthenticPixels(image,exception) == MagickFalse)
1397             break;
1398           offset=(MagickOffsetType) (image->rows-y-1);
1399           if (image->previous == (Image *) NULL)
1400             {
1401               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType)
1402                 (image->rows-y),image->rows);
1403               if (status == MagickFalse)
1404                 break;
1405             }
1406         }
1407         break;
1408       }
1409       default:
1410       {
1411         pixel_info=RelinquishVirtualMemory(pixel_info);
1412         ThrowReaderException(CorruptImageError,"ImproperImageHeader");
1413       }
1414     }
1415     pixel_info=RelinquishVirtualMemory(pixel_info);
1416     if (y > 0)
1417       break;
1418     if (EOFBlob(image) != MagickFalse)
1419       {
1420         ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
1421           image->filename);
1422         break;
1423       }
1424     if (bmp_info.height < 0)
1425       {
1426         Image
1427           *flipped_image;
1428
1429         /*
1430           Correct image orientation.
1431         */
1432         flipped_image=FlipImage(image,exception);
1433         if (flipped_image != (Image *) NULL)
1434           {
1435             DuplicateBlob(flipped_image,image);
1436             ReplaceImageInList(&image, flipped_image);
1437             image=flipped_image;
1438           }
1439       }
1440     /*
1441       Proceed to next image.
1442     */
1443     if (image_info->number_scenes != 0)
1444       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1445         break;
1446     *magick='\0';
1447     if (bmp_info.ba_offset != 0)
1448       {
1449         offset=SeekBlob(image,(MagickOffsetType) bmp_info.ba_offset,SEEK_SET);
1450         if (offset < 0)
1451           ThrowReaderException(CorruptImageError,"ImproperImageHeader");
1452       }
1453     count=ReadBlob(image,2,magick);
1454     if ((count == 2) && (IsBMP(magick,2) != MagickFalse))
1455       {
1456         /*
1457           Acquire next image structure.
1458         */
1459         AcquireNextImage(image_info,image,exception);
1460         if (GetNextImageInList(image) == (Image *) NULL)
1461           {
1462             image=DestroyImageList(image);
1463             return((Image *) NULL);
1464           }
1465         image=SyncNextImageInList(image);
1466         status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
1467           GetBlobSize(image));
1468         if (status == MagickFalse)
1469           break;
1470       }
1471   } while (IsBMP(magick,2) != MagickFalse);
1472   (void) CloseBlob(image);
1473   return(GetFirstImageInList(image));
1474 }
1475 \f
1476 /*
1477 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1478 %                                                                             %
1479 %                                                                             %
1480 %                                                                             %
1481 %   R e g i s t e r B M P I m a g e                                           %
1482 %                                                                             %
1483 %                                                                             %
1484 %                                                                             %
1485 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1486 %
1487 %  RegisterBMPImage() adds attributes for the BMP image format to
1488 %  the list of supported formats.  The attributes include the image format
1489 %  tag, a method to read and/or write the format, whether the format
1490 %  supports the saving of more than one frame to the same file or blob,
1491 %  whether the format supports native in-memory I/O, and a brief
1492 %  description of the format.
1493 %
1494 %  The format of the RegisterBMPImage method is:
1495 %
1496 %      size_t RegisterBMPImage(void)
1497 %
1498 */
1499 ModuleExport size_t RegisterBMPImage(void)
1500 {
1501   MagickInfo
1502     *entry;
1503
1504   entry=AcquireMagickInfo("BMP","BMP","Microsoft Windows bitmap image");
1505   entry->decoder=(DecodeImageHandler *) ReadBMPImage;
1506   entry->encoder=(EncodeImageHandler *) WriteBMPImage;
1507   entry->magick=(IsImageFormatHandler *) IsBMP;
1508   entry->flags^=CoderAdjoinFlag;
1509   entry->flags|=CoderDecoderSeekableStreamFlag;
1510   (void) RegisterMagickInfo(entry);
1511   entry=AcquireMagickInfo("BMP","BMP2","Microsoft Windows bitmap image (V2)");
1512   entry->decoder=(DecodeImageHandler *) ReadBMPImage;
1513   entry->encoder=(EncodeImageHandler *) WriteBMPImage;
1514   entry->magick=(IsImageFormatHandler *) IsBMP;
1515   entry->flags^=CoderAdjoinFlag;
1516   entry->flags|=CoderDecoderSeekableStreamFlag;
1517   (void) RegisterMagickInfo(entry);
1518   entry=AcquireMagickInfo("BMP","BMP3","Microsoft Windows bitmap image (V3)");
1519   entry->decoder=(DecodeImageHandler *) ReadBMPImage;
1520   entry->encoder=(EncodeImageHandler *) WriteBMPImage;
1521   entry->magick=(IsImageFormatHandler *) IsBMP;
1522   entry->flags^=CoderAdjoinFlag;
1523   entry->flags|=CoderDecoderSeekableStreamFlag;
1524   (void) RegisterMagickInfo(entry);
1525   return(MagickImageCoderSignature);
1526 }
1527 \f
1528 /*
1529 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1530 %                                                                             %
1531 %                                                                             %
1532 %                                                                             %
1533 %   U n r e g i s t e r B M P I m a g e                                       %
1534 %                                                                             %
1535 %                                                                             %
1536 %                                                                             %
1537 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1538 %
1539 %  UnregisterBMPImage() removes format registrations made by the
1540 %  BMP module from the list of supported formats.
1541 %
1542 %  The format of the UnregisterBMPImage method is:
1543 %
1544 %      UnregisterBMPImage(void)
1545 %
1546 */
1547 ModuleExport void UnregisterBMPImage(void)
1548 {
1549   (void) UnregisterMagickInfo("BMP");
1550   (void) UnregisterMagickInfo("BMP2");
1551   (void) UnregisterMagickInfo("BMP3");
1552 }
1553 \f
1554 /*
1555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1556 %                                                                             %
1557 %                                                                             %
1558 %                                                                             %
1559 %   W r i t e B M P I m a g e                                                 %
1560 %                                                                             %
1561 %                                                                             %
1562 %                                                                             %
1563 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1564 %
1565 %  WriteBMPImage() writes an image in Microsoft Windows bitmap encoded
1566 %  image format, version 3 for Windows or (if the image has a matte channel)
1567 %  version 4.
1568 %
1569 %  The format of the WriteBMPImage method is:
1570 %
1571 %      MagickBooleanType WriteBMPImage(const ImageInfo *image_info,
1572 %        Image *image,ExceptionInfo *exception)
1573 %
1574 %  A description of each parameter follows.
1575 %
1576 %    o image_info: the image info.
1577 %
1578 %    o image:  The image.
1579 %
1580 %    o exception: return any errors or warnings in this structure.
1581 %
1582 */
1583 static MagickBooleanType WriteBMPImage(const ImageInfo *image_info,Image *image,
1584   ExceptionInfo *exception)
1585 {
1586   BMPInfo
1587     bmp_info;
1588
1589   BMPSubtype
1590     bmp_subtype;
1591
1592   const char
1593     *option;
1594
1595   const StringInfo
1596     *profile;
1597
1598   MagickBooleanType
1599     have_color_info,
1600     status;
1601
1602   MagickOffsetType
1603     scene;
1604
1605   MemoryInfo
1606     *pixel_info;
1607
1608   register const Quantum
1609     *p;
1610
1611   register ssize_t
1612     i,
1613     x;
1614
1615   register unsigned char
1616     *q;
1617
1618   size_t
1619     bytes_per_line,
1620     imageListLength,
1621     type;
1622
1623   ssize_t
1624     y;
1625
1626   unsigned char
1627     *bmp_data,
1628     *pixels;
1629
1630   /*
1631     Open output image file.
1632   */
1633   assert(image_info != (const ImageInfo *) NULL);
1634   assert(image_info->signature == MagickCoreSignature);
1635   assert(image != (Image *) NULL);
1636   assert(image->signature == MagickCoreSignature);
1637   if (image->debug != MagickFalse)
1638     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1639   assert(exception != (ExceptionInfo *) NULL);
1640   assert(exception->signature == MagickCoreSignature);
1641   status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1642   if (status == MagickFalse)
1643     return(status);
1644   type=4;
1645   if (LocaleCompare(image_info->magick,"BMP2") == 0)
1646     type=2;
1647   else
1648     if (LocaleCompare(image_info->magick,"BMP3") == 0)
1649       type=3;
1650   option=GetImageOption(image_info,"bmp:format");
1651   if (option != (char *) NULL)
1652     {
1653       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1654           "  Format=%s",option);
1655       if (LocaleCompare(option,"bmp2") == 0)
1656         type=2;
1657       if (LocaleCompare(option,"bmp3") == 0)
1658         type=3;
1659       if (LocaleCompare(option,"bmp4") == 0)
1660         type=4;
1661     }
1662   scene=0;
1663   imageListLength=GetImageListLength(image);
1664   do
1665   {
1666     /*
1667       Initialize BMP raster file header.
1668     */
1669     if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
1670       (void) TransformImageColorspace(image,sRGBColorspace,exception);
1671     (void) memset(&bmp_info,0,sizeof(bmp_info));
1672     bmp_info.file_size=14+12;
1673     if (type > 2)
1674       bmp_info.file_size+=28;
1675     bmp_info.offset_bits=bmp_info.file_size;
1676     bmp_info.compression=BI_RGB;
1677     bmp_info.red_mask=0x00ff0000U;
1678     bmp_info.green_mask=0x0000ff00U;
1679     bmp_info.blue_mask=0x000000ffU;
1680     bmp_info.alpha_mask=0xff000000U;
1681     bmp_subtype=UndefinedSubtype;
1682     if ((image->storage_class == PseudoClass) && (image->colors > 256))
1683       (void) SetImageStorageClass(image,DirectClass,exception);
1684     if (image->storage_class != DirectClass)
1685       {
1686         /*
1687           Colormapped BMP raster.
1688         */
1689         bmp_info.bits_per_pixel=8;
1690         if (image->colors <= 2)
1691           bmp_info.bits_per_pixel=1;
1692         else
1693           if (image->colors <= 16)
1694             bmp_info.bits_per_pixel=4;
1695           else
1696             if (image->colors <= 256)
1697               bmp_info.bits_per_pixel=8;
1698         if (image_info->compression == RLECompression)
1699           bmp_info.bits_per_pixel=8;
1700         bmp_info.number_colors=1U << bmp_info.bits_per_pixel;
1701         if (image->alpha_trait != UndefinedPixelTrait)
1702           (void) SetImageStorageClass(image,DirectClass,exception);
1703         else
1704           if ((size_t) bmp_info.number_colors < image->colors)
1705             (void) SetImageStorageClass(image,DirectClass,exception);
1706           else
1707             {
1708               bmp_info.file_size+=3*(1UL << bmp_info.bits_per_pixel);
1709               bmp_info.offset_bits+=3*(1UL << bmp_info.bits_per_pixel);
1710               if (type > 2)
1711                 {
1712                   bmp_info.file_size+=(1UL << bmp_info.bits_per_pixel);
1713                   bmp_info.offset_bits+=(1UL << bmp_info.bits_per_pixel);
1714                 }
1715             }
1716       }
1717     if (image->storage_class == DirectClass)
1718       {
1719         /*
1720           Full color BMP raster.
1721         */
1722         bmp_info.number_colors=0;
1723         option=GetImageOption(image_info,"bmp:subtype");
1724         if (option != (const char *) NULL)
1725         {
1726           if (image->alpha_trait != UndefinedPixelTrait)
1727             {
1728               if (LocaleNCompare(option,"ARGB4444",8) == 0)
1729                 {
1730                   bmp_subtype=ARGB4444;
1731                   bmp_info.red_mask=0x00000f00U;
1732                   bmp_info.green_mask=0x000000f0U;
1733                   bmp_info.blue_mask=0x0000000fU;
1734                   bmp_info.alpha_mask=0x0000f000U;
1735                 }
1736               else if (LocaleNCompare(option,"ARGB1555",8) == 0)
1737                 {
1738                   bmp_subtype=ARGB1555;
1739                   bmp_info.red_mask=0x00007c00U;
1740                   bmp_info.green_mask=0x000003e0U;
1741                   bmp_info.blue_mask=0x0000001fU;
1742                   bmp_info.alpha_mask=0x00008000U;
1743                 }
1744             }
1745           else
1746           {
1747             if (LocaleNCompare(option,"RGB555",6) == 0)
1748               {
1749                 bmp_subtype=RGB555;
1750                 bmp_info.red_mask=0x00007c00U;
1751                 bmp_info.green_mask=0x000003e0U;
1752                 bmp_info.blue_mask=0x0000001fU;
1753                 bmp_info.alpha_mask=0U;
1754               }
1755             else if (LocaleNCompare(option,"RGB565",6) == 0)
1756               {
1757                 bmp_subtype=RGB565;
1758                 bmp_info.red_mask=0x0000f800U;
1759                 bmp_info.green_mask=0x000007e0U;
1760                 bmp_info.blue_mask=0x0000001fU;
1761                 bmp_info.alpha_mask=0U;
1762               }
1763           }
1764         }
1765         if (bmp_subtype != UndefinedSubtype)
1766           {
1767             bmp_info.bits_per_pixel=16;
1768             bmp_info.compression=BI_BITFIELDS;
1769           }
1770         else
1771           {
1772             bmp_info.bits_per_pixel=(unsigned short) ((type > 3) &&
1773                (image->alpha_trait != UndefinedPixelTrait) ? 32 : 24);
1774             bmp_info.compression=(unsigned int) ((type > 3) &&
1775               (image->alpha_trait != UndefinedPixelTrait) ? BI_BITFIELDS : BI_RGB);
1776             if ((type == 3) && (image->alpha_trait != UndefinedPixelTrait))
1777               {
1778                 option=GetImageOption(image_info,"bmp3:alpha");
1779                 if (IsStringTrue(option))
1780                   bmp_info.bits_per_pixel=32;
1781               }
1782           }
1783       }
1784     bytes_per_line=4*((image->columns*bmp_info.bits_per_pixel+31)/32);
1785     bmp_info.ba_offset=0;
1786     profile=GetImageProfile(image,"icc");
1787     have_color_info=(image->rendering_intent != UndefinedIntent) ||
1788       (profile != (StringInfo *) NULL) || (image->gamma != 0.0) ?  MagickTrue :
1789       MagickFalse;
1790     if (type == 2)
1791       bmp_info.size=12;
1792     else
1793       if ((type == 3) || ((image->alpha_trait == UndefinedPixelTrait) &&
1794           (have_color_info == MagickFalse)))
1795         {
1796           type=3;
1797           bmp_info.size=40;
1798         }
1799       else
1800         {
1801           int
1802             extra_size;
1803
1804           bmp_info.size=108;
1805           extra_size=68;
1806           if ((image->rendering_intent != UndefinedIntent) ||
1807               (profile != (StringInfo *) NULL))
1808             {
1809               bmp_info.size=124;
1810               extra_size+=16;
1811             }
1812           bmp_info.file_size+=extra_size;
1813           bmp_info.offset_bits+=extra_size;
1814         }
1815     if (((ssize_t) image->columns != (ssize_t) ((signed int) image->columns)) ||
1816         ((ssize_t) image->rows != (ssize_t) ((signed int) image->rows)))
1817       ThrowWriterException(ImageError,"WidthOrHeightExceedsLimit");
1818     bmp_info.width=(ssize_t) image->columns;
1819     bmp_info.height=(ssize_t) image->rows;
1820     bmp_info.planes=1;
1821     bmp_info.image_size=(unsigned int) (bytes_per_line*image->rows);
1822     bmp_info.file_size+=bmp_info.image_size;
1823     bmp_info.x_pixels=75*39;
1824     bmp_info.y_pixels=75*39;
1825     switch (image->units)
1826     {
1827       case UndefinedResolution:
1828       case PixelsPerInchResolution:
1829       {
1830         bmp_info.x_pixels=(unsigned int) (100.0*image->resolution.x/2.54);
1831         bmp_info.y_pixels=(unsigned int) (100.0*image->resolution.y/2.54);
1832         break;
1833       }
1834       case PixelsPerCentimeterResolution:
1835       {
1836         bmp_info.x_pixels=(unsigned int) (100.0*image->resolution.x);
1837         bmp_info.y_pixels=(unsigned int) (100.0*image->resolution.y);
1838         break;
1839       }
1840     }
1841     bmp_info.colors_important=bmp_info.number_colors;
1842     /*
1843       Convert MIFF to BMP raster pixels.
1844     */
1845     pixel_info=AcquireVirtualMemory((size_t) bmp_info.image_size,
1846       sizeof(*pixels));
1847     if (pixel_info == (MemoryInfo *) NULL)
1848       ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1849     pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
1850     (void) memset(pixels,0,(size_t) bmp_info.image_size);
1851     switch (bmp_info.bits_per_pixel)
1852     {
1853       case 1:
1854       {
1855         size_t
1856           bit,
1857           byte;
1858
1859         /*
1860           Convert PseudoClass image to a BMP monochrome image.
1861         */
1862         for (y=0; y < (ssize_t) image->rows; y++)
1863         {
1864           ssize_t
1865             offset;
1866
1867           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1868           if (p == (const Quantum *) NULL)
1869             break;
1870           q=pixels+(image->rows-y-1)*bytes_per_line;
1871           bit=0;
1872           byte=0;
1873           for (x=0; x < (ssize_t) image->columns; x++)
1874           {
1875             byte<<=1;
1876             byte|=GetPixelIndex(image,p) != 0 ? 0x01 : 0x00;
1877             bit++;
1878             if (bit == 8)
1879               {
1880                 *q++=(unsigned char) byte;
1881                 bit=0;
1882                 byte=0;
1883               }
1884              p+=GetPixelChannels(image);
1885            }
1886            if (bit != 0)
1887              {
1888                *q++=(unsigned char) (byte << (8-bit));
1889                x++;
1890              }
1891           offset=(ssize_t) (image->columns+7)/8;
1892           for (x=offset; x < (ssize_t) bytes_per_line; x++)
1893             *q++=0x00;
1894           if (image->previous == (Image *) NULL)
1895             {
1896               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1897                 image->rows);
1898               if (status == MagickFalse)
1899                 break;
1900             }
1901         }
1902         break;
1903       }
1904       case 4:
1905       {
1906         unsigned int
1907           byte,
1908           nibble;
1909
1910         ssize_t
1911           offset;
1912
1913         /*
1914           Convert PseudoClass image to a BMP monochrome image.
1915         */
1916         for (y=0; y < (ssize_t) image->rows; y++)
1917         {
1918           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1919           if (p == (const Quantum *) NULL)
1920             break;
1921           q=pixels+(image->rows-y-1)*bytes_per_line;
1922           nibble=0;
1923           byte=0;
1924           for (x=0; x < (ssize_t) image->columns; x++)
1925           {
1926             byte<<=4;
1927             byte|=((unsigned int) GetPixelIndex(image,p) & 0x0f);
1928             nibble++;
1929             if (nibble == 2)
1930               {
1931                 *q++=(unsigned char) byte;
1932                 nibble=0;
1933                 byte=0;
1934               }
1935             p+=GetPixelChannels(image);
1936           }
1937           if (nibble != 0)
1938             {
1939               *q++=(unsigned char) (byte << 4);
1940               x++;
1941             }
1942           offset=(ssize_t) (image->columns+1)/2;
1943           for (x=offset; x < (ssize_t) bytes_per_line; x++)
1944             *q++=0x00;
1945           if (image->previous == (Image *) NULL)
1946             {
1947               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1948                 image->rows);
1949               if (status == MagickFalse)
1950                 break;
1951             }
1952         }
1953         break;
1954       }
1955       case 8:
1956       {
1957         /*
1958           Convert PseudoClass packet to BMP pixel.
1959         */
1960         for (y=0; y < (ssize_t) image->rows; y++)
1961         {
1962           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1963           if (p == (const Quantum *) NULL)
1964             break;
1965           q=pixels+(image->rows-y-1)*bytes_per_line;
1966           for (x=0; x < (ssize_t) image->columns; x++)
1967           {
1968             *q++=(unsigned char) GetPixelIndex(image,p);
1969             p+=GetPixelChannels(image);
1970           }
1971           for ( ; x < (ssize_t) bytes_per_line; x++)
1972             *q++=0x00;
1973           if (image->previous == (Image *) NULL)
1974             {
1975               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1976                 image->rows);
1977               if (status == MagickFalse)
1978                 break;
1979             }
1980         }
1981         break;
1982       }
1983       case 16:
1984       {
1985         /*
1986           Convert DirectClass packet to BMP BGR888.
1987         */
1988         for (y=0; y < (ssize_t) image->rows; y++)
1989         {
1990           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1991           if (p == (const Quantum *) NULL)
1992             break;
1993           q=pixels+(image->rows-y-1)*bytes_per_line;
1994           for (x=0; x < (ssize_t) image->columns; x++)
1995           {
1996             unsigned short
1997               pixel;
1998
1999             pixel=0;
2000             if (bmp_subtype == ARGB4444)
2001               {
2002                 pixel=(unsigned short) (ScaleQuantumToAny(
2003                   GetPixelAlpha(image,p),15) << 12);
2004                 pixel|=(unsigned short) (ScaleQuantumToAny(
2005                   GetPixelRed(image,p),15) << 8);
2006                 pixel|=(unsigned short) (ScaleQuantumToAny(
2007                   GetPixelGreen(image,p),15) << 4);
2008                 pixel|=(unsigned short) (ScaleQuantumToAny(
2009                   GetPixelBlue(image,p),15));
2010               }
2011             else if (bmp_subtype == RGB565)
2012               {
2013                 pixel=(unsigned short) (ScaleQuantumToAny(
2014                   GetPixelRed(image,p),31) << 11);
2015                 pixel|=(unsigned short) (ScaleQuantumToAny(
2016                   GetPixelGreen(image,p),63) << 5);
2017                 pixel|=(unsigned short) (ScaleQuantumToAny(
2018                   GetPixelBlue(image,p),31));
2019               }
2020             else
2021               {
2022                 if (bmp_subtype == ARGB1555)
2023                   pixel=(unsigned short) (ScaleQuantumToAny(
2024                     GetPixelAlpha(image,p),1) << 15);
2025                 pixel|=(unsigned short) (ScaleQuantumToAny(
2026                   GetPixelRed(image,p),31) << 10);
2027                 pixel|=(unsigned short) (ScaleQuantumToAny(
2028                   GetPixelGreen(image,p),31) << 5);
2029                 pixel|=(unsigned short) (ScaleQuantumToAny(
2030                   GetPixelBlue(image,p),31));
2031               }
2032             *((unsigned short *) q)=pixel;
2033             q+=2;
2034             p+=GetPixelChannels(image);
2035           }
2036           for (x=2L*(ssize_t) image->columns; 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 24:
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             *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
2062             *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
2063             *q++=ScaleQuantumToChar(GetPixelRed(image,p));
2064             p+=GetPixelChannels(image);
2065           }
2066           for (x=3L*(ssize_t) image->columns; x < (ssize_t) bytes_per_line; x++)
2067             *q++=0x00;
2068           if (image->previous == (Image *) NULL)
2069             {
2070               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2071                 image->rows);
2072               if (status == MagickFalse)
2073                 break;
2074             }
2075         }
2076         break;
2077       }
2078       case 32:
2079       {
2080         /*
2081           Convert DirectClass packet to ARGB8888 pixel.
2082         */
2083         for (y=0; y < (ssize_t) image->rows; y++)
2084         {
2085           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
2086           if (p == (const Quantum *) NULL)
2087             break;
2088           q=pixels+(image->rows-y-1)*bytes_per_line;
2089           for (x=0; x < (ssize_t) image->columns; x++)
2090           {
2091             *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
2092             *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
2093             *q++=ScaleQuantumToChar(GetPixelRed(image,p));
2094             *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
2095             p+=GetPixelChannels(image);
2096           }
2097           if (image->previous == (Image *) NULL)
2098             {
2099               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2100                 image->rows);
2101               if (status == MagickFalse)
2102                 break;
2103             }
2104         }
2105         break;
2106       }
2107     }
2108     if ((type > 2) && (bmp_info.bits_per_pixel == 8))
2109       if (image_info->compression != NoCompression)
2110         {
2111           MemoryInfo
2112             *rle_info;
2113
2114           /*
2115             Convert run-length encoded raster pixels.
2116           */
2117           rle_info=AcquireVirtualMemory((size_t) (2*(bytes_per_line+2)+2),
2118             (image->rows+2)*sizeof(*pixels));
2119           if (rle_info == (MemoryInfo *) NULL)
2120             {
2121               pixel_info=RelinquishVirtualMemory(pixel_info);
2122               ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2123             }
2124           bmp_data=(unsigned char *) GetVirtualMemoryBlob(rle_info);
2125           bmp_info.file_size-=bmp_info.image_size;
2126           bmp_info.image_size=(unsigned int) EncodeImage(image,bytes_per_line,
2127             pixels,bmp_data);
2128           bmp_info.file_size+=bmp_info.image_size;
2129           pixel_info=RelinquishVirtualMemory(pixel_info);
2130           pixel_info=rle_info;
2131           pixels=bmp_data;
2132           bmp_info.compression=BI_RLE8;
2133         }
2134     /*
2135       Write BMP for Windows, all versions, 14-byte header.
2136     */
2137     if (image->debug != MagickFalse)
2138       {
2139         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2140           "   Writing BMP version %.20g datastream",(double) type);
2141         if (image->storage_class == DirectClass)
2142           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2143             "   Storage class=DirectClass");
2144         else
2145           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2146             "   Storage class=PseudoClass");
2147         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2148           "   Image depth=%.20g",(double) image->depth);
2149         if (image->alpha_trait != UndefinedPixelTrait)
2150           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2151             "   Matte=True");
2152         else
2153           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2154             "   Matte=MagickFalse");
2155         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2156           "   BMP bits_per_pixel=%.20g",(double) bmp_info.bits_per_pixel);
2157         switch ((int) bmp_info.compression)
2158         {
2159            case BI_RGB:
2160            {
2161              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2162                "   Compression=BI_RGB");
2163              break;
2164            }
2165            case BI_RLE8:
2166            {
2167              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2168                "   Compression=BI_RLE8");
2169              break;
2170            }
2171            case BI_BITFIELDS:
2172            {
2173              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2174                "   Compression=BI_BITFIELDS");
2175              break;
2176            }
2177            default:
2178            {
2179              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2180                "   Compression=UNKNOWN (%u)",bmp_info.compression);
2181              break;
2182            }
2183         }
2184         if (bmp_info.number_colors == 0)
2185           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2186             "   Number_colors=unspecified");
2187         else
2188           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2189             "   Number_colors=%u",bmp_info.number_colors);
2190       }
2191     (void) WriteBlob(image,2,(unsigned char *) "BM");
2192     (void) WriteBlobLSBLong(image,bmp_info.file_size);
2193     (void) WriteBlobLSBLong(image,bmp_info.ba_offset);  /* always 0 */
2194     (void) WriteBlobLSBLong(image,bmp_info.offset_bits);
2195     if (type == 2)
2196       {
2197         /*
2198           Write 12-byte version 2 bitmap header.
2199         */
2200         (void) WriteBlobLSBLong(image,bmp_info.size);
2201         (void) WriteBlobLSBSignedShort(image,(signed short) bmp_info.width);
2202         (void) WriteBlobLSBSignedShort(image,(signed short) bmp_info.height);
2203         (void) WriteBlobLSBShort(image,bmp_info.planes);
2204         (void) WriteBlobLSBShort(image,bmp_info.bits_per_pixel);
2205       }
2206     else
2207       {
2208         /*
2209           Write 40-byte version 3+ bitmap header.
2210         */
2211         (void) WriteBlobLSBLong(image,bmp_info.size);
2212         (void) WriteBlobLSBSignedLong(image,(signed int) bmp_info.width);
2213         (void) WriteBlobLSBSignedLong(image,(signed int) bmp_info.height);
2214         (void) WriteBlobLSBShort(image,bmp_info.planes);
2215         (void) WriteBlobLSBShort(image,bmp_info.bits_per_pixel);
2216         (void) WriteBlobLSBLong(image,bmp_info.compression);
2217         (void) WriteBlobLSBLong(image,bmp_info.image_size);
2218         (void) WriteBlobLSBLong(image,bmp_info.x_pixels);
2219         (void) WriteBlobLSBLong(image,bmp_info.y_pixels);
2220         (void) WriteBlobLSBLong(image,bmp_info.number_colors);
2221         (void) WriteBlobLSBLong(image,bmp_info.colors_important);
2222       }
2223     if ((type > 3) && ((image->alpha_trait != UndefinedPixelTrait) ||
2224         (have_color_info != MagickFalse)))
2225       {
2226         /*
2227           Write the rest of the 108-byte BMP Version 4 header.
2228         */
2229         (void) WriteBlobLSBLong(image,bmp_info.red_mask);
2230         (void) WriteBlobLSBLong(image,bmp_info.green_mask);
2231         (void) WriteBlobLSBLong(image,bmp_info.blue_mask);
2232         (void) WriteBlobLSBLong(image,bmp_info.alpha_mask);
2233         (void) WriteBlobLSBLong(image,0x73524742U);  /* sRGB */
2234         (void) WriteBlobLSBLong(image,(unsigned int)
2235           (image->chromaticity.red_primary.x*0x40000000));
2236         (void) WriteBlobLSBLong(image,(unsigned int)
2237           (image->chromaticity.red_primary.y*0x40000000));
2238         (void) WriteBlobLSBLong(image,(unsigned int)
2239           ((1.000f-(image->chromaticity.red_primary.x+
2240           image->chromaticity.red_primary.y))*0x40000000));
2241         (void) WriteBlobLSBLong(image,(unsigned int)
2242           (image->chromaticity.green_primary.x*0x40000000));
2243         (void) WriteBlobLSBLong(image,(unsigned int)
2244           (image->chromaticity.green_primary.y*0x40000000));
2245         (void) WriteBlobLSBLong(image,(unsigned int)
2246           ((1.000f-(image->chromaticity.green_primary.x+
2247           image->chromaticity.green_primary.y))*0x40000000));
2248         (void) WriteBlobLSBLong(image,(unsigned int)
2249           (image->chromaticity.blue_primary.x*0x40000000));
2250         (void) WriteBlobLSBLong(image,(unsigned int)
2251           (image->chromaticity.blue_primary.y*0x40000000));
2252         (void) WriteBlobLSBLong(image,(unsigned int)
2253           ((1.000f-(image->chromaticity.blue_primary.x+
2254           image->chromaticity.blue_primary.y))*0x40000000));
2255         (void) WriteBlobLSBLong(image,(unsigned int)
2256           (bmp_info.gamma_scale.x*0x10000));
2257         (void) WriteBlobLSBLong(image,(unsigned int)
2258           (bmp_info.gamma_scale.y*0x10000));
2259         (void) WriteBlobLSBLong(image,(unsigned int)
2260           (bmp_info.gamma_scale.z*0x10000));
2261         if ((image->rendering_intent != UndefinedIntent) ||
2262             (profile != (StringInfo *) NULL))
2263           {
2264             ssize_t
2265               intent;
2266
2267             switch ((int) image->rendering_intent)
2268             {
2269               case SaturationIntent:
2270               {
2271                 intent=LCS_GM_BUSINESS;
2272                 break;
2273               }
2274               case RelativeIntent:
2275               {
2276                 intent=LCS_GM_GRAPHICS;
2277                 break;
2278               }
2279               case PerceptualIntent:
2280               {
2281                 intent=LCS_GM_IMAGES;
2282                 break;
2283               }
2284               case AbsoluteIntent:
2285               {
2286                 intent=LCS_GM_ABS_COLORIMETRIC;
2287                 break;
2288               }
2289               default:
2290               {
2291                 intent=0;
2292                 break;
2293               }
2294             }
2295             (void) WriteBlobLSBLong(image,(unsigned int) intent);
2296             (void) WriteBlobLSBLong(image,0x00);  /* dummy profile data */
2297             (void) WriteBlobLSBLong(image,0x00);  /* dummy profile length */
2298             (void) WriteBlobLSBLong(image,0x00);  /* reserved */
2299           }
2300       }
2301     if (image->storage_class == PseudoClass)
2302       {
2303         unsigned char
2304           *bmp_colormap;
2305
2306         /*
2307           Dump colormap to file.
2308         */
2309         if (image->debug != MagickFalse)
2310           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2311             "  Colormap: %.20g entries",(double) image->colors);
2312         bmp_colormap=(unsigned char *) AcquireQuantumMemory((size_t) (1UL <<
2313           bmp_info.bits_per_pixel),4*sizeof(*bmp_colormap));
2314         if (bmp_colormap == (unsigned char *) NULL)
2315           ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2316         q=bmp_colormap;
2317         for (i=0; i < (ssize_t) MagickMin((ssize_t) image->colors,(ssize_t) bmp_info.number_colors); i++)
2318         {
2319           *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].blue));
2320           *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].green));
2321           *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].red));
2322           if (type > 2)
2323             *q++=(unsigned char) 0x0;
2324         }
2325         for ( ; i < (ssize_t) (1UL << bmp_info.bits_per_pixel); i++)
2326         {
2327           *q++=(unsigned char) 0x00;
2328           *q++=(unsigned char) 0x00;
2329           *q++=(unsigned char) 0x00;
2330           if (type > 2)
2331             *q++=(unsigned char) 0x00;
2332         }
2333         if (type <= 2)
2334           (void) WriteBlob(image,(size_t) (3*(1L << bmp_info.bits_per_pixel)),
2335             bmp_colormap);
2336         else
2337           (void) WriteBlob(image,(size_t) (4*(1L << bmp_info.bits_per_pixel)),
2338             bmp_colormap);
2339         bmp_colormap=(unsigned char *) RelinquishMagickMemory(bmp_colormap);
2340       }
2341     if (image->debug != MagickFalse)
2342       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2343         "  Pixels:  %u bytes",bmp_info.image_size);
2344     (void) WriteBlob(image,(size_t) bmp_info.image_size,pixels);
2345     pixel_info=RelinquishVirtualMemory(pixel_info);
2346     if (GetNextImageInList(image) == (Image *) NULL)
2347       break;
2348     image=SyncNextImageInList(image);
2349     status=SetImageProgress(image,SaveImagesTag,scene++,imageListLength);
2350     if (status == MagickFalse)
2351       break;
2352   } while (image_info->adjoin != MagickFalse);
2353   (void) CloseBlob(image);
2354   return(MagickTrue);
2355 }