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