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