1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3%                                                                             %
4%                                                                             %
5%                                                                             %
6%                            DDDD   IIIII  BBBB                               %
7%                            D   D    I    B   B                              %
8%                            D   D    I    BBBB                               %
9%                            D   D    I    B   B                              %
10%                            DDDD   IIIII  BBBB                               %
11%                                                                             %
12%                                                                             %
13%                   Read/Write Windows DIB Image Format                       %
14%                                                                             %
15%                              Software Design                                %
16%                                   Cristy                                    %
17%                                 July 1992                                   %
18%                                                                             %
19%                                                                             %
20%  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
21%  dedicated to making software imaging solutions freely available.           %
22%                                                                             %
23%  You may not use this file except in compliance with the License.  You may  %
24%  obtain a copy of the License at                                            %
25%                                                                             %
26%    http://www.imagemagick.org/script/license.php                            %
27%                                                                             %
28%  Unless required by applicable law or agreed to in writing, software        %
29%  distributed under the License is distributed on an "AS IS" BASIS,          %
30%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
31%  See the License for the specific language governing permissions and        %
32%  limitations under the License.                                             %
33%                                                                             %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36%
37*/
38
39/*
40  Include declarations.
41*/
42#include "MagickCore/studio.h"
43#include "MagickCore/attribute.h"
44#include "MagickCore/blob.h"
45#include "MagickCore/blob-private.h"
46#include "MagickCore/cache.h"
47#include "MagickCore/color.h"
48#include "MagickCore/color-private.h"
49#include "MagickCore/colormap.h"
50#include "MagickCore/colormap-private.h"
51#include "MagickCore/colorspace.h"
52#include "MagickCore/colorspace-private.h"
53#include "MagickCore/draw.h"
54#include "MagickCore/exception.h"
55#include "MagickCore/exception-private.h"
56#include "MagickCore/geometry.h"
57#include "MagickCore/image.h"
58#include "MagickCore/image-private.h"
59#include "MagickCore/list.h"
60#include "MagickCore/log.h"
61#include "MagickCore/magick.h"
62#include "MagickCore/memory_.h"
63#include "MagickCore/monitor.h"
64#include "MagickCore/monitor-private.h"
65#include "MagickCore/pixel-accessor.h"
66#include "MagickCore/quantum-private.h"
67#include "MagickCore/static.h"
68#include "MagickCore/string_.h"
69#include "MagickCore/module.h"
70#include "MagickCore/transform.h"
71
72/*
73  Typedef declarations.
74*/
75typedef struct _DIBInfo
76{
77  size_t
78    size;
79
80  ssize_t
81    width,
82    height;
83
84  unsigned short
85    planes,
86    bits_per_pixel;
87
88  size_t
89    compression,
90    image_size,
91    x_pixels,
92    y_pixels,
93    number_colors,
94    red_mask,
95    green_mask,
96    blue_mask,
97    alpha_mask,
98    colors_important;
99
100  ssize_t
101    colorspace;
102
103  PointInfo
104    red_primary,
105    green_primary,
106    blue_primary,
107    gamma_scale;
108} DIBInfo;
109
110/*
111  Forward declarations.
112*/
113static MagickBooleanType
114  WriteDIBImage(const ImageInfo *,Image *,ExceptionInfo *);
115
116/*
117%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
118%                                                                             %
119%                                                                             %
120%                                                                             %
121%   D e c o d e I m a g e                                                     %
122%                                                                             %
123%                                                                             %
124%                                                                             %
125%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126%
127%  DecodeImage unpacks the packed image pixels into runlength-encoded
128%  pixel packets.
129%
130%  The format of the DecodeImage method is:
131%
132%      MagickBooleanType DecodeImage(Image *image,
133%        const MagickBooleanType compression,unsigned char *pixels)
134%
135%  A description of each parameter follows:
136%
137%    o image: the address of a structure of type Image.
138%
139%    o compression:  A value of 1 means the compressed pixels are runlength
140%      encoded for a 256-color bitmap.  A value of 2 means a 16-color bitmap.
141%
142%    o pixels:  The address of a byte (8 bits) array of pixel data created by
143%      the decoding process.
144%
145*/
146static MagickBooleanType DecodeImage(Image *image,
147  const MagickBooleanType compression,unsigned char *pixels)
148{
149#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__MINGW32__) || defined(__MINGW64__)
150#define BI_RGB  0
151#define BI_RLE8  1
152#define BI_RLE4  2
153#define BI_BITFIELDS  3
154#undef BI_JPEG
155#define BI_JPEG  4
156#undef BI_PNG
157#define BI_PNG  5
158#endif
159
160  int
161    count;
162
163  ssize_t
164    y;
165
166  register ssize_t
167    i,
168    x;
169
170  register unsigned char
171    *p,
172    *q;
173
174  unsigned char
175    byte;
176
177  assert(image != (Image *) NULL);
178  assert(image->signature == MagickCoreSignature);
179  if (image->debug != MagickFalse)
180    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
181  assert(pixels != (unsigned char *) NULL);
182  (void) ResetMagickMemory(pixels,0,(size_t) image->columns*image->rows*
183    sizeof(*pixels));
184  byte=0;
185  x=0;
186  p=pixels;
187  q=pixels+(size_t) image->columns*image->rows;
188  for (y=0; y < (ssize_t) image->rows; )
189  {
190    if ((p < pixels) || (p >= q))
191      break;
192    count=ReadBlobByte(image);
193    if (count == EOF)
194      break;
195    if (count != 0)
196      {
197        count=(int) MagickMin((size_t) count,(size_t) (q-p));
198        /*
199          Encoded mode.
200        */
201        byte=(unsigned char) ReadBlobByte(image);
202        if (compression == BI_RLE8)
203          {
204            for (i=0; i < count; i++)
205              *p++=(unsigned char) byte;
206          }
207        else
208          {
209            for (i=0; i < count; i++)
210              *p++=(unsigned char)
211                ((i & 0x01) != 0 ? (byte & 0x0f) : ((byte >> 4) & 0x0f));
212          }
213        x+=count;
214      }
215    else
216      {
217        /*
218          Escape mode.
219        */
220        count=ReadBlobByte(image);
221        if (count == 0x01)
222          return(MagickTrue);
223        switch (count)
224        {
225          case 0x00:
226          {
227            /*
228              End of line.
229            */
230            x=0;
231            y++;
232            p=pixels+y*image->columns;
233            break;
234          }
235          case 0x02:
236          {
237            /*
238              Delta mode.
239            */
240            x+=ReadBlobByte(image);
241            y+=ReadBlobByte(image);
242            p=pixels+y*image->columns+x;
243            break;
244          }
245          default:
246          {
247            /*
248              Absolute mode.
249            */
250            count=(int) MagickMin((size_t) count,(size_t) (q-p));
251            if (compression == BI_RLE8)
252              for (i=0; i < count; i++)
253                *p++=(unsigned char) ReadBlobByte(image);
254            else
255              for (i=0; i < count; i++)
256              {
257                if ((i & 0x01) == 0)
258                  byte=(unsigned char) ReadBlobByte(image);
259                *p++=(unsigned char)
260                  ((i & 0x01) != 0 ? (byte & 0x0f) : ((byte >> 4) & 0x0f));
261              }
262            x+=count;
263            /*
264              Read pad byte.
265            */
266            if (compression == BI_RLE8)
267              {
268                if ((count & 0x01) != 0)
269                  (void) ReadBlobByte(image);
270              }
271            else
272              if (((count & 0x03) == 1) || ((count & 0x03) == 2))
273                (void) ReadBlobByte(image);
274            break;
275          }
276        }
277      }
278    if (SetImageProgress(image,LoadImageTag,y,image->rows) == MagickFalse)
279      break;
280  }
281  (void) ReadBlobByte(image);  /* end of line */
282  (void) ReadBlobByte(image);
283  return(MagickTrue);
284}
285
286/*
287%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
288%                                                                             %
289%                                                                             %
290%                                                                             %
291%   E n c o d e I m a g e                                                     %
292%                                                                             %
293%                                                                             %
294%                                                                             %
295%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
296%
297%  EncodeImage compresses pixels using a runlength encoded format.
298%
299%  The format of the EncodeImage method is:
300%
301%    static MagickBooleanType EncodeImage(Image *image,
302%      const size_t bytes_per_line,const unsigned char *pixels,
303%      unsigned char *compressed_pixels)
304%
305%  A description of each parameter follows:
306%
307%    o image:  The image.
308%
309%    o bytes_per_line: the number of bytes in a scanline of compressed pixels
310%
311%    o pixels:  The address of a byte (8 bits) array of pixel data created by
312%      the compression process.
313%
314%    o compressed_pixels:  The address of a byte (8 bits) array of compressed
315%      pixel data.
316%
317*/
318static size_t EncodeImage(Image *image,const size_t bytes_per_line,
319  const unsigned char *pixels,unsigned char *compressed_pixels)
320{
321  ssize_t
322    y;
323
324  register const unsigned char
325    *p;
326
327  register ssize_t
328    i,
329    x;
330
331  register unsigned char
332    *q;
333
334  /*
335    Runlength encode pixels.
336  */
337  assert(image != (Image *) NULL);
338  assert(image->signature == MagickCoreSignature);
339  if (image->debug != MagickFalse)
340    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
341  assert(pixels != (const unsigned char *) NULL);
342  assert(compressed_pixels != (unsigned char *) NULL);
343  p=pixels;
344  q=compressed_pixels;
345  i=0;
346  for (y=0; y < (ssize_t) image->rows; y++)
347  {
348    for (x=0; x < (ssize_t) bytes_per_line; x+=i)
349    {
350      /*
351        Determine runlength.
352      */
353      for (i=1; ((x+i) < (ssize_t) bytes_per_line); i++)
354        if ((*(p+i) != *p) || (i == 255))
355          break;
356      *q++=(unsigned char) i;
357      *q++=(*p);
358      p+=i;
359    }
360    /*
361      End of line.
362    */
363    *q++=0x00;
364    *q++=0x00;
365    if (SetImageProgress(image,LoadImageTag,y,image->rows) == MagickFalse)
366      break;
367  }
368  /*
369    End of bitmap.
370  */
371  *q++=0;
372  *q++=0x01;
373  return((size_t) (q-compressed_pixels));
374}
375
376/*
377%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
378%                                                                             %
379%                                                                             %
380%                                                                             %
381%   I s D I B                                                                 %
382%                                                                             %
383%                                                                             %
384%                                                                             %
385%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
386%
387%  IsDIB() returns MagickTrue if the image format type, identified by the
388%  magick string, is DIB.
389%
390%  The format of the IsDIB method is:
391%
392%      MagickBooleanType IsDIB(const unsigned char *magick,const size_t length)
393%
394%  A description of each parameter follows:
395%
396%    o magick: compare image format pattern against these bytes.
397%
398%    o length: Specifies the length of the magick string.
399%
400*/
401static MagickBooleanType IsDIB(const unsigned char *magick,const size_t length)
402{
403  if (length < 2)
404    return(MagickFalse);
405  if (memcmp(magick,"\050\000",2) == 0)
406    return(MagickTrue);
407  return(MagickFalse);
408}
409
410/*
411%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
412%                                                                             %
413%                                                                             %
414%                                                                             %
415%   R e a d D I B I m a g e                                                   %
416%                                                                             %
417%                                                                             %
418%                                                                             %
419%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
420%
421%  ReadDIBImage() reads a Microsoft Windows bitmap image file and
422%  returns it.  It allocates the memory necessary for the new Image structure
423%  and returns a pointer to the new image.
424%
425%  The format of the ReadDIBImage method is:
426%
427%      image=ReadDIBImage(image_info)
428%
429%  A description of each parameter follows:
430%
431%    o image_info: the image info.
432%
433%    o exception: return any errors or warnings in this structure.
434%
435*/
436static Image *ReadDIBImage(const ImageInfo *image_info,ExceptionInfo *exception)
437{
438  DIBInfo
439    dib_info;
440
441  Image
442    *image;
443
444  MagickBooleanType
445    status;
446
447  MemoryInfo
448    *pixel_info;
449
450  Quantum
451    index;
452
453  register ssize_t
454    x;
455
456  register Quantum
457    *q;
458
459  register ssize_t
460    i;
461
462  register unsigned char
463    *p;
464
465  size_t
466    bytes_per_line,
467    length;
468
469  ssize_t
470    bit,
471    count,
472    y;
473
474
475  unsigned char
476    *pixels;
477
478  /*
479    Open image file.
480  */
481  assert(image_info != (const ImageInfo *) NULL);
482  assert(image_info->signature == MagickCoreSignature);
483  if (image_info->debug != MagickFalse)
484    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
485      image_info->filename);
486  assert(exception != (ExceptionInfo *) NULL);
487  assert(exception->signature == MagickCoreSignature);
488  image=AcquireImage(image_info,exception);
489  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
490  if (status == MagickFalse)
491    {
492      image=DestroyImageList(image);
493      return((Image *) NULL);
494    }
495  /*
496    Determine if this a DIB file.
497  */
498  (void) ResetMagickMemory(&dib_info,0,sizeof(dib_info));
499  dib_info.size=ReadBlobLSBLong(image);
500  if (dib_info.size != 40)
501    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
502  /*
503    Microsoft Windows 3.X DIB image file.
504  */
505  dib_info.width=ReadBlobLSBSignedLong(image);
506  dib_info.height=ReadBlobLSBSignedLong(image);
507  dib_info.planes=ReadBlobLSBShort(image);
508  dib_info.bits_per_pixel=ReadBlobLSBShort(image);
509  if (dib_info.bits_per_pixel > 32)
510    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
511  dib_info.compression=ReadBlobLSBLong(image);
512  dib_info.image_size=ReadBlobLSBLong(image);
513  dib_info.x_pixels=ReadBlobLSBLong(image);
514  dib_info.y_pixels=ReadBlobLSBLong(image);
515  dib_info.number_colors=ReadBlobLSBLong(image);
516  dib_info.colors_important=ReadBlobLSBLong(image);
517  if ((dib_info.bits_per_pixel != 1) && (dib_info.bits_per_pixel != 4) &&
518      (dib_info.bits_per_pixel != 8) && (dib_info.bits_per_pixel != 16) &&
519      (dib_info.bits_per_pixel != 24) && (dib_info.bits_per_pixel != 32))
520    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
521  if ((dib_info.compression == BI_BITFIELDS) &&
522      ((dib_info.bits_per_pixel == 16) || (dib_info.bits_per_pixel == 32)))
523    {
524      dib_info.red_mask=ReadBlobLSBLong(image);
525      dib_info.green_mask=ReadBlobLSBLong(image);
526      dib_info.blue_mask=ReadBlobLSBLong(image);
527    }
528  if (EOFBlob(image) != MagickFalse)
529    ThrowReaderException(CorruptImageError,"UnexpectedEndOfFile");
530  if (dib_info.width <= 0)
531    ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
532  if (dib_info.height == 0)
533    ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
534  if (dib_info.planes != 1)
535    ThrowReaderException(CorruptImageError,"StaticPlanesValueNotEqualToOne");
536  if ((dib_info.bits_per_pixel != 1) && (dib_info.bits_per_pixel != 4) &&
537      (dib_info.bits_per_pixel != 8) && (dib_info.bits_per_pixel != 16) &&
538      (dib_info.bits_per_pixel != 24) && (dib_info.bits_per_pixel != 32))
539    ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
540  if (dib_info.bits_per_pixel < 16 &&
541      dib_info.number_colors > (size_t) (1UL << dib_info.bits_per_pixel))
542    ThrowReaderException(CorruptImageError,"UnrecognizedNumberOfColors");
543  if ((dib_info.compression == 1) && (dib_info.bits_per_pixel != 8))
544    ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
545  if ((dib_info.compression == 2) && (dib_info.bits_per_pixel != 4))
546    ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
547  if ((dib_info.compression == 3) && (dib_info.bits_per_pixel < 16))
548    ThrowReaderException(CorruptImageError,"UnrecognizedBitsPerPixel");
549  switch (dib_info.compression)
550  {
551    case BI_RGB:
552    case BI_RLE8:
553    case BI_RLE4:
554    case BI_BITFIELDS:
555      break;
556    case BI_JPEG:
557      ThrowReaderException(CoderError,"JPEGCompressNotSupported");
558    case BI_PNG:
559      ThrowReaderException(CoderError,"PNGCompressNotSupported");
560    default:
561      ThrowReaderException(CorruptImageError,"UnrecognizedImageCompression");
562  }
563  image->columns=(size_t) MagickAbsoluteValue(dib_info.width);
564  image->rows=(size_t) MagickAbsoluteValue(dib_info.height);
565  image->depth=8;
566  image->alpha_trait=dib_info.bits_per_pixel == 32 ? BlendPixelTrait :
567    UndefinedPixelTrait;
568  if ((dib_info.number_colors > 256) || (dib_info.colors_important > 256))
569    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
570  if ((dib_info.number_colors != 0) || (dib_info.bits_per_pixel < 16))
571    {
572      size_t
573        one;
574
575      image->storage_class=PseudoClass;
576      image->colors=dib_info.number_colors;
577      one=1;
578      if (image->colors == 0)
579        image->colors=one << dib_info.bits_per_pixel;
580    }
581  if (image_info->size)
582    {
583      RectangleInfo
584        geometry;
585
586      MagickStatusType
587        flags;
588
589      flags=ParseAbsoluteGeometry(image_info->size,&geometry);
590      if (flags & WidthValue)
591        if ((geometry.width != 0) && (geometry.width < image->columns))
592          image->columns=geometry.width;
593      if (flags & HeightValue)
594        if ((geometry.height != 0) && (geometry.height < image->rows))
595          image->rows=geometry.height;
596    }
597  status=SetImageExtent(image,image->columns,image->rows,exception);
598  if (status == MagickFalse)
599    return(DestroyImageList(image));
600  if (image->storage_class == PseudoClass)
601    {
602      size_t
603        length,
604        packet_size;
605
606      unsigned char
607        *dib_colormap;
608
609      /*
610        Read DIB raster colormap.
611      */
612      if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
613        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
614      length=(size_t) image->colors;
615      dib_colormap=(unsigned char *) AcquireQuantumMemory(length,
616        4*sizeof(*dib_colormap));
617      if (dib_colormap == (unsigned char *) NULL)
618        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
619      packet_size=4;
620      count=ReadBlob(image,packet_size*image->colors,dib_colormap);
621      if (count != (ssize_t) (packet_size*image->colors))
622        ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
623      p=dib_colormap;
624      for (i=0; i < (ssize_t) image->colors; i++)
625      {
626        image->colormap[i].blue=ScaleCharToQuantum(*p++);
627        image->colormap[i].green=ScaleCharToQuantum(*p++);
628        image->colormap[i].red=ScaleCharToQuantum(*p++);
629        if (packet_size == 4)
630          p++;
631      }
632      dib_colormap=(unsigned char *) RelinquishMagickMemory(dib_colormap);
633    }
634  /*
635    Read image data.
636  */
637  if (dib_info.compression == BI_RLE4)
638    dib_info.bits_per_pixel<<=1;
639  bytes_per_line=4*((image->columns*dib_info.bits_per_pixel+31)/32);
640  length=bytes_per_line*image->rows;
641  pixel_info=AcquireVirtualMemory((size_t) image->rows,MagickMax(
642    bytes_per_line,image->columns+256UL)*sizeof(*pixels));
643  if (pixel_info == (MemoryInfo *) NULL)
644    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
645  pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
646  if ((dib_info.compression == BI_RGB) ||
647      (dib_info.compression == BI_BITFIELDS))
648    {
649      count=ReadBlob(image,length,pixels);
650      if (count != (ssize_t) (length))
651        ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
652    }
653  else
654    {
655      /*
656        Convert run-length encoded raster pixels.
657      */
658      status=DecodeImage(image,dib_info.compression ? MagickTrue : MagickFalse,
659        pixels);
660      if (status == MagickFalse)
661        ThrowReaderException(CorruptImageError,"UnableToRunlengthDecodeImage");
662    }
663  /*
664    Initialize image structure.
665  */
666  image->units=PixelsPerCentimeterResolution;
667  image->resolution.x=(double) dib_info.x_pixels/100.0;
668  image->resolution.y=(double) dib_info.y_pixels/100.0;
669  /*
670    Convert DIB raster image to pixel packets.
671  */
672  switch (dib_info.bits_per_pixel)
673  {
674    case 1:
675    {
676      /*
677        Convert bitmap scanline.
678      */
679      for (y=(ssize_t) image->rows-1; y >= 0; y--)
680      {
681        p=pixels+(image->rows-y-1)*bytes_per_line;
682        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
683        if (q == (Quantum *) NULL)
684          break;
685        for (x=0; x < ((ssize_t) image->columns-7); x+=8)
686        {
687          for (bit=0; bit < 8; bit++)
688          {
689            index=(Quantum) ((*p) & (0x80 >> bit) ? 0x01 : 0x00);
690            SetPixelIndex(image,index,q);
691            q+=GetPixelChannels(image);
692          }
693          p++;
694        }
695        if ((image->columns % 8) != 0)
696          {
697            for (bit=0; bit < (ssize_t) (image->columns % 8); bit++)
698            {
699              index=(Quantum) ((*p) & (0x80 >> bit) ? 0x01 : 0x00);
700              SetPixelIndex(image,index,q);
701              q+=GetPixelChannels(image);
702            }
703            p++;
704          }
705        if (SyncAuthenticPixels(image,exception) == MagickFalse)
706          break;
707        if (image->previous == (Image *) NULL)
708          {
709            status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
710              image->rows);
711            if (status == MagickFalse)
712              break;
713          }
714      }
715      (void) SyncImage(image,exception);
716      break;
717    }
718    case 4:
719    {
720      /*
721        Convert PseudoColor scanline.
722      */
723      for (y=(ssize_t) image->rows-1; y >= 0; y--)
724      {
725        p=pixels+(image->rows-y-1)*bytes_per_line;
726        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
727        if (q == (Quantum *) NULL)
728          break;
729        for (x=0; x < ((ssize_t) image->columns-1); x+=2)
730        {
731          index=ConstrainColormapIndex(image,(*p >> 4) & 0xf,exception);
732          SetPixelIndex(image,index,q);
733          q+=GetPixelChannels(image);
734          index=ConstrainColormapIndex(image,*p & 0xf,exception);
735          SetPixelIndex(image,index,q);
736          p++;
737          q+=GetPixelChannels(image);
738        }
739        if ((image->columns % 2) != 0)
740          {
741            index=ConstrainColormapIndex(image,(*p >> 4) & 0xf,exception);
742            SetPixelIndex(image,index,q);
743            q+=GetPixelChannels(image);
744            p++;
745          }
746        if (SyncAuthenticPixels(image,exception) == MagickFalse)
747          break;
748        if (image->previous == (Image *) NULL)
749          {
750            status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
751              image->rows);
752            if (status == MagickFalse)
753              break;
754          }
755      }
756      (void) SyncImage(image,exception);
757      break;
758    }
759    case 8:
760    {
761      /*
762        Convert PseudoColor scanline.
763      */
764      if ((dib_info.compression == BI_RLE8) ||
765          (dib_info.compression == BI_RLE4))
766        bytes_per_line=image->columns;
767      for (y=(ssize_t) image->rows-1; y >= 0; y--)
768      {
769        p=pixels+(image->rows-y-1)*bytes_per_line;
770        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
771        if (q == (Quantum *) NULL)
772          break;
773        for (x=0; x < (ssize_t) image->columns; x++)
774        {
775          index=ConstrainColormapIndex(image,*p,exception);
776          SetPixelIndex(image,index,q);
777          p++;
778          q+=GetPixelChannels(image);
779        }
780        if (SyncAuthenticPixels(image,exception) == MagickFalse)
781          break;
782        if (image->previous == (Image *) NULL)
783          {
784            status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
785              image->rows);
786            if (status == MagickFalse)
787              break;
788          }
789      }
790      (void) SyncImage(image,exception);
791      break;
792    }
793    case 16:
794    {
795      unsigned short
796        word;
797
798      /*
799        Convert PseudoColor scanline.
800      */
801      image->storage_class=DirectClass;
802      if (dib_info.compression == BI_RLE8)
803        bytes_per_line=2*image->columns;
804      for (y=(ssize_t) image->rows-1; y >= 0; y--)
805      {
806        p=pixels+(image->rows-y-1)*bytes_per_line;
807        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
808        if (q == (Quantum *) NULL)
809          break;
810        for (x=0; x < (ssize_t) image->columns; x++)
811        {
812          word=(*p++);
813          word|=(*p++ << 8);
814          if (dib_info.red_mask == 0)
815            {
816              SetPixelRed(image,ScaleCharToQuantum(ScaleColor5to8(
817                (unsigned char) ((word >> 10) & 0x1f))),q);
818              SetPixelGreen(image,ScaleCharToQuantum(ScaleColor5to8(
819                (unsigned char) ((word >> 5) & 0x1f))),q);
820              SetPixelBlue(image,ScaleCharToQuantum(ScaleColor5to8(
821                (unsigned char) (word & 0x1f))),q);
822            }
823          else
824            {
825              SetPixelRed(image,ScaleCharToQuantum(ScaleColor5to8(
826                (unsigned char) ((word >> 11) & 0x1f))),q);
827              SetPixelGreen(image,ScaleCharToQuantum(ScaleColor6to8(
828                (unsigned char) ((word >> 5) & 0x3f))),q);
829              SetPixelBlue(image,ScaleCharToQuantum(ScaleColor5to8(
830                (unsigned char) (word & 0x1f))),q);
831            }
832          q+=GetPixelChannels(image);
833        }
834        if (SyncAuthenticPixels(image,exception) == MagickFalse)
835          break;
836        if (image->previous == (Image *) NULL)
837          {
838            status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
839              image->rows);
840            if (status == MagickFalse)
841              break;
842          }
843      }
844      break;
845    }
846    case 24:
847    case 32:
848    {
849      /*
850        Convert DirectColor scanline.
851      */
852      for (y=(ssize_t) image->rows-1; y >= 0; y--)
853      {
854        p=pixels+(image->rows-y-1)*bytes_per_line;
855        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
856        if (q == (Quantum *) NULL)
857          break;
858        for (x=0; x < (ssize_t) image->columns; x++)
859        {
860          SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
861          SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
862          SetPixelRed(image,ScaleCharToQuantum(*p++),q);
863          if (image->alpha_trait != UndefinedPixelTrait)
864            SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
865          q+=GetPixelChannels(image);
866        }
867        if (SyncAuthenticPixels(image,exception) == MagickFalse)
868          break;
869        if (image->previous == (Image *) NULL)
870          {
871            status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
872              image->rows);
873            if (status == MagickFalse)
874              break;
875          }
876      }
877      break;
878    }
879    default:
880      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
881  }
882  pixel_info=RelinquishVirtualMemory(pixel_info);
883  if (EOFBlob(image) != MagickFalse)
884    ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
885      image->filename);
886  if (dib_info.height < 0)
887    {
888      Image
889        *flipped_image;
890
891      /*
892        Correct image orientation.
893      */
894      flipped_image=FlipImage(image,exception);
895      if (flipped_image != (Image *) NULL)
896        {
897          DuplicateBlob(flipped_image,image);
898          image=DestroyImage(image);
899          image=flipped_image;
900        }
901    }
902  (void) CloseBlob(image);
903  return(GetFirstImageInList(image));
904}
905
906/*
907%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
908%                                                                             %
909%                                                                             %
910%                                                                             %
911%   R e g i s t e r D I B I m a g e                                           %
912%                                                                             %
913%                                                                             %
914%                                                                             %
915%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
916%
917%  RegisterDIBImage() adds attributes for the DIB image format to
918%  the list of supported formats.  The attributes include the image format
919%  tag, a method to read and/or write the format, whether the format
920%  supports the saving of more than one frame to the same file or blob,
921%  whether the format supports native in-memory I/O, and a brief
922%  description of the format.
923%
924%  The format of the RegisterDIBImage method is:
925%
926%      size_t RegisterDIBImage(void)
927%
928*/
929ModuleExport size_t RegisterDIBImage(void)
930{
931  MagickInfo
932    *entry;
933
934  entry=AcquireMagickInfo("DIB","DIB",
935    "Microsoft Windows 3.X Packed Device-Independent Bitmap");
936  entry->decoder=(DecodeImageHandler *) ReadDIBImage;
937  entry->encoder=(EncodeImageHandler *) WriteDIBImage;
938  entry->magick=(IsImageFormatHandler *) IsDIB;
939  entry->flags^=CoderAdjoinFlag;
940  entry->flags|=CoderStealthFlag;
941  (void) RegisterMagickInfo(entry);
942  return(MagickImageCoderSignature);
943}
944
945/*
946%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
947%                                                                             %
948%                                                                             %
949%                                                                             %
950%   U n r e g i s t e r D I B I m a g e                                       %
951%                                                                             %
952%                                                                             %
953%                                                                             %
954%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
955%
956%  UnregisterDIBImage() removes format registrations made by the
957%  DIB module from the list of supported formats.
958%
959%  The format of the UnregisterDIBImage method is:
960%
961%      UnregisterDIBImage(void)
962%
963*/
964ModuleExport void UnregisterDIBImage(void)
965{
966  (void) UnregisterMagickInfo("DIB");
967}
968
969/*
970%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
971%                                                                             %
972%                                                                             %
973%                                                                             %
974%   W r i t e D I B I m a g e                                                 %
975%                                                                             %
976%                                                                             %
977%                                                                             %
978%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
979%
980%  WriteDIBImage() writes an image in Microsoft Windows bitmap encoded
981%  image format.
982%
983%  The format of the WriteDIBImage method is:
984%
985%      MagickBooleanType WriteDIBImage(const ImageInfo *image_info,
986%        Image *image,ExceptionInfo *exception)
987%
988%  A description of each parameter follows.
989%
990%    o image_info: the image info.
991%
992%    o image:  The image.
993%
994%    o exception: return any errors or warnings in this structure.
995%
996*/
997static MagickBooleanType WriteDIBImage(const ImageInfo *image_info,Image *image,
998  ExceptionInfo *exception)
999{
1000  DIBInfo
1001    dib_info;
1002
1003  MagickBooleanType
1004    status;
1005
1006  register const Quantum
1007    *p;
1008
1009  register ssize_t
1010    i,
1011    x;
1012
1013  register unsigned char
1014    *q;
1015
1016  size_t
1017    bytes_per_line;
1018
1019  ssize_t
1020    y;
1021
1022  unsigned char
1023    *dib_data,
1024    *pixels;
1025
1026  /*
1027    Open output image file.
1028  */
1029  assert(image_info != (const ImageInfo *) NULL);
1030  assert(image_info->signature == MagickCoreSignature);
1031  assert(image != (Image *) NULL);
1032  assert(image->signature == MagickCoreSignature);
1033  if (image->debug != MagickFalse)
1034    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1035  assert(exception != (ExceptionInfo *) NULL);
1036  assert(exception->signature == MagickCoreSignature);
1037  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1038  if (status == MagickFalse)
1039    return(status);
1040  /*
1041    Initialize DIB raster file header.
1042  */
1043  (void) TransformImageColorspace(image,sRGBColorspace,exception);
1044  if (image->storage_class == DirectClass)
1045    {
1046      /*
1047        Full color DIB raster.
1048      */
1049      dib_info.number_colors=0;
1050      dib_info.bits_per_pixel=(unsigned short) (image->alpha_trait ? 32 : 24);
1051    }
1052  else
1053    {
1054      /*
1055        Colormapped DIB raster.
1056      */
1057      dib_info.bits_per_pixel=8;
1058      if (image_info->depth > 8)
1059        dib_info.bits_per_pixel=16;
1060      if (SetImageMonochrome(image,exception) != MagickFalse)
1061        dib_info.bits_per_pixel=1;
1062      dib_info.number_colors=(dib_info.bits_per_pixel == 16) ? 0 :
1063        (1UL << dib_info.bits_per_pixel);
1064    }
1065  bytes_per_line=4*((image->columns*dib_info.bits_per_pixel+31)/32);
1066  dib_info.size=40;
1067  dib_info.width=(ssize_t) image->columns;
1068  dib_info.height=(ssize_t) image->rows;
1069  dib_info.planes=1;
1070  dib_info.compression=(size_t) (dib_info.bits_per_pixel == 16 ?
1071    BI_BITFIELDS : BI_RGB);
1072  dib_info.image_size=bytes_per_line*image->rows;
1073  dib_info.x_pixels=75*39;
1074  dib_info.y_pixels=75*39;
1075  switch (image->units)
1076  {
1077    case UndefinedResolution:
1078    case PixelsPerInchResolution:
1079    {
1080      dib_info.x_pixels=(size_t) (100.0*image->resolution.x/2.54);
1081      dib_info.y_pixels=(size_t) (100.0*image->resolution.y/2.54);
1082      break;
1083    }
1084    case PixelsPerCentimeterResolution:
1085    {
1086      dib_info.x_pixels=(size_t) (100.0*image->resolution.x);
1087      dib_info.y_pixels=(size_t) (100.0*image->resolution.y);
1088      break;
1089    }
1090  }
1091  dib_info.colors_important=dib_info.number_colors;
1092  /*
1093    Convert MIFF to DIB raster pixels.
1094  */
1095  pixels=(unsigned char *) AcquireQuantumMemory(dib_info.image_size,
1096    sizeof(*pixels));
1097  if (pixels == (unsigned char *) NULL)
1098    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1099  (void) ResetMagickMemory(pixels,0,dib_info.image_size);
1100  switch (dib_info.bits_per_pixel)
1101  {
1102    case 1:
1103    {
1104      register unsigned char
1105        bit,
1106        byte;
1107
1108      /*
1109        Convert PseudoClass image to a DIB monochrome image.
1110      */
1111      for (y=0; y < (ssize_t) image->rows; y++)
1112      {
1113        p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1114        if (p == (const Quantum *) NULL)
1115          break;
1116        q=pixels+(image->rows-y-1)*bytes_per_line;
1117        bit=0;
1118        byte=0;
1119        for (x=0; x < (ssize_t) image->columns; x++)
1120        {
1121          byte<<=1;
1122          byte|=GetPixelIndex(image,p) != 0 ? 0x01 : 0x00;
1123          bit++;
1124          if (bit == 8)
1125            {
1126              *q++=byte;
1127              bit=0;
1128              byte=0;
1129            }
1130           p+=GetPixelChannels(image);
1131         }
1132         if (bit != 0)
1133           {
1134             *q++=(unsigned char) (byte << (8-bit));
1135             x++;
1136           }
1137        for (x=(ssize_t) (image->columns+7)/8; x < (ssize_t) bytes_per_line; x++)
1138          *q++=0x00;
1139        status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1140          image->rows);
1141        if (status == MagickFalse)
1142          break;
1143      }
1144      break;
1145    }
1146    case 8:
1147    {
1148      /*
1149        Convert PseudoClass packet to DIB pixel.
1150      */
1151      for (y=0; y < (ssize_t) image->rows; y++)
1152      {
1153        p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1154        if (p == (const Quantum *) NULL)
1155          break;
1156        q=pixels+(image->rows-y-1)*bytes_per_line;
1157        for (x=0; x < (ssize_t) image->columns; x++)
1158        {
1159          *q++=(unsigned char) GetPixelIndex(image,p);
1160          p+=GetPixelChannels(image);
1161        }
1162        for ( ; x < (ssize_t) bytes_per_line; x++)
1163          *q++=0x00;
1164        status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1165          image->rows);
1166        if (status == MagickFalse)
1167          break;
1168      }
1169      break;
1170    }
1171    case 16:
1172    {
1173      unsigned short
1174        word;
1175      /*
1176        Convert PseudoClass packet to DIB pixel.
1177      */
1178      for (y=0; y < (ssize_t) image->rows; y++)
1179      {
1180        p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1181        if (p == (const Quantum *) NULL)
1182          break;
1183        q=pixels+(image->rows-y-1)*bytes_per_line;
1184        for (x=0; x < (ssize_t) image->columns; x++)
1185        {
1186          word=(unsigned short) ((ScaleColor8to5((unsigned char)
1187            ScaleQuantumToChar(GetPixelRed(image,p))) << 11) | (ScaleColor8to6(
1188            (unsigned char) ScaleQuantumToChar(GetPixelGreen(image,p))) << 5) |
1189            (ScaleColor8to5((unsigned char) ScaleQuantumToChar((unsigned char)
1190            GetPixelBlue(image,p)) << 0)));
1191          *q++=(unsigned char)(word & 0xff);
1192          *q++=(unsigned char)(word >> 8);
1193          p+=GetPixelChannels(image);
1194        }
1195        for (x=(ssize_t) (2*image->columns); x < (ssize_t) bytes_per_line; x++)
1196          *q++=0x00;
1197        status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1198          image->rows);
1199        if (status == MagickFalse)
1200          break;
1201      }
1202      break;
1203    }
1204    case 24:
1205    case 32:
1206    {
1207      /*
1208        Convert DirectClass packet to DIB RGB pixel.
1209      */
1210      for (y=0; y < (ssize_t) image->rows; y++)
1211      {
1212        p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1213        if (p == (const Quantum *) NULL)
1214          break;
1215        q=pixels+(image->rows-y-1)*bytes_per_line;
1216        for (x=0; x < (ssize_t) image->columns; x++)
1217        {
1218          *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
1219          *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
1220          *q++=ScaleQuantumToChar(GetPixelRed(image,p));
1221          if (image->alpha_trait != UndefinedPixelTrait)
1222            *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
1223          p+=GetPixelChannels(image);
1224        }
1225        if (dib_info.bits_per_pixel == 24)
1226          for (x=(ssize_t) (3*image->columns); x < (ssize_t) bytes_per_line; x++)
1227            *q++=0x00;
1228        status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1229          image->rows);
1230        if (status == MagickFalse)
1231          break;
1232      }
1233      break;
1234    }
1235  }
1236  if (dib_info.bits_per_pixel == 8)
1237    if (image_info->compression != NoCompression)
1238      {
1239        size_t
1240          length;
1241
1242        /*
1243          Convert run-length encoded raster pixels.
1244        */
1245        length=2UL*(bytes_per_line+2UL)+2UL;
1246        dib_data=(unsigned char *) AcquireQuantumMemory(length,
1247          (image->rows+2UL)*sizeof(*dib_data));
1248        if (dib_data == (unsigned char *) NULL)
1249          {
1250            pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1251            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1252          }
1253        dib_info.image_size=(size_t) EncodeImage(image,bytes_per_line,
1254          pixels,dib_data);
1255        pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1256        pixels=dib_data;
1257        dib_info.compression = BI_RLE8;
1258      }
1259  /*
1260    Write DIB header.
1261  */
1262  (void) WriteBlobLSBLong(image,(unsigned int) dib_info.size);
1263  (void) WriteBlobLSBLong(image,dib_info.width);
1264  (void) WriteBlobLSBLong(image,(unsigned short) dib_info.height);
1265  (void) WriteBlobLSBShort(image,(unsigned short) dib_info.planes);
1266  (void) WriteBlobLSBShort(image,dib_info.bits_per_pixel);
1267  (void) WriteBlobLSBLong(image,(unsigned int) dib_info.compression);
1268  (void) WriteBlobLSBLong(image,(unsigned int) dib_info.image_size);
1269  (void) WriteBlobLSBLong(image,(unsigned int) dib_info.x_pixels);
1270  (void) WriteBlobLSBLong(image,(unsigned int) dib_info.y_pixels);
1271  (void) WriteBlobLSBLong(image,(unsigned int) dib_info.number_colors);
1272  (void) WriteBlobLSBLong(image,(unsigned int) dib_info.colors_important);
1273  if (image->storage_class == PseudoClass)
1274    {
1275      if (dib_info.bits_per_pixel <= 8)
1276        {
1277          unsigned char
1278            *dib_colormap;
1279
1280          /*
1281            Dump colormap to file.
1282          */
1283          dib_colormap=(unsigned char *) AcquireQuantumMemory((size_t)
1284            (1UL << dib_info.bits_per_pixel),4*sizeof(*dib_colormap));
1285          if (dib_colormap == (unsigned char *) NULL)
1286            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1287          q=dib_colormap;
1288          for (i=0; i < (ssize_t) MagickMin(image->colors,dib_info.number_colors); i++)
1289          {
1290            *q++=ScaleQuantumToChar(image->colormap[i].blue);
1291            *q++=ScaleQuantumToChar(image->colormap[i].green);
1292            *q++=ScaleQuantumToChar(image->colormap[i].red);
1293            *q++=(Quantum) 0x0;
1294          }
1295          for ( ; i < (ssize_t) (1L << dib_info.bits_per_pixel); i++)
1296          {
1297            *q++=(Quantum) 0x0;
1298            *q++=(Quantum) 0x0;
1299            *q++=(Quantum) 0x0;
1300            *q++=(Quantum) 0x0;
1301          }
1302          (void) WriteBlob(image,(size_t) (4*(1 << dib_info.bits_per_pixel)),
1303            dib_colormap);
1304          dib_colormap=(unsigned char *) RelinquishMagickMemory(dib_colormap);
1305        }
1306      else
1307        if ((dib_info.bits_per_pixel == 16) &&
1308            (dib_info.compression == BI_BITFIELDS))
1309          {
1310            (void) WriteBlobLSBLong(image,0xf800);
1311            (void) WriteBlobLSBLong(image,0x07e0);
1312            (void) WriteBlobLSBLong(image,0x001f);
1313          }
1314    }
1315  (void) WriteBlob(image,dib_info.image_size,pixels);
1316  pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1317  (void) CloseBlob(image);
1318  return(MagickTrue);
1319}
1320