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