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