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