root / ImageMagick / trunk / coders / bmp.c

Revision 12035, 67.1 kB (checked in by cristy, 6 days ago)
Line 
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%                                John Cristy                                  %
17%                            Glenn Randers-Pehrson                            %
18%                               December 2001                                 %
19%                                                                             %
20%                                                                             %
21%  Copyright 1999-2008 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 "magick/studio.h"
44#include "magick/blob.h"
45#include "magick/blob-private.h"
46#include "magick/color-private.h"
47#include "magick/colorspace.h"
48#include "magick/exception.h"
49#include "magick/exception-private.h"
50#include "magick/image.h"
51#include "magick/image-private.h"
52#include "magick/list.h"
53#include "magick/log.h"
54#include "magick/magick.h"
55#include "magick/memory_.h"
56#include "magick/monitor.h"
57#include "magick/monitor-private.h"
58#include "magick/profile.h"
59#include "magick/quantum-private.h"
60#include "magick/static.h"
61#include "magick/string_.h"
62#include "magick/module.h"
63#include "magick/transform.h"
64
65/*
66  Macro definitions (from Windows wingdi.h).
67*/
68#undef BI_JPEG
69#define BI_JPEG  4
70#undef BI_PNG
71#define BI_PNG  5
72#if !defined(__WINDOWS__) || defined(__MINGW32__)
73#define BI_RGB  0
74#define BI_RLE8  1
75#define BI_RLE4  2
76#define BI_BITFIELDS  3
77
78#define LCS_CALIBRATED_RBG  0
79#define LCS_sRGB  1
80#define LCS_WINDOWS_COLOR_SPACE  2
81#define PROFILE_LINKED  3
82#define PROFILE_EMBEDDED  4
83
84#define LCS_GM_BUSINESS  1  /* Saturation */
85#define LCS_GM_GRAPHICS  2  /* Relative */
86#define LCS_GM_IMAGES  4  /* Perceptual */
87#define LCS_GM_ABS_COLORIMETRIC  8  /* Absolute */
88#endif
89
90/*
91  Typedef declarations.
92*/
93typedef struct _BMPInfo
94{
95  unsigned long
96    file_size,
97    ba_offset,
98    offset_bits,
99    size;
100
101  long
102    width,
103    height;
104
105  unsigned short
106    planes,
107    bits_per_pixel;
108
109  unsigned long
110    compression,
111    image_size,
112    x_pixels,
113    y_pixels,
114    number_colors,
115    red_mask,
116    green_mask,
117    blue_mask,
118    alpha_mask,
119    colors_important;
120
121  long
122    colorspace;
123
124  PrimaryInfo
125    red_primary,
126    green_primary,
127    blue_primary,
128    gamma_scale;
129} BMPInfo;
130
131/*
132  Forward declarations.
133*/
134static MagickBooleanType
135  WriteBMPImage(const ImageInfo *,Image *);
136
137/*
138%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
139%                                                                             %
140%                                                                             %
141%                                                                             %
142%   D e c o d e I m a g e                                                     %
143%                                                                             %
144%                                                                             %
145%                                                                             %
146%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
147%
148%  DecodeImage unpacks the packed image pixels into runlength-encoded
149%  pixel packets.
150%
151%  The format of the DecodeImage method is:
152%
153%      MagickBooleanType DecodeImage(Image *image,
154%        const unsigned long compression,unsigned char *pixels)
155%
156%  A description of each parameter follows:
157%
158%    o image: the address of a structure of type Image.
159%
160%    o compression:  Zero means uncompressed.  A value of 1 means the
161%      compressed pixels are runlength encoded for a 256-color bitmap.
162%      A value of 2 means a 16-color bitmap.  A value of 3 means bitfields
163%      encoding.
164%
165%    o pixels:  The address of a byte (8 bits) array of pixel data created by
166%      the decoding process.
167%
168*/
169
170static inline long MagickAbsoluteValue(const long x)
171{
172  if (x < 0)
173    return(-x);
174  return(x);
175}
176
177static inline size_t MagickMax(const size_t x,const size_t y)
178{
179  if (x > y)
180    return(x);
181  return(y);
182}
183
184static inline long MagickMin(const long x,const long y)
185{
186  if (x < y)
187    return(x);
188  return(y);
189}
190
191static MagickBooleanType DecodeImage(Image *image,
192  const unsigned long compression,unsigned char *pixels)
193{
194  int
195    count;
196
197  long
198    y;
199
200  register long
201    i,
202    x;
203
204  register unsigned char
205    *p,
206    *q;
207
208  unsigned char
209    byte;
210
211  assert(image != (Image *) NULL);
212  assert(image->signature == MagickSignature);
213  if (image->debug != MagickFalse)
214    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
215  assert(pixels != (unsigned char *) NULL);
216  (void) ResetMagickMemory(pixels,0,(size_t) image->columns*image->rows*
217    sizeof(*pixels));
218  byte=0;
219  x=0;
220  p=pixels;
221  q=pixels+(size_t) image->columns*image->rows;
222  for (y=0; y < (long) image->rows; )
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=MagickMin(count,(int) (q-p));
235        byte=(unsigned char) ReadBlobByte(image);
236        if (compression == BI_RLE8)
237          {
238            for (i=0; i < count; i++)
239              *p++=(unsigned char) byte;
240          }
241        else
242          {
243            for (i=0; i < 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 == 0x01)
256          return(MagickTrue);
257        switch (count)
258        {
259          case 0x00:
260          {
261            /*
262              End of line.
263            */
264            x=0;
265            y++;
266            p=pixels+y*image->columns;
267            break;
268          }
269          case 0x02:
270          {
271            /*
272              Delta mode.
273            */
274            x+=ReadBlobByte(image);
275            y+=ReadBlobByte(image);
276            p=pixels+y*image->columns+x;
277            break;
278          }
279          default:
280          {
281            /*
282              Absolute mode.
283            */
284            count=MagickMin(count,(int) (q-p));
285            if (compression == BI_RLE8)
286              for (i=0; i < count; i++)
287                *p++=(unsigned char) ReadBlobByte(image);
288            else
289              for (i=0; i < count; i++)
290              {
291                if ((i & 0x01) == 0)
292                  byte=(unsigned char) ReadBlobByte(image);
293                *p++=(unsigned char)
294                  ((i & 0x01) != 0 ? (byte & 0x0f) : ((byte >> 4) & 0x0f));
295              }
296            x+=count;
297            /*
298              Read pad byte.
299            */
300            if (compression == BI_RLE8)
301              {
302                if ((count & 0x01) != 0)
303                  (void) ReadBlobByte(image);
304              }
305            else
306              if (((count & 0x03) == 1) || ((count & 0x03) == 2))
307                (void) ReadBlobByte(image);
308            break;
309          }
310        }
311      }
312    if (SetImageProgress(image,LoadImageTag,y,image->rows) == MagickFalse)
313      break;
314  }
315  (void) ReadBlobByte(image);  /* end of line */
316  (void) ReadBlobByte(image);
317  return(MagickTrue);
318}
319
320/*
321%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
322%                                                                             %
323%                                                                             %
324%                                                                             %
325%   E n c o d e I m a g e                                                     %
326%                                                                             %
327%                                                                             %
328%                                                                             %
329%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
330%
331%  EncodeImage compresses pixels using a runlength encoded format.
332%
333%  The format of the EncodeImage method is:
334%
335%    static MagickBooleanType EncodeImage(Image *image,
336%      const unsigned long bytes_per_line,const unsigned char *pixels,
337%      unsigned char *compressed_pixels)
338%
339%  A description of each parameter follows:
340%
341%    o image:  The image.
342%
343%    o bytes_per_line: the number of bytes in a scanline of compressed pixels
344%
345%    o pixels:  The address of a byte (8 bits) array of pixel data created by
346%      the compression process.
347%
348%    o compressed_pixels:  The address of a byte (8 bits) array of compressed
349%      pixel data.
350%
351*/
352static size_t EncodeImage(Image *image,const unsigned long bytes_per_line,
353  const unsigned char *pixels,unsigned char *compressed_pixels)
354{
355  long
356    y;
357
358  MagickBooleanType
359    status;
360
361  register const unsigned char
362    *p;
363
364  register long
365    i,
366    x;
367
368  register unsigned char
369    *q;
370
371  /*
372    Runlength encode pixels.
373  */
374  assert(image != (Image *) NULL);
375  assert(image->signature == MagickSignature);
376  if (image->debug != MagickFalse)
377    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
378  assert(pixels != (const unsigned char *) NULL);
379  assert(compressed_pixels != (unsigned char *) NULL);
380  p=pixels;
381  q=compressed_pixels;
382  i=0;
383  for (y=0; y < (long) image->rows; y++)
384  {
385    for (x=0; x < (long) bytes_per_line; x+=i)
386    {
387      /*
388        Determine runlength.
389      */
390      for (i=1; ((x+i) < (long) bytes_per_line); i++)
391        if ((i == 255) || (*(p+i) != *p))
392          break;
393      *q++=(unsigned char) i;
394      *q++=(*p);
395      p+=i;
396    }
397    /*
398      End of line.
399    */
400    *q++=(unsigned char) 0x00;
401    *q++=(unsigned char) 0x00;
402    status=SetImageProgress(image,SaveImageTag,y,image->rows);
403    if (status == MagickFalse)
404      break;
405  }
406  /*
407    End of bitmap.
408  */
409  *q++=(unsigned char) 0x00;
410  *q++=(unsigned char) 0x01;
411  return((size_t) (q-compressed_pixels));
412}
413
414/*
415%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
416%                                                                             %
417%                                                                             %
418%                                                                             %
419%   I s B M P                                                                 %
420%                                                                             %
421%                                                                             %
422%                                                                             %
423%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
424%
425%  IsBMP() returns MagickTrue if the image format type, identified by the
426%  magick string, is BMP.
427%
428%  The format of the IsBMP method is:
429%
430%      MagickBooleanType IsBMP(const unsigned char *magick,const size_t length)
431%
432%  A description of each parameter follows:
433%
434%    o magick: This string is generally the first few bytes of an image file
435%      or blob.
436%
437%    o length: Specifies the length of the magick string.
438%
439*/
440static MagickBooleanType IsBMP(const unsigned char *magick,const size_t length)
441{
442  if (length < 2)
443    return(MagickFalse);
444  if ((LocaleNCompare((char *) magick,"BA",2) == 0) ||
445      (LocaleNCompare((char *) magick,"BM",2) == 0) ||
446      (LocaleNCompare((char *) magick,"IC",2) == 0) ||
447      (LocaleNCompare((char *) magick,"PI",2) == 0) ||
448      (LocaleNCompare((char *) magick,"CI",2) == 0) ||
449      (LocaleNCompare((char *) magick,"CP",2) == 0))
450    return(MagickTrue);
451  return(MagickFalse);
452}
453
454/*
455%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
456%                                                                             %
457%                                                                             %
458%                                                                             %
459%   R e a d B M P I m a g e                                                   %
460%                                                                             %
461%                                                                             %
462%                                                                             %
463%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
464%
465%  ReadBMPImage() reads a Microsoft Windows bitmap image file, Version
466%  2, 3 (for Windows or NT), or 4, and  returns it.  It allocates the memory
467%  necessary for the new Image structure and returns a pointer to the new
468%  image.
469%
470%  The format of the ReadBMPImage method is:
471%
472%      image=ReadBMPImage(image_info)
473%
474%  A description of each parameter follows:
475%
476%    o image_info: the image info.
477%
478%    o exception: return any errors or warnings in this structure.
479%
480*/
481
482static Image *ReadBMPImage(const ImageInfo *image_info,ExceptionInfo *exception)
483{
484  BMPInfo
485    bmp_info;
486
487  Image
488    *image;
489
490  IndexPacket
491    index;
492
493  long
494    y;
495
496  MagickBooleanType
497    status;
498
499  MagickOffsetType
500    offset,
501    start_position;
502
503  register IndexPacket
504    *indexes;
505
506  register long
507    x;
508
509  register PixelPacket
510    *q;
511
512  register long
513    i;
514
515  register unsigned char
516    *p;
517
518  ssize_t
519    count;
520
521  size_t
522    length;
523
524  unsigned char
525    magick[12],
526    *pixels;
527
528  unsigned long
529    bit,
530    blue,
531    bytes_per_line,
532    green,
533    opacity,
534    red;
535
536  /*
537    Open image file.
538  */
539  assert(image_info != (const ImageInfo *) NULL);
540  assert(image_info->signature == MagickSignature);
541  if (image_info->debug != MagickFalse)
542    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
543      image_info->filename);
544  assert(exception != (ExceptionInfo *) NULL);
545  assert(exception->signature == MagickSignature);
546  image=AcquireImage(image_info);
547  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
548  if (status == MagickFalse)
549    {
550      image=DestroyImageList(image);
551      return((Image *) NULL);
552    }
553  /*
554    Determine if this a BMP file.
555  */
556  (void) ResetMagickMemory(&bmp_info,0,sizeof(bmp_info));
557  bmp_info.ba_offset=0;
558  start_position=0;
559  count=ReadBlob(image,2,magick);
560  do
561  {
562    LongPixelPacket
563      shift;
564
565    PixelPacket
566      quantum_bits;
567
568    unsigned long
569      profile_data,
570      profile_size;
571
572    /*
573      Verify BMP identifier.
574    */
575    if (bmp_info.ba_offset == 0)
576      start_position=TellBlob(image)-2;
577    bmp_info.ba_offset=0;
578    while (LocaleNCompare((char *) magick,"BA",2) == 0)
579    {
580      bmp_info.file_size=ReadBlobLSBLong(image);
581      bmp_info.ba_offset=ReadBlobLSBLong(image);
582      bmp_info.offset_bits=ReadBlobLSBLong(image);
583      count=ReadBlob(image,2,magick);
584      if (count != 2)
585        break;
586    }
587    if (image->debug != MagickFalse)
588      (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Magick: %c%c",
589        magick[0],magick[1]);
590    if ((count == 0) || ((LocaleNCompare((char *) magick,"BM",2) != 0) &&
591        (LocaleNCompare((char *) magick,"CI",2) != 0)))
592      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
593    bmp_info.file_size=ReadBlobLSBLong(image);
594    (void) ReadBlobLSBLong(image);
595    bmp_info.offset_bits=ReadBlobLSBLong(image);
596    bmp_info.size=ReadBlobLSBLong(image);
597    if (image->debug != MagickFalse)
598      (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  BMP size: %lu",
599        bmp_info.size);
600    if (bmp_info.size == 12)
601      {
602        /*
603          OS/2 BMP image file.
604        */
605        bmp_info.width=(short) ReadBlobLSBShort(image);
606        bmp_info.height=(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: %ldx%ld",bmp_info.width,bmp_info.height);
621          }
622      }
623    else
624      {
625        /*
626          Microsoft Windows BMP image file.
627        */
628        if (bmp_info.size < 40)
629          ThrowReaderException(CorruptImageError,"NonOS2HeaderSizeError");
630        bmp_info.width=(long) ReadBlobLSBLong(image);
631        bmp_info.height=(long) ReadBlobLSBLong(image);
632        bmp_info.planes=ReadBlobLSBShort(image);
633        bmp_info.bits_per_pixel=ReadBlobLSBShort(image);
634        bmp_info.compression=ReadBlobLSBLong(image);
635        bmp_info.image_size=ReadBlobLSBLong(image);
636        bmp_info.x_pixels=ReadBlobLSBLong(image);
637        bmp_info.y_pixels=ReadBlobLSBLong(image);
638        bmp_info.number_colors=ReadBlobLSBLong(image);
639        bmp_info.colors_important=ReadBlobLSBLong(image);
640        profile_data=0;
641        profile_size=0;
642        if (image->debug != MagickFalse)
643          {
644            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
645              "  Format: MS Windows bitmap");
646            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
647              "  Geometry: %ldx%ld",bmp_info.width,bmp_info.height);
648            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
649              "  Bits per pixel: %d",bmp_info.bits_per_pixel);
650            switch ((int) bmp_info.compression)
651            {
652              case BI_RGB:
653              {
654                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
655                  "  Compression: BI_RGB");
656                break;
657              }
658              case BI_RLE4:
659              {
660                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
661                  "  Compression: BI_RLE4");
662                break;
663              }
664              case BI_RLE8:
665              {
666                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
667                  "  Compression: BI_RLE8");
668                break;
669              }
670              case BI_BITFIELDS:
671              {
672                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
673                  "  Compression: BI_BITFIELDS");
674                break;
675              }
676              case BI_PNG:
677              {
678                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
679                  "  Compression: BI_PNG");
680                break;
681              }
682              case BI_JPEG:
683              {
684                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
685                  "  Compression: BI_JPEG");
686                break;
687              }
688              default:
689              {
690                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
691                  "  Compression: UNKNOWN (%lu)",bmp_info.compression);
692              }
693            }
694            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
695              "  Number of colors: %lu",bmp_info.number_colors);
696          }
697        bmp_info.red_mask=ReadBlobLSBLong(image);
698        bmp_info.green_mask=ReadBlobLSBLong(image);
699        bmp_info.blue_mask=ReadBlobLSBLong(image);
700        if (bmp_info.size > 40)
701          {
702            double
703              sum;
704
705            /*
706              Read color management information.
707            */
708            bmp_info.alpha_mask=ReadBlobLSBLong(image);
709            bmp_info.colorspace=(long) ReadBlobLSBLong(image);
710            /*
711              Decode 2^30 fixed point formatted CIE primaries.
712            */
713            bmp_info.red_primary.x=(double) ReadBlobLSBLong(image)/0x3ffffff;
714            bmp_info.red_primary.y=(double) ReadBlobLSBLong(image)/0x3ffffff;
715            bmp_info.red_primary.z=(double) ReadBlobLSBLong(image)/0x3ffffff;
716            bmp_info.green_primary.x=(double) ReadBlobLSBLong(image)/0x3ffffff;
717            bmp_info.green_primary.y=(double) ReadBlobLSBLong(image)/0x3ffffff;
718            bmp_info.green_primary.z=(double) ReadBlobLSBLong(image)/0x3ffffff;
719            bmp_info.blue_primary.x=(double) ReadBlobLSBLong(image)/0x3ffffff;
720            bmp_info.blue_primary.y=(double) ReadBlobLSBLong(image)/0x3ffffff;
721            bmp_info.blue_primary.z=(double) ReadBlobLSBLong(image)/0x3ffffff;
722            sum=bmp_info.red_primary.x+bmp_info.red_primary.x+
723              bmp_info.red_primary.z;
724            image->chromaticity.red_primary.x/=sum;
725            image->chromaticity.red_primary.y/=sum;
726            sum=bmp_info.green_primary.x+bmp_info.green_primary.x+
727              bmp_info.green_primary.z;
728            image->chromaticity.green_primary.x/=sum;
729            image->chromaticity.green_primary.y/=sum;
730            sum=bmp_info.blue_primary.x+bmp_info.blue_primary.x+
731              bmp_info.blue_primary.z;
732            image->chromaticity.blue_primary.x/=sum;
733            image->chromaticity.blue_primary.y/=sum;
734            /*
735              Decode 16^16 fixed point formatted gamma_scales.
736            */
737            bmp_info.gamma_scale.x=(double) ReadBlobLSBLong(image)/0xffff;
738            bmp_info.gamma_scale.y=(double) ReadBlobLSBLong(image)/0xffff;
739            bmp_info.gamma_scale.z=(double) ReadBlobLSBLong(image)/0xffff;
740            /*
741              Compute a single gamma from the BMP 3-channel gamma.
742            */
743            image->gamma=(bmp_info.gamma_scale.x+bmp_info.gamma_scale.y+
744              bmp_info.gamma_scale.z)/3.0;
745          }
746        if (bmp_info.size > 108)
747          {
748            unsigned long
749              intent;
750
751            /*
752              Read BMP Version 5 color management information.
753            */
754            intent=ReadBlobLSBLong(image);
755            switch ((int) intent)
756            {
757              case LCS_GM_BUSINESS:
758              {
759                image->rendering_intent=SaturationIntent;
760                break;
761              }
762              case LCS_GM_GRAPHICS:
763              {
764                image->rendering_intent=RelativeIntent;
765                break;
766              }
767              case LCS_GM_IMAGES:
768              {
769                image->rendering_intent=PerceptualIntent;
770                break;
771              }
772              case LCS_GM_ABS_COLORIMETRIC:
773              {
774                image->rendering_intent=AbsoluteIntent;
775                break;
776              }
777            }
778            profile_data=ReadBlobLSBLong(image);
779            profile_size=ReadBlobLSBLong(image);
780            (void) ReadBlobLSBLong(image);  /* Reserved byte */
781          }
782      }
783    if ((bmp_info.compression != BI_RGB) &&
784        ((MagickSizeType) bmp_info.file_size != GetBlobSize(image)))
785      (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError,
786        "LengthAndFilesizeDoNotMatch","`%s'",image->filename);
787    if (bmp_info.width <= 0)
788      ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
789    if (bmp_info.height == 0)
790      ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
791    if (bmp_info.planes != 1)
792      ThrowReaderException(CorruptImageError,"StaticPlanesValueNotEqualToOne");
793    if ((bmp_info.bits_per_pixel != 1) && (bmp_info.bits_per_pixel != 4) &&
794        (bmp_info.bits_per_pixel != 8) && (bmp_info.bits_per_pixel != 16) &&
795        (bmp_info.bits_per_pixel != 24) && (bmp_info.bits_per_pixel != 32))
796      ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
797    if (bmp_info.number_colors > (1UL << bmp_info.bits_per_pixel))
798      {
799        if (bmp_info.bits_per_pixel < 24)
800          ThrowReaderException(CorruptImageError,"UnrecognizedNumberOfColors");
801        bmp_info.number_colors=0;
802      }
803    if (bmp_info.compression > 3)
804      ThrowReaderException(CorruptImageError,"UnrecognizedImageCompression");
805    if ((bmp_info.compression == 1) && (bmp_info.bits_per_pixel != 8))
806      ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
807    if ((bmp_info.compression == 2) && (bmp_info.bits_per_pixel != 4))
808      ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
809    if ((bmp_info.compression == 3) && (bmp_info.bits_per_pixel < 16))
810      ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
811    switch (bmp_info.compression)
812    {
813      case BI_RGB:
814      case BI_RLE8:
815      case BI_RLE4:
816      case BI_BITFIELDS:
817        break;
818      case BI_JPEG:
819        ThrowReaderException(CoderError,"JPEGCompressNotSupported");
820      case BI_PNG:
821        ThrowReaderException(CoderError,"PNGCompressNotSupported");
822      default:
823        ThrowReaderException(CorruptImageError,"UnrecognizedImageCompression");
824    }
825    image->columns=(unsigned long) MagickAbsoluteValue(bmp_info.width);
826    image->rows=(unsigned long) MagickAbsoluteValue(bmp_info.height);
827    image->depth=8;
828    image->matte=bmp_info.alpha_mask != 0 ? MagickTrue : MagickFalse;
829    if ((bmp_info.number_colors != 0) || (bmp_info.bits_per_pixel < 16))
830      {
831        image->storage_class=PseudoClass;
832        image->colors=bmp_info.number_colors;
833        if (image->colors == 0)
834          image->colors=1L << bmp_info.bits_per_pixel;
835      }
836    if (image->storage_class == PseudoClass)
837      {
838        unsigned char
839          *bmp_colormap;
840
841        size_t
842          packet_size;
843
844        /*
845          Read BMP raster colormap.
846        */
847        if (image->debug != MagickFalse)
848          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
849            "  Reading colormap of %ld colors",image->colors);
850        if (AcquireImageColormap(image,image->colors) == MagickFalse)
851          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
852        bmp_colormap=(unsigned char *) AcquireQuantumMemory((size_t)
853          image->colors,4*sizeof(*bmp_colormap));
854        if (bmp_colormap == (unsigned char *) NULL)
855          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
856        if ((bmp_info.size == 12) || (bmp_info.size == 64))
857          packet_size=3;
858        else
859          packet_size=4;
860        offset=SeekBlob(image,start_position+14+bmp_info.size,SEEK_SET);
861        if (offset < 0)
862          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
863        count=ReadBlob(image,packet_size*image->colors,bmp_colormap);
864        if (count != (ssize_t) (packet_size*image->colors))
865          ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
866        p=bmp_colormap;
867        for (i=0; i < (long) image->colors; i++)
868        {
869          image->colormap[i].blue=ScaleCharToQuantum(*p++);
870          image->colormap[i].green=ScaleCharToQuantum(*p++);
871          image->colormap[i].red=ScaleCharToQuantum(*p++);
872          if (packet_size == 4)
873            p++;
874        }
875        bmp_colormap=(unsigned char *) RelinquishMagickMemory(bmp_colormap);
876      }
877    if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
878      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
879        break;
880    /*
881      Read image data.
882    */
883    if (SetImageExtent(image,0,0) == MagickFalse)
884      {
885        InheritException(exception,&image->exception);
886        return(DestroyImageList(image));
887      }
888    offset=SeekBlob(image,start_position+bmp_info.offset_bits,SEEK_SET);
889    if (offset < 0)
890      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
891    if (bmp_info.compression == BI_RLE4)
892      bmp_info.bits_per_pixel<<=1;
893    bytes_per_line=4*((image->columns*bmp_info.bits_per_pixel+31)/32);
894    length=(size_t) bytes_per_line*image->rows;
895    pixels=(unsigned char *) AcquireQuantumMemory((size_t) image->rows,
896      MagickMax(bytes_per_line,image->columns+256UL)*sizeof(*pixels));
897    if (pixels == (unsigned char *) NULL)
898      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
899    if ((bmp_info.compression == BI_RGB) ||
900        (bmp_info.compression == BI_BITFIELDS))
901      {
902        if (image->debug != MagickFalse)
903          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
904            "  Reading pixels (%ld bytes)",(long) length);
905        count=ReadBlob(image,length,pixels);
906        if (count != (ssize_t) length)
907          ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
908      }
909    else
910      {
911        /*
912          Convert run-length encoded raster pixels.
913        */
914        status=DecodeImage(image,bmp_info.compression,pixels);
915        if (status == MagickFalse)
916          ThrowReaderException(CorruptImageError,
917            "UnableToRunlengthDecodeImage");
918      }
919    /*
920      Initialize image structure.
921    */
922    image->x_resolution=(double) bmp_info.x_pixels/100.0;
923    image->y_resolution=(double) bmp_info.y_pixels/100.0;
924    image->units=PixelsPerCentimeterResolution;
925    /*
926      Convert BMP raster image to pixel packets.
927    */
928    if (bmp_info.compression == BI_RGB)
929      {
930        bmp_info.alpha_mask=0;
931        bmp_info.red_mask=0x00ff0000UL;
932        bmp_info.green_mask=0x0000ff00UL;
933        bmp_info.blue_mask=0x000000ffUL;
934        if (bmp_info.bits_per_pixel == 16)
935          {
936            /*
937              RGB555.
938            */
939            bmp_info.red_mask=0x00007c00UL;
940            bmp_info.green_mask=0x000003e0UL;
941            bmp_info.blue_mask=0x0000001fUL;
942          }
943      }
944    if ((bmp_info.bits_per_pixel == 16) || (bmp_info.bits_per_pixel == 32))
945      {
946        register unsigned long
947          sample;
948
949        /*
950          Get shift and quantum bits info from bitfield masks.
951        */
952        (void) ResetMagickMemory(&shift,0,sizeof(shift));
953        (void) ResetMagickMemory(&quantum_bits,0,sizeof(quantum_bits));
954        if (bmp_info.red_mask != 0)
955          while (((bmp_info.red_mask << shift.red) & 0x80000000UL) == 0)
956            shift.red++;
957        if (bmp_info.green_mask != 0)
958          while (((bmp_info.green_mask << shift.green) & 0x80000000UL) == 0)
959            shift.green++;
960        if (bmp_info.blue_mask != 0)
961          while (((bmp_info.blue_mask << shift.blue) & 0x80000000UL) == 0)
962            shift.blue++;
963        if (bmp_info.alpha_mask != 0)
964          while (((bmp_info.alpha_mask << shift.opacity) & 0x80000000UL) == 0)
965            shift.opacity++;
966        sample=shift.red;
967        while (((bmp_info.red_mask << sample) & 0x80000000UL) != 0)
968          sample++;
969        quantum_bits.red=(Quantum) (sample-shift.red);
970        sample=shift.green;
971        while (((bmp_info.green_mask << sample) & 0x80000000UL) != 0)
972