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