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