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