]> 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(__WINDOWS__) || 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           image=DestroyImageList(image);
865           return((Image *) NULL);
866         }
867       DuplicateBlob(flipped_image,image);
868       image=DestroyImage(image);
869       image=flipped_image;
870     }
871   (void) CloseBlob(image);
872   return(GetFirstImageInList(image));
873 }
874 \f
875 /*
876 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
877 %                                                                             %
878 %                                                                             %
879 %                                                                             %
880 %   R e g i s t e r D I B I m a g e                                           %
881 %                                                                             %
882 %                                                                             %
883 %                                                                             %
884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
885 %
886 %  RegisterDIBImage() adds attributes for the DIB image format to
887 %  the list of supported formats.  The attributes include the image format
888 %  tag, a method to read and/or write the format, whether the format
889 %  supports the saving of more than one frame to the same file or blob,
890 %  whether the format supports native in-memory I/O, and a brief
891 %  description of the format.
892 %
893 %  The format of the RegisterDIBImage method is:
894 %
895 %      unsigned long RegisterDIBImage(void)
896 %
897 */
898 ModuleExport unsigned long RegisterDIBImage(void)
899 {
900   MagickInfo
901     *entry;
902
903   entry=SetMagickInfo("DIB");
904   entry->decoder=(DecodeImageHandler *) ReadDIBImage;
905   entry->encoder=(EncodeImageHandler *) WriteDIBImage;
906   entry->magick=(IsImageFormatHandler *) IsDIB;
907   entry->adjoin=MagickFalse;
908   entry->stealth=MagickTrue;
909   entry->description=ConstantString(
910     "Microsoft Windows 3.X Packed Device-Independent Bitmap");
911   entry->module=ConstantString("DIB");
912   (void) RegisterMagickInfo(entry);
913   return(MagickImageCoderSignature);
914 }
915 \f
916 /*
917 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
918 %                                                                             %
919 %                                                                             %
920 %                                                                             %
921 %   U n r e g i s t e r D I B I m a g e                                       %
922 %                                                                             %
923 %                                                                             %
924 %                                                                             %
925 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
926 %
927 %  UnregisterDIBImage() removes format registrations made by the
928 %  DIB module from the list of supported formats.
929 %
930 %  The format of the UnregisterDIBImage method is:
931 %
932 %      UnregisterDIBImage(void)
933 %
934 */
935 ModuleExport void UnregisterDIBImage(void)
936 {
937   (void) UnregisterMagickInfo("DIB");
938 }
939 \f
940 /*
941 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
942 %                                                                             %
943 %                                                                             %
944 %                                                                             %
945 %   W r i t e D I B I m a g e                                                 %
946 %                                                                             %
947 %                                                                             %
948 %                                                                             %
949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
950 %
951 %  WriteDIBImage() writes an image in Microsoft Windows bitmap encoded
952 %  image format.
953 %
954 %  The format of the WriteDIBImage method is:
955 %
956 %      MagickBooleanType WriteDIBImage(const ImageInfo *image_info,Image *image)
957 %
958 %  A description of each parameter follows.
959 %
960 %    o image_info: the image info.
961 %
962 %    o image:  The image.
963 %
964 */
965 static MagickBooleanType WriteDIBImage(const ImageInfo *image_info,Image *image)
966 {
967   DIBInfo
968     dib_info;
969
970   long
971     y;
972
973   MagickBooleanType
974     status;
975
976   register const IndexPacket
977     *indexes;
978
979   register const PixelPacket
980     *p;
981
982   register long
983     i,
984     x;
985
986   register unsigned char
987     *q;
988
989   unsigned char
990     *dib_data,
991     *pixels;
992
993   unsigned long
994     bytes_per_line;
995
996   /*
997     Open output image file.
998   */
999   assert(image_info != (const ImageInfo *) NULL);
1000   assert(image_info->signature == MagickSignature);
1001   assert(image != (Image *) NULL);
1002   assert(image->signature == MagickSignature);
1003   if (image->debug != MagickFalse)
1004     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1005   status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
1006   if (status == MagickFalse)
1007     return(status);
1008   /*
1009     Initialize DIB raster file header.
1010   */
1011   if (image->colorspace != RGBColorspace)
1012     (void) TransformImageColorspace(image,RGBColorspace);
1013   if (image->storage_class == DirectClass)
1014     {
1015       /*
1016         Full color DIB raster.
1017       */
1018       dib_info.number_colors=0;
1019       dib_info.bits_per_pixel=(unsigned short) (image->matte ? 32 : 24);
1020     }
1021   else
1022     {
1023       /*
1024         Colormapped DIB raster.
1025       */
1026       dib_info.bits_per_pixel=8;
1027       if (image_info->depth > 8)
1028         dib_info.bits_per_pixel=16;
1029       if (IsMonochromeImage(image,&image->exception) != MagickFalse)
1030         dib_info.bits_per_pixel=1;
1031       dib_info.number_colors=(dib_info.bits_per_pixel == 16) ? 0 :
1032         (1UL << dib_info.bits_per_pixel);
1033     }
1034   bytes_per_line=4*((image->columns*dib_info.bits_per_pixel+31)/32);
1035   dib_info.size=40;
1036   dib_info.width=(long) image->columns;
1037   dib_info.height=(long) image->rows;
1038   dib_info.planes=1;
1039   dib_info.compression=(unsigned long) (dib_info.bits_per_pixel == 16 ?
1040     BI_BITFIELDS : BI_RGB);
1041   dib_info.image_size=bytes_per_line*image->rows;
1042   dib_info.x_pixels=75*39;
1043   dib_info.y_pixels=75*39;
1044   switch (image->units)
1045   {
1046     case UndefinedResolution:
1047     case PixelsPerInchResolution:
1048     {
1049       dib_info.x_pixels=(unsigned long) (100.0*image->x_resolution/2.54);
1050       dib_info.y_pixels=(unsigned long) (100.0*image->y_resolution/2.54);
1051       break;
1052     }
1053     case PixelsPerCentimeterResolution:
1054     {
1055       dib_info.x_pixels=(unsigned long) (100.0*image->x_resolution);
1056       dib_info.y_pixels=(unsigned long) (100.0*image->y_resolution);
1057       break;
1058     }
1059   }
1060   dib_info.colors_important=dib_info.number_colors;
1061   /*
1062     Convert MIFF to DIB raster pixels.
1063   */
1064   pixels=(unsigned char *) AcquireQuantumMemory(dib_info.image_size,
1065     sizeof(*pixels));
1066   if (pixels == (unsigned char *) NULL)
1067     ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1068   (void) ResetMagickMemory(pixels,0,dib_info.image_size);
1069   switch (dib_info.bits_per_pixel)
1070   {
1071     case 1:
1072     {
1073       register unsigned char
1074         bit,
1075         byte;
1076
1077       /*
1078         Convert PseudoClass image to a DIB monochrome image.
1079       */
1080       for (y=0; y < (long) image->rows; y++)
1081       {
1082         p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1083         if (p == (const PixelPacket *) NULL)
1084           break;
1085         indexes=GetVirtualIndexQueue(image);
1086         q=pixels+(image->rows-y-1)*bytes_per_line;
1087         bit=0;
1088         byte=0;
1089         for (x=0; x < (long) image->columns; x++)
1090         {
1091           byte<<=1;
1092           byte|=indexes[x] != 0 ? 0x01 : 0x00;
1093           bit++;
1094           if (bit == 8)
1095             {
1096               *q++=byte;
1097               bit=0;
1098               byte=0;
1099             }
1100            p++;
1101          }
1102          if (bit != 0)
1103            {
1104              *q++=(unsigned char) (byte << (8-bit));
1105              x++;
1106            }
1107         for (x=(long) (image->columns+7)/8; x < (long) bytes_per_line; x++)
1108           *q++=0x00;
1109         status=SetImageProgress(image,SaveImageTag,y,image->rows);
1110         if (status == MagickFalse)
1111           break;
1112       }
1113       break;
1114     }
1115     case 8:
1116     {
1117       /*
1118         Convert PseudoClass packet to DIB pixel.
1119       */
1120       for (y=0; y < (long) image->rows; y++)
1121       {
1122         p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1123         if (p == (const PixelPacket *) NULL)
1124           break;
1125         indexes=GetVirtualIndexQueue(image);
1126         q=pixels+(image->rows-y-1)*bytes_per_line;
1127         for (x=0; x < (long) image->columns; x++)
1128           *q++=(unsigned char) indexes[x];
1129         for ( ; x < (long) bytes_per_line; x++)
1130           *q++=0x00;
1131         status=SetImageProgress(image,SaveImageTag,y,image->rows);
1132         if (status == MagickFalse)
1133           break;
1134       }
1135       break;
1136     }
1137     case 16:
1138     {
1139       unsigned short
1140         word;
1141       /*
1142         Convert PseudoClass packet to DIB pixel. 
1143       */
1144       for (y=0; y < (long) image->rows; y++)
1145       {
1146         p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1147         if (p == (const PixelPacket *) NULL)
1148           break;
1149         q=pixels+(image->rows-y-1)*bytes_per_line;
1150         for (x=0; x < (long) image->columns; x++)
1151         {
1152           word=(unsigned short) ((ScaleColor8to5((unsigned char)
1153             ScaleQuantumToChar(GetRedSample(p))) << 11) | (ScaleColor8to6((unsigned char)
1154             ScaleQuantumToChar(GetGreenSample(p))) << 5) | (ScaleColor8to5(
1155             (unsigned char) ScaleQuantumToChar((unsigned char) GetBlueSample(p)) << 0)));
1156           *q++=(unsigned char)(word & 0xff);
1157           *q++=(unsigned char)(word >> 8);
1158           p++;
1159         }
1160         for (x=2L*image->columns; x < (long) bytes_per_line; x++)
1161           *q++=0x00;
1162         status=SetImageProgress(image,SaveImageTag,y,image->rows);
1163         if (status == MagickFalse)
1164           break;
1165       }
1166       break;
1167     }
1168     case 24:
1169     case 32:
1170     {
1171       /*
1172         Convert DirectClass packet to DIB RGB pixel.
1173       */
1174       for (y=0; y < (long) image->rows; y++)
1175       {
1176         p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1177         if (p == (const PixelPacket *) NULL)
1178           break;
1179         q=pixels+(image->rows-y-1)*bytes_per_line;
1180         for (x=0; x < (long) image->columns; x++)
1181         {
1182           *q++=ScaleQuantumToChar(GetBlueSample(p));
1183           *q++=ScaleQuantumToChar(GetGreenSample(p));
1184           *q++=ScaleQuantumToChar(GetRedSample(p));
1185           if (image->matte != MagickFalse)
1186             *q++=ScaleQuantumToChar(GetOpacitySample(p));
1187           p++;
1188         }
1189         if (dib_info.bits_per_pixel == 24)
1190           for (x=3L*image->columns; x < (long) bytes_per_line; x++)
1191             *q++=0x00;
1192         status=SetImageProgress(image,SaveImageTag,y,image->rows);
1193         if (status == MagickFalse)
1194           break;
1195       }
1196       break;
1197     }
1198   }
1199   if (dib_info.bits_per_pixel == 8)
1200     if (image_info->compression != NoCompression)
1201       {
1202         size_t
1203           length;
1204
1205         /*
1206           Convert run-length encoded raster pixels.
1207         */
1208         length=2UL*(bytes_per_line+2UL)+2UL;
1209         dib_data=(unsigned char *) AcquireQuantumMemory(length,
1210           (image->rows+2UL)*sizeof(*dib_data));
1211         if (pixels == (unsigned char *) NULL)
1212           {
1213             pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1214             ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1215           }
1216         dib_info.image_size=(unsigned long) EncodeImage(image,bytes_per_line,
1217           pixels,dib_data);
1218         pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1219         pixels=dib_data;
1220         dib_info.compression = BI_RLE8;
1221       }
1222   /*
1223     Write DIB header.
1224   */
1225   (void) WriteBlobLSBLong(image,dib_info.size);
1226   (void) WriteBlobLSBLong(image,(unsigned long) dib_info.width);
1227   (void) WriteBlobLSBLong(image,(unsigned short) dib_info.height);
1228   (void) WriteBlobLSBShort(image,(unsigned short) dib_info.planes);
1229   (void) WriteBlobLSBShort(image,dib_info.bits_per_pixel);
1230   (void) WriteBlobLSBLong(image,dib_info.compression);
1231   (void) WriteBlobLSBLong(image,dib_info.image_size);
1232   (void) WriteBlobLSBLong(image,dib_info.x_pixels);
1233   (void) WriteBlobLSBLong(image,dib_info.y_pixels);
1234   (void) WriteBlobLSBLong(image,dib_info.number_colors);
1235   (void) WriteBlobLSBLong(image,dib_info.colors_important);
1236   if (image->storage_class == PseudoClass)
1237     {
1238       if (dib_info.bits_per_pixel <= 8)
1239         {
1240           unsigned char
1241             *dib_colormap;
1242
1243           /*
1244             Dump colormap to file.
1245           */
1246           dib_colormap=(unsigned char *) AcquireQuantumMemory((size_t)
1247             (1UL << dib_info.bits_per_pixel),4*sizeof(dib_colormap));
1248           if (dib_colormap == (unsigned char *) NULL)
1249             ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1250           q=dib_colormap;
1251           for (i=0; i < (long) MagickMin(image->colors,dib_info.number_colors); i++)
1252           {
1253             *q++=ScaleQuantumToChar(image->colormap[i].blue);
1254             *q++=ScaleQuantumToChar(image->colormap[i].green);
1255             *q++=ScaleQuantumToChar(image->colormap[i].red);
1256             *q++=(Quantum) 0x0;
1257           }
1258           for ( ; i < (long) (1L << dib_info.bits_per_pixel); i++)
1259           {
1260             *q++=(Quantum) 0x0;
1261             *q++=(Quantum) 0x0;
1262             *q++=(Quantum) 0x0;
1263             *q++=(Quantum) 0x0;
1264           }
1265           (void) WriteBlob(image,(size_t) (4*(1 << dib_info.bits_per_pixel)),
1266             dib_colormap);
1267           dib_colormap=(unsigned char *) RelinquishMagickMemory(dib_colormap);
1268         }
1269       else
1270         if ((dib_info.bits_per_pixel == 16) &&
1271             (dib_info.compression == BI_BITFIELDS))
1272           {
1273             (void) WriteBlobLSBLong(image,0xf800);
1274             (void) WriteBlobLSBLong(image,0x07e0);
1275             (void) WriteBlobLSBLong(image,0x001f);
1276           }
1277     }
1278   (void) WriteBlob(image,dib_info.image_size,pixels);
1279   pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1280   (void) CloseBlob(image);
1281   return(MagickTrue);
1282 }