]> 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 %                                John Cristy                                  %
17 %                                 July 1992                                   %
18 %                                                                             %
19 %                                                                             %
20 %  Copyright 1999-2010 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 "magick/studio.h"
43 #include "magick/blob.h"
44 #include "magick/blob-private.h"
45 #include "magick/cache.h"
46 #include "magick/color.h"
47 #include "magick/colormap-private.h"
48 #include "magick/color-private.h"
49 #include "magick/colorspace.h"
50 #include "magick/draw.h"
51 #include "magick/exception.h"
52 #include "magick/exception-private.h"
53 #include "magick/geometry.h"
54 #include "magick/image.h"
55 #include "magick/image-private.h"
56 #include "magick/list.h"
57 #include "magick/log.h"
58 #include "magick/magick.h"
59 #include "magick/memory_.h"
60 #include "magick/monitor.h"
61 #include "magick/monitor-private.h"
62 #include "magick/quantum-private.h"
63 #include "magick/static.h"
64 #include "magick/string_.h"
65 #include "magick/module.h"
66 #include "magick/transform.h"
67 \f
68 /*
69   Typedef declarations.
70 */
71 typedef struct _DIBInfo
72 {
73   unsigned long
74     size;
75
76   long
77     width,
78     height;
79
80   unsigned short
81     planes,
82     bits_per_pixel;
83
84   unsigned long
85     compression,
86     image_size,
87     x_pixels,
88     y_pixels,
89     number_colors,
90     red_mask,
91     green_mask,
92     blue_mask,
93     alpha_mask,
94     colors_important;
95
96   long
97     colorspace;
98
99   PointInfo
100     red_primary,
101     green_primary,
102     blue_primary,
103     gamma_scale;
104 } DIBInfo;
105 \f
106 /*
107   Forward declarations.
108 */
109 static MagickBooleanType
110   WriteDIBImage(const ImageInfo *,Image *);
111 \f
112 /*
113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
114 %                                                                             %
115 %                                                                             %
116 %                                                                             %
117 %   D e c o d e I m a g e                                                     %
118 %                                                                             %
119 %                                                                             %
120 %                                                                             %
121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
122 %
123 %  DecodeImage unpacks the packed image pixels into runlength-encoded
124 %  pixel packets.
125 %
126 %  The format of the DecodeImage method is:
127 %
128 %      MagickBooleanType DecodeImage(Image *image,
129 %        const MagickBooleanType compression,unsigned char *pixels)
130 %
131 %  A description of each parameter follows:
132 %
133 %    o image: the address of a structure of type Image.
134 %
135 %    o compression:  A value of 1 means the compressed pixels are runlength
136 %      encoded for a 256-color bitmap.  A value of 2 means a 16-color bitmap.
137 %
138 %    o pixels:  The address of a byte (8 bits) array of pixel data created by
139 %      the decoding process.
140 %
141 */
142
143 static inline size_t MagickMin(const size_t x,const size_t y)
144 {
145   if (x < y)
146     return(x);
147   return(y);
148 }
149
150 static MagickBooleanType DecodeImage(Image *image,
151   const MagickBooleanType compression,unsigned char *pixels)
152 {
153 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__MINGW32__)
154 #define BI_RGB  0
155 #define BI_RLE8  1
156 #define BI_RLE4  2
157 #define BI_BITFIELDS  3
158 #endif
159
160   int
161     count;
162
163   long
164     y;
165
166   register long
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 == MagickSignature);
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 < (long) 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 \f
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 unsigned long 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 */
318 static size_t EncodeImage(Image *image,const unsigned long bytes_per_line,
319   const unsigned char *pixels,unsigned char *compressed_pixels)
320 {
321   long
322     y;
323
324   register const unsigned char
325     *p;
326
327   register long
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 == MagickSignature);
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 < (long) image->rows; y++)
347   {
348     for (x=0; x < (long) bytes_per_line; x+=i)
349     {
350       /*
351         Determine runlength.
352       */
353       for (i=1; ((x+i) < (long) 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 \f
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 */
401 static 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 \f
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 */
436
437 static inline long MagickAbsoluteValue(const long x)
438 {
439   if (x < 0)
440     return(-x);
441   return(x);
442 }
443
444 static inline size_t MagickMax(const size_t x,const size_t y)
445 {
446   if (x > y)
447     return(x);
448   return(y);
449 }
450
451 static Image *ReadDIBImage(const ImageInfo *image_info,ExceptionInfo *exception)
452 {
453   DIBInfo
454     dib_info;
455
456   Image
457     *image;
458
459   IndexPacket
460     index;
461
462   long
463     bit,
464     y;
465
466   MagickBooleanType
467     status;
468
469   register IndexPacket
470     *indexes;
471
472   register long
473     x;
474
475   register PixelPacket
476     *q;
477
478   register long
479     i;
480
481   register unsigned char
482     *p;
483
484   size_t
485     length;
486
487   ssize_t
488     count;
489
490   unsigned char
491     *pixels;
492
493   unsigned long
494     bytes_per_line;
495
496   /*
497     Open image file.
498   */
499   assert(image_info != (const ImageInfo *) NULL);
500   assert(image_info->signature == MagickSignature);
501   if (image_info->debug != MagickFalse)
502     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
503       image_info->filename);
504   assert(exception != (ExceptionInfo *) NULL);
505   assert(exception->signature == MagickSignature);
506   image=AcquireImage(image_info);
507   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
508   if (status == MagickFalse)
509     {
510       image=DestroyImageList(image);
511       return((Image *) NULL);
512     }
513   /*
514     Determine if this a DIB file.
515   */
516   (void) ResetMagickMemory(&dib_info,0,sizeof(dib_info));
517   dib_info.size=ReadBlobLSBLong(image);
518   if (dib_info.size!=40)
519     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
520   /*
521     Microsoft Windows 3.X DIB image file.
522   */
523   dib_info.width=(short) ReadBlobLSBLong(image);
524   dib_info.height=(short) ReadBlobLSBLong(image);
525   dib_info.planes=ReadBlobLSBShort(image);
526   dib_info.bits_per_pixel=ReadBlobLSBShort(image);
527   dib_info.compression=ReadBlobLSBLong(image);
528   dib_info.image_size=ReadBlobLSBLong(image);
529   dib_info.x_pixels=ReadBlobLSBLong(image);
530   dib_info.y_pixels=ReadBlobLSBLong(image);
531   dib_info.number_colors=ReadBlobLSBLong(image);
532   dib_info.colors_important=ReadBlobLSBLong(image);
533   if ((dib_info.compression == BI_BITFIELDS) &&
534       ((dib_info.bits_per_pixel == 16) || (dib_info.bits_per_pixel == 32)))
535     {
536       dib_info.red_mask=ReadBlobLSBLong(image);
537       dib_info.green_mask=ReadBlobLSBLong(image);
538       dib_info.blue_mask=ReadBlobLSBLong(image);
539     }
540   image->matte=dib_info.bits_per_pixel == 32 ? MagickTrue : MagickFalse;
541   image->columns=(unsigned long) MagickAbsoluteValue(dib_info.width);
542   image->rows=(unsigned long) MagickAbsoluteValue(dib_info.height);
543   image->depth=8;
544   if ((dib_info.number_colors != 0) || (dib_info.bits_per_pixel < 16))
545     {
546       image->storage_class=PseudoClass;
547       image->colors=dib_info.number_colors;
548       if (image->colors == 0)
549         image->colors=1L << dib_info.bits_per_pixel;
550     }
551   if (image_info->size)
552     {
553       RectangleInfo
554         geometry;
555
556       MagickStatusType
557         flags;
558
559       flags=ParseAbsoluteGeometry(image_info->size,&geometry);
560       if (flags & WidthValue)
561         if ((geometry.width != 0) && (geometry.width < image->columns))
562           image->columns=geometry.width;
563       if (flags & HeightValue)
564         if ((geometry.height != 0) && (geometry.height < image->rows))
565           image->rows=geometry.height;
566     }
567   if (image->storage_class == PseudoClass)
568     {
569       size_t
570         length,
571         packet_size;
572
573       unsigned char
574         *dib_colormap;
575
576       /*
577         Read DIB raster colormap.
578       */
579       if (AcquireImageColormap(image,image->colors) == MagickFalse)
580         ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
581       length=(size_t) image->colors;
582       dib_colormap=(unsigned char *) AcquireQuantumMemory(length,
583         4*sizeof(*dib_colormap));
584       if (dib_colormap == (unsigned char *) NULL)
585         ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
586       packet_size=4;
587       count=ReadBlob(image,packet_size*image->colors,dib_colormap);
588       if (count != (ssize_t) (packet_size*image->colors))
589         ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
590       p=dib_colormap;
591       for (i=0; i < (long) image->colors; i++)
592       {
593         image->colormap[i].blue=ScaleCharToQuantum(*p++);
594         image->colormap[i].green=ScaleCharToQuantum(*p++);
595         image->colormap[i].red=ScaleCharToQuantum(*p++);
596         if (packet_size == 4)
597           p++;
598       }
599       dib_colormap=(unsigned char *) RelinquishMagickMemory(dib_colormap);
600     }
601   /*
602     Read image data.
603   */
604   if (dib_info.compression == BI_RLE4)
605     dib_info.bits_per_pixel<<=1;
606   bytes_per_line=4*((image->columns*dib_info.bits_per_pixel+31)/32);
607   length=bytes_per_line*image->rows;
608   pixels=(unsigned char *) AcquireQuantumMemory((size_t) image->rows,
609     MagickMax(bytes_per_line,image->columns+256UL)*sizeof(*pixels));
610   if (pixels == (unsigned char *) NULL)
611     ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
612   if ((dib_info.compression == BI_RGB) ||
613       (dib_info.compression == BI_BITFIELDS))
614     {
615       count=ReadBlob(image,length,pixels);
616       if (count != (ssize_t) (length))
617         ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
618     }
619   else
620     {
621       /*
622         Convert run-length encoded raster pixels.
623       */
624       status=DecodeImage(image,dib_info.compression ? MagickTrue : MagickFalse,
625         pixels);
626       if (status == MagickFalse)
627         ThrowReaderException(CorruptImageError,"UnableToRunlengthDecodeImage");
628     }
629   /*
630     Initialize image structure.
631   */
632   image->units=PixelsPerCentimeterResolution;
633   image->x_resolution=(double) dib_info.x_pixels/100.0;
634   image->y_resolution=(double) dib_info.y_pixels/100.0;
635   /*
636     Convert DIB raster image to pixel packets.
637   */
638   switch (dib_info.bits_per_pixel)
639   {
640     case 1:
641     {
642       /*
643         Convert bitmap scanline.
644       */
645       for (y=(long) image->rows-1; y >= 0; y--)
646       {
647         p=pixels+(image->rows-y-1)*bytes_per_line;
648         q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
649         if (q == (PixelPacket *) NULL)
650           break;
651         indexes=GetAuthenticIndexQueue(image);
652         for (x=0; x < ((long) image->columns-7); x+=8)
653         {
654           for (bit=0; bit < 8; bit++)
655           {
656             index=(IndexPacket) ((*p) & (0x80 >> bit) ? 0x01 : 0x00);
657             indexes[x+bit]=index;
658             *q++=image->colormap[(long) index];
659           }
660           p++;
661         }
662         if ((image->columns % 8) != 0)
663           {
664             for (bit=0; bit < (long) (image->columns % 8); bit++)
665             {
666               index=(IndexPacket) ((*p) & (0x80 >> bit) ? 0x01 : 0x00);
667               indexes[x+bit]=index;
668               *q++=image->colormap[(long) index];
669             }
670             p++;
671           }
672         if (SyncAuthenticPixels(image,exception) == MagickFalse)
673           break;
674         if (image->previous == (Image *) NULL)
675           {
676             status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
677               image->rows);
678             if (status == MagickFalse)
679               break;
680           }
681       }
682       break;
683     }
684     case 4:
685     {
686       /*
687         Convert PseudoColor scanline.
688       */
689       for (y=(long) image->rows-1; y >= 0; y--)
690       {
691         p=pixels+(image->rows-y-1)*bytes_per_line;
692         q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
693         if (q == (PixelPacket *) NULL)
694           break;
695         indexes=GetAuthenticIndexQueue(image);
696         for (x=0; x < ((long) image->columns-1); x+=2)
697         {
698           index=ConstrainColormapIndex(image,(*p >> 4) & 0xf);
699           indexes[x]=index;
700           *q++=image->colormap[(long) index];
701           index=ConstrainColormapIndex(image,*p & 0xf);
702           indexes[x+1]=index;
703           *q++=image->colormap[(long) index];
704           p++;
705         }
706         if ((image->columns % 2) != 0)
707           {
708             index=ConstrainColormapIndex(image,(*p >> 4) & 0xf);
709             indexes[x]=index;
710             *q++=image->colormap[(long) index];
711             p++;
712           }
713         if (SyncAuthenticPixels(image,exception) == MagickFalse)
714           break;
715         if (image->previous == (Image *) NULL)
716           {
717             status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
718               image->rows);
719             if (status == MagickFalse)
720               break;
721           }
722       }
723       break;
724     }
725     case 8:
726     {
727       /*
728         Convert PseudoColor scanline.
729       */
730       if ((dib_info.compression == BI_RLE8) ||
731           (dib_info.compression == BI_RLE4))
732         bytes_per_line=image->columns;
733       for (y=(long) image->rows-1; y >= 0; y--)
734       {
735         p=pixels+(image->rows-y-1)*bytes_per_line;
736         q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
737         if (q == (PixelPacket *) NULL)
738           break;
739         indexes=GetAuthenticIndexQueue(image);
740         for (x=0; x < (long) image->columns; x++)
741         {
742           index=ConstrainColormapIndex(image,*p);
743           indexes[x]=index;
744           *q=image->colormap[(long) index];
745           p++;
746           q++;
747         }
748         if (SyncAuthenticPixels(image,exception) == MagickFalse)
749           break;
750         if (image->previous == (Image *) NULL)
751           {
752             status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
753               image->rows);
754             if (status == MagickFalse)
755               break;
756           }
757       }
758       break;
759     }
760     case 16:
761     {
762       unsigned short
763         word;
764
765       /*
766         Convert PseudoColor scanline.
767       */
768       image->storage_class=DirectClass;
769       if (dib_info.compression == BI_RLE8)
770         bytes_per_line=2*image->columns;
771       for (y=(long) image->rows-1; y >= 0; y--)
772       {
773         p=pixels+(image->rows-y-1)*bytes_per_line;
774         q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
775         if (q == (PixelPacket *) NULL)
776           break;
777         for (x=0; x < (long) image->columns; x++)
778         {
779           word=(*p++);
780           word|=(*p++ << 8);
781           if (dib_info.red_mask == 0)
782             {
783               q->red=ScaleCharToQuantum(ScaleColor5to8((unsigned char)
784                 ((word >> 10) & 0x1f)));
785               q->green=ScaleCharToQuantum(ScaleColor5to8((unsigned char)
786                 ((word >> 5) & 0x1f)));
787               q->blue=ScaleCharToQuantum(ScaleColor5to8((unsigned char)
788                 (word & 0x1f)));
789             }
790           else
791             {
792               q->red=ScaleCharToQuantum(ScaleColor5to8((unsigned char)
793                 ((word >> 11) & 0x1f)));
794               q->green=ScaleCharToQuantum(ScaleColor6to8((unsigned char)
795                 ((word >> 5) & 0x3f)));
796               q->blue=ScaleCharToQuantum(ScaleColor5to8((unsigned char)
797                 (word & 0x1f)));
798             }
799           q++;
800         }
801         if (SyncAuthenticPixels(image,exception) == MagickFalse)
802           break;
803         if (image->previous == (Image *) NULL)
804           {
805             status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
806               image->rows);
807             if (status == MagickFalse)
808               break;
809           }
810       }
811       break;
812     }
813     case 24:
814     case 32:
815     {
816       /*
817         Convert DirectColor scanline.
818       */
819       for (y=(long) 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 == (PixelPacket *) NULL)
824           break;
825         for (x=0; x < (long) image->columns; x++)
826         {
827           q->blue=ScaleCharToQuantum(*p++);
828           q->green=ScaleCharToQuantum(*p++);
829           q->red=ScaleCharToQuantum(*p++);
830           if (image->matte != MagickFalse)
831             q->opacity=ScaleCharToQuantum(*p++);
832           q++;
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     default:
847       ThrowReaderException(CorruptImageError,"ImproperImageHeader");
848   }
849   pixels=(unsigned char *) RelinquishMagickMemory(pixels);
850   if (EOFBlob(image) != MagickFalse)
851     ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
852       image->filename);
853   if (dib_info.height < 0)
854     {
855       Image
856         *flipped_image;
857
858       /*
859         Correct image orientation.
860       */
861       flipped_image=FlipImage(image,exception);
862       if (flipped_image != (Image *) NULL)
863         {
864           DuplicateBlob(flipped_image,image);
865           image=DestroyImage(image);
866           image=flipped_image;
867         }
868     }
869   (void) CloseBlob(image);
870   return(GetFirstImageInList(image));
871 }
872 \f
873 /*
874 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
875 %                                                                             %
876 %                                                                             %
877 %                                                                             %
878 %   R e g i s t e r D I B I m a g e                                           %
879 %                                                                             %
880 %                                                                             %
881 %                                                                             %
882 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
883 %
884 %  RegisterDIBImage() adds attributes for the DIB image format to
885 %  the list of supported formats.  The attributes include the image format
886 %  tag, a method to read and/or write the format, whether the format
887 %  supports the saving of more than one frame to the same file or blob,
888 %  whether the format supports native in-memory I/O, and a brief
889 %  description of the format.
890 %
891 %  The format of the RegisterDIBImage method is:
892 %
893 %      unsigned long RegisterDIBImage(void)
894 %
895 */
896 ModuleExport unsigned long RegisterDIBImage(void)
897 {
898   MagickInfo
899     *entry;
900
901   entry=SetMagickInfo("DIB");
902   entry->decoder=(DecodeImageHandler *) ReadDIBImage;
903   entry->encoder=(EncodeImageHandler *) WriteDIBImage;
904   entry->magick=(IsImageFormatHandler *) IsDIB;
905   entry->adjoin=MagickFalse;
906   entry->stealth=MagickTrue;
907   entry->description=ConstantString(
908     "Microsoft Windows 3.X Packed Device-Independent Bitmap");
909   entry->module=ConstantString("DIB");
910   (void) RegisterMagickInfo(entry);
911   return(MagickImageCoderSignature);
912 }
913 \f
914 /*
915 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
916 %                                                                             %
917 %                                                                             %
918 %                                                                             %
919 %   U n r e g i s t e r D I B I m a g e                                       %
920 %                                                                             %
921 %                                                                             %
922 %                                                                             %
923 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
924 %
925 %  UnregisterDIBImage() removes format registrations made by the
926 %  DIB module from the list of supported formats.
927 %
928 %  The format of the UnregisterDIBImage method is:
929 %
930 %      UnregisterDIBImage(void)
931 %
932 */
933 ModuleExport void UnregisterDIBImage(void)
934 {
935   (void) UnregisterMagickInfo("DIB");
936 }
937 \f
938 /*
939 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
940 %                                                                             %
941 %                                                                             %
942 %                                                                             %
943 %   W r i t e D I B I m a g e                                                 %
944 %                                                                             %
945 %                                                                             %
946 %                                                                             %
947 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
948 %
949 %  WriteDIBImage() writes an image in Microsoft Windows bitmap encoded
950 %  image format.
951 %
952 %  The format of the WriteDIBImage method is:
953 %
954 %      MagickBooleanType WriteDIBImage(const ImageInfo *image_info,Image *image)
955 %
956 %  A description of each parameter follows.
957 %
958 %    o image_info: the image info.
959 %
960 %    o image:  The image.
961 %
962 */
963 static MagickBooleanType WriteDIBImage(const ImageInfo *image_info,Image *image)
964 {
965   DIBInfo
966     dib_info;
967
968   long
969     y;
970
971   MagickBooleanType
972     status;
973
974   register const IndexPacket
975     *indexes;
976
977   register const PixelPacket
978     *p;
979
980   register long
981     i,
982     x;
983
984   register unsigned char
985     *q;
986
987   unsigned char
988     *dib_data,
989     *pixels;
990
991   unsigned long
992     bytes_per_line;
993
994   /*
995     Open output image file.
996   */
997   assert(image_info != (const ImageInfo *) NULL);
998   assert(image_info->signature == MagickSignature);
999   assert(image != (Image *) NULL);
1000   assert(image->signature == MagickSignature);
1001   if (image->debug != MagickFalse)
1002     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1003   status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
1004   if (status == MagickFalse)
1005     return(status);
1006   /*
1007     Initialize DIB raster file header.
1008   */
1009   if (image->colorspace != RGBColorspace)
1010     (void) TransformImageColorspace(image,RGBColorspace);
1011   if (image->storage_class == DirectClass)
1012     {
1013       /*
1014         Full color DIB raster.
1015       */
1016       dib_info.number_colors=0;
1017       dib_info.bits_per_pixel=(unsigned short) (image->matte ? 32 : 24);
1018     }
1019   else
1020     {
1021       /*
1022         Colormapped DIB raster.
1023       */
1024       dib_info.bits_per_pixel=8;
1025       if (image_info->depth > 8)
1026         dib_info.bits_per_pixel=16;
1027       if (IsMonochromeImage(image,&image->exception) != MagickFalse)
1028         dib_info.bits_per_pixel=1;
1029       dib_info.number_colors=(dib_info.bits_per_pixel == 16) ? 0 :
1030         (1UL << dib_info.bits_per_pixel);
1031     }
1032   bytes_per_line=4*((image->columns*dib_info.bits_per_pixel+31)/32);
1033   dib_info.size=40;
1034   dib_info.width=(long) image->columns;
1035   dib_info.height=(long) image->rows;
1036   dib_info.planes=1;
1037   dib_info.compression=(unsigned long) (dib_info.bits_per_pixel == 16 ?
1038     BI_BITFIELDS : BI_RGB);
1039   dib_info.image_size=bytes_per_line*image->rows;
1040   dib_info.x_pixels=75*39;
1041   dib_info.y_pixels=75*39;
1042   switch (image->units)
1043   {
1044     case UndefinedResolution:
1045     case PixelsPerInchResolution:
1046     {
1047       dib_info.x_pixels=(unsigned long) (100.0*image->x_resolution/2.54);
1048       dib_info.y_pixels=(unsigned long) (100.0*image->y_resolution/2.54);
1049       break;
1050     }
1051     case PixelsPerCentimeterResolution:
1052     {
1053       dib_info.x_pixels=(unsigned long) (100.0*image->x_resolution);
1054       dib_info.y_pixels=(unsigned long) (100.0*image->y_resolution);
1055       break;
1056     }
1057   }
1058   dib_info.colors_important=dib_info.number_colors;
1059   /*
1060     Convert MIFF to DIB raster pixels.
1061   */
1062   pixels=(unsigned char *) AcquireQuantumMemory(dib_info.image_size,
1063     sizeof(*pixels));
1064   if (pixels == (unsigned char *) NULL)
1065     ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1066   (void) ResetMagickMemory(pixels,0,dib_info.image_size);
1067   switch (dib_info.bits_per_pixel)
1068   {
1069     case 1:
1070     {
1071       register unsigned char
1072         bit,
1073         byte;
1074
1075       /*
1076         Convert PseudoClass image to a DIB monochrome image.
1077       */
1078       for (y=0; y < (long) image->rows; y++)
1079       {
1080         p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1081         if (p == (const PixelPacket *) NULL)
1082           break;
1083         indexes=GetVirtualIndexQueue(image);
1084         q=pixels+(image->rows-y-1)*bytes_per_line;
1085         bit=0;
1086         byte=0;
1087         for (x=0; x < (long) image->columns; x++)
1088         {
1089           byte<<=1;
1090           byte|=indexes[x] != 0 ? 0x01 : 0x00;
1091           bit++;
1092           if (bit == 8)
1093             {
1094               *q++=byte;
1095               bit=0;
1096               byte=0;
1097             }
1098            p++;
1099          }
1100          if (bit != 0)
1101            {
1102              *q++=(unsigned char) (byte << (8-bit));
1103              x++;
1104            }
1105         for (x=(long) (image->columns+7)/8; x < (long) bytes_per_line; x++)
1106           *q++=0x00;
1107         status=SetImageProgress(image,SaveImageTag,y,image->rows);
1108         if (status == MagickFalse)
1109           break;
1110       }
1111       break;
1112     }
1113     case 8:
1114     {
1115       /*
1116         Convert PseudoClass packet to DIB pixel.
1117       */
1118       for (y=0; y < (long) image->rows; y++)
1119       {
1120         p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1121         if (p == (const PixelPacket *) NULL)
1122           break;
1123         indexes=GetVirtualIndexQueue(image);
1124         q=pixels+(image->rows-y-1)*bytes_per_line;
1125         for (x=0; x < (long) image->columns; x++)
1126           *q++=(unsigned char) indexes[x];
1127         for ( ; x < (long) bytes_per_line; x++)
1128           *q++=0x00;
1129         status=SetImageProgress(image,SaveImageTag,y,image->rows);
1130         if (status == MagickFalse)
1131           break;
1132       }
1133       break;
1134     }
1135     case 16:
1136     {
1137       unsigned short
1138         word;
1139       /*
1140         Convert PseudoClass packet to DIB pixel. 
1141       */
1142       for (y=0; y < (long) image->rows; y++)
1143       {
1144         p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1145         if (p == (const PixelPacket *) NULL)
1146           break;
1147         q=pixels+(image->rows-y-1)*bytes_per_line;
1148         for (x=0; x < (long) image->columns; x++)
1149         {
1150           word=(unsigned short) ((ScaleColor8to5((unsigned char)
1151             ScaleQuantumToChar(GetRedPixelComponent(p))) << 11) | (ScaleColor8to6((unsigned char)
1152             ScaleQuantumToChar(GetGreenPixelComponent(p))) << 5) | (ScaleColor8to5(
1153             (unsigned char) ScaleQuantumToChar((unsigned char) GetBluePixelComponent(p)) << 0)));
1154           *q++=(unsigned char)(word & 0xff);
1155           *q++=(unsigned char)(word >> 8);
1156           p++;
1157         }
1158         for (x=2L*image->columns; x < (long) bytes_per_line; x++)
1159           *q++=0x00;
1160         status=SetImageProgress(image,SaveImageTag,y,image->rows);
1161         if (status == MagickFalse)
1162           break;
1163       }
1164       break;
1165     }
1166     case 24:
1167     case 32:
1168     {
1169       /*
1170         Convert DirectClass packet to DIB RGB pixel.
1171       */
1172       for (y=0; y < (long) image->rows; y++)
1173       {
1174         p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1175         if (p == (const PixelPacket *) NULL)
1176           break;
1177         q=pixels+(image->rows-y-1)*bytes_per_line;
1178         for (x=0; x < (long) image->columns; x++)
1179         {
1180           *q++=ScaleQuantumToChar(GetBluePixelComponent(p));
1181           *q++=ScaleQuantumToChar(GetGreenPixelComponent(p));
1182           *q++=ScaleQuantumToChar(GetRedPixelComponent(p));
1183           if (image->matte != MagickFalse)
1184             *q++=ScaleQuantumToChar(GetOpacityPixelComponent(p));
1185           p++;
1186         }
1187         if (dib_info.bits_per_pixel == 24)
1188           for (x=3L*image->columns; x < (long) bytes_per_line; x++)
1189             *q++=0x00;
1190         status=SetImageProgress(image,SaveImageTag,y,image->rows);
1191         if (status == MagickFalse)
1192           break;
1193       }
1194       break;
1195     }
1196   }
1197   if (dib_info.bits_per_pixel == 8)
1198     if (image_info->compression != NoCompression)
1199       {
1200         size_t
1201           length;
1202
1203         /*
1204           Convert run-length encoded raster pixels.
1205         */
1206         length=2UL*(bytes_per_line+2UL)+2UL;
1207         dib_data=(unsigned char *) AcquireQuantumMemory(length,
1208           (image->rows+2UL)*sizeof(*dib_data));
1209         if (pixels == (unsigned char *) NULL)
1210           {
1211             pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1212             ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1213           }
1214         dib_info.image_size=(unsigned long) EncodeImage(image,bytes_per_line,
1215           pixels,dib_data);
1216         pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1217         pixels=dib_data;
1218         dib_info.compression = BI_RLE8;
1219       }
1220   /*
1221     Write DIB header.
1222   */
1223   (void) WriteBlobLSBLong(image,dib_info.size);
1224   (void) WriteBlobLSBLong(image,(unsigned long) dib_info.width);
1225   (void) WriteBlobLSBLong(image,(unsigned short) dib_info.height);
1226   (void) WriteBlobLSBShort(image,(unsigned short) dib_info.planes);
1227   (void) WriteBlobLSBShort(image,dib_info.bits_per_pixel);
1228   (void) WriteBlobLSBLong(image,dib_info.compression);
1229   (void) WriteBlobLSBLong(image,dib_info.image_size);
1230   (void) WriteBlobLSBLong(image,dib_info.x_pixels);
1231   (void) WriteBlobLSBLong(image,dib_info.y_pixels);
1232   (void) WriteBlobLSBLong(image,dib_info.number_colors);
1233   (void) WriteBlobLSBLong(image,dib_info.colors_important);
1234   if (image->storage_class == PseudoClass)
1235     {
1236       if (dib_info.bits_per_pixel <= 8)
1237         {
1238           unsigned char
1239             *dib_colormap;
1240
1241           /*
1242             Dump colormap to file.
1243           */
1244           dib_colormap=(unsigned char *) AcquireQuantumMemory((size_t)
1245             (1UL << dib_info.bits_per_pixel),4*sizeof(dib_colormap));
1246           if (dib_colormap == (unsigned char *) NULL)
1247             ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1248           q=dib_colormap;
1249           for (i=0; i < (long) MagickMin(image->colors,dib_info.number_colors); i++)
1250           {
1251             *q++=ScaleQuantumToChar(image->colormap[i].blue);
1252             *q++=ScaleQuantumToChar(image->colormap[i].green);
1253             *q++=ScaleQuantumToChar(image->colormap[i].red);
1254             *q++=(Quantum) 0x0;
1255           }
1256           for ( ; i < (long) (1L << dib_info.bits_per_pixel); i++)
1257           {
1258             *q++=(Quantum) 0x0;
1259             *q++=(Quantum) 0x0;
1260             *q++=(Quantum) 0x0;
1261             *q++=(Quantum) 0x0;
1262           }
1263           (void) WriteBlob(image,(size_t) (4*(1 << dib_info.bits_per_pixel)),
1264             dib_colormap);
1265           dib_colormap=(unsigned char *) RelinquishMagickMemory(dib_colormap);
1266         }
1267       else
1268         if ((dib_info.bits_per_pixel == 16) &&
1269             (dib_info.compression == BI_BITFIELDS))
1270           {
1271             (void) WriteBlobLSBLong(image,0xf800);
1272             (void) WriteBlobLSBLong(image,0x07e0);
1273             (void) WriteBlobLSBLong(image,0x001f);
1274           }
1275     }
1276   (void) WriteBlob(image,dib_info.image_size,pixels);
1277   pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1278   (void) CloseBlob(image);
1279   return(MagickTrue);
1280 }