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