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