root / ImageMagick / branches / ImageMagick-6.3.6 / coders / bmp.c

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