dib.c revision b0a657e13c4aefba39c51292005427b47277869d
13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            DDDD   IIIII  BBBB                               %
73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            D   D    I    B   B                              %
83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            D   D    I    BBBB                               %
93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            D   D    I    B   B                              %
103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            DDDD   IIIII  BBBB                               %
113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                   Read/Write Windows DIB Image Format                       %
143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              Software Design                                %
163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                John Cristy                                  %
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                 July 1992                                   %
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
201454be7db7a897f42cd40e4165f945d77196a6f8cristy%  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  dedicated to making software imaging solutions freely available.           %
223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  You may not use this file except in compliance with the License.  You may  %
243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  obtain a copy of the License at                                            %
253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    http://www.imagemagick.org/script/license.php                            %
273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Unless required by applicable law or agreed to in writing, software        %
293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  distributed under the License is distributed on an "AS IS" BASIS,          %
303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  See the License for the specific language governing permissions and        %
323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  limitations under the License.                                             %
333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Include declarations.
413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
424c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/studio.h"
434c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/attribute.h"
444c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob.h"
454c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob-private.h"
464c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/cache.h"
474c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color.h"
484c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color-private.h"
494c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/colormap.h"
504c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/colormap-private.h"
514c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/colorspace.h"
52510d06a3f7063e91993e13d546d5685048248074cristy#include "MagickCore/colorspace-private.h"
534c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/draw.h"
544c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception.h"
554c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception-private.h"
564c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/geometry.h"
574c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image.h"
584c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image-private.h"
594c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/list.h"
604c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/log.h"
614c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/magick.h"
624c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/memory_.h"
634c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor.h"
644c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor-private.h"
654c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/pixel-accessor.h"
664c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/quantum-private.h"
674c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/static.h"
684c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string_.h"
694c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/module.h"
704c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/transform.h"
713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Typedef declarations.
743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
753ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _DIBInfo
763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
77f6fe0a138e6b5879b6c11a27d715412479acf128cristy  size_t
783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    size;
793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80f6fe0a138e6b5879b6c11a27d715412479acf128cristy  ssize_t
813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width,
823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height;
833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned short
853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    planes,
863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bits_per_pixel;
873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88f6fe0a138e6b5879b6c11a27d715412479acf128cristy  size_t
893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    compression,
903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_size,
913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x_pixels,
923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y_pixels,
933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    number_colors,
943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red_mask,
953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green_mask,
963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue_mask,
973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    alpha_mask,
983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    colors_important;
993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100f6fe0a138e6b5879b6c11a27d715412479acf128cristy  ssize_t
1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    colorspace;
1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PointInfo
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red_primary,
1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green_primary,
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue_primary,
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    gamma_scale;
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} DIBInfo;
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
1141e178e70fb3c956f9fc1e30c3ba863e882666465cristy  WriteDIBImage(const ImageInfo *,Image *,ExceptionInfo *);
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   D e c o d e I m a g e                                                     %
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  DecodeImage unpacks the packed image pixels into runlength-encoded
1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pixel packets.
1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the DecodeImage method is:
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType DecodeImage(Image *image,
1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        const MagickBooleanType compression,unsigned char *pixels)
1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the address of a structure of type Image.
1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o compression:  A value of 1 means the compressed pixels are runlength
1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      encoded for a 256-color bitmap.  A value of 2 means a 16-color bitmap.
1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o pixels:  The address of a byte (8 bits) array of pixel data created by
1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      the decoding process.
1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic inline size_t MagickMin(const size_t x,const size_t y)
1483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x < y)
1503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
1513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
1523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1543ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType DecodeImage(Image *image,
1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const MagickBooleanType compression,unsigned char *pixels)
1563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1570157aeadef2fce908277168097a160a8f15a6952cristy#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__MINGW32__)
1583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define BI_RGB  0
1593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define BI_RLE8  1
1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define BI_RLE4  2
1613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define BI_BITFIELDS  3
1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
1653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
167bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
170bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p,
1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    byte;
1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(pixels != (unsigned char *) NULL);
1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(pixels,0,(size_t) image->columns*image->rows*
1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*pixels));
1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  byte=0;
1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  p=pixels;
1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  q=pixels+(size_t) image->columns*image->rows;
192bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; )
1933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((p < pixels) || (p >= q))
1953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
1963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=ReadBlobByte(image);
1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (count == EOF)
1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (count != 0)
2003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(int) MagickMin((size_t) count,(size_t) (q-p));
2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Encoded mode.
2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        byte=(unsigned char) ReadBlobByte(image);
2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (compression == BI_RLE8)
2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < count; i++)
2093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *p++=(unsigned char) byte;
2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < count; i++)
2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *p++=(unsigned char)
2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ((i & 0x01) != 0 ? (byte & 0x0f) : ((byte >> 4) & 0x0f));
2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
2173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        x+=count;
2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
2213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
2223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Escape mode.
2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=ReadBlobByte(image);
2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0x01)
2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickTrue);
2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        switch (count)
2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 0x00:
2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              End of line.
2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            x=0;
2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            y++;
2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=pixels+y*image->columns;
2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 0x02:
2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Delta mode.
2433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            x+=ReadBlobByte(image);
2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            y+=ReadBlobByte(image);
2463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=pixels+y*image->columns+x;
2473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
2483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
2493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
2503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
2523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Absolute mode.
2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
2543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            count=(int) MagickMin((size_t) count,(size_t) (q-p));
2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (compression == BI_RLE8)
2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < count; i++)
2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *p++=(unsigned char) ReadBlobByte(image);
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < count; i++)
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((i & 0x01) == 0)
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  byte=(unsigned char) ReadBlobByte(image);
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *p++=(unsigned char)
2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ((i & 0x01) != 0 ? (byte & 0x0f) : ((byte >> 4) & 0x0f));
2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            x+=count;
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read pad byte.
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (compression == BI_RLE8)
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((count & 0x01) != 0)
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ReadBlobByte(image);
2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (((count & 0x03) == 1) || ((count & 0x03) == 2))
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ReadBlobByte(image);
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SetImageProgress(image,LoadImageTag,y,image->rows) == MagickFalse)
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ReadBlobByte(image);  /* end of line */
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ReadBlobByte(image);
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   E n c o d e I m a g e                                                     %
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  EncodeImage compresses pixels using a runlength encoded format.
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the EncodeImage method is:
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    static MagickBooleanType EncodeImage(Image *image,
306bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      const size_t bytes_per_line,const unsigned char *pixels,
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      unsigned char *compressed_pixels)
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o bytes_per_line: the number of bytes in a scanline of compressed pixels
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o pixels:  The address of a byte (8 bits) array of pixel data created by
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      the compression process.
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o compressed_pixels:  The address of a byte (8 bits) array of compressed
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      pixel data.
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
322bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic size_t EncodeImage(Image *image,const size_t bytes_per_line,
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const unsigned char *pixels,unsigned char *compressed_pixels)
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
325bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const unsigned char
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
331bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Runlength encode pixels.
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(pixels != (const unsigned char *) NULL);
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(compressed_pixels != (unsigned char *) NULL);
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  p=pixels;
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  q=compressed_pixels;
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;
350bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
352bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=0; x < (ssize_t) bytes_per_line; x+=i)
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Determine runlength.
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
357bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (i=1; ((x+i) < (ssize_t) bytes_per_line); i++)
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((*(p+i) != *p) || (i == 255))
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *q++=(unsigned char) i;
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *q++=(*p);
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p+=i;
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      End of line.
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q++=0x00;
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q++=0x00;
3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SetImageProgress(image,LoadImageTag,y,image->rows) == MagickFalse)
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    End of bitmap.
3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *q++=0;
3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *q++=0x01;
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((size_t) (q-compressed_pixels));
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s D I B                                                                 %
3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsDIB() returns MagickTrue if the image format type, identified by the
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is DIB.
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsDIB method is:
3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsDIB(const unsigned char *magick,const size_t length)
3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsDIB(const unsigned char *magick,const size_t length)
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 2)
4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\050\000",2) == 0)
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d D I B I m a g e                                                   %
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadDIBImage() reads a Microsoft Windows bitmap image file and
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  returns it.  It allocates the memory necessary for the new Image structure
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  and returns a pointer to the new image.
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadDIBImage method is:
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      image=ReadDIBImage(image_info)
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
441bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickAbsoluteValue(const ssize_t x)
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x < 0)
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(-x);
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(x);
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic inline size_t MagickMax(const size_t x,const size_t y)
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x > y)
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadDIBImage(const ImageInfo *image_info,ExceptionInfo *exception)
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  DIBInfo
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    dib_info;
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4664c08aed51c5899665ade97263692328eea4af106cristy  Quantum
4674c08aed51c5899665ade97263692328eea4af106cristy    index;
4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
469bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4724c08aed51c5899665ade97263692328eea4af106cristy  register Quantum
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
475bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
482ddbc41b8cf3749a1d8fbad1dd5dede5cb62aabefcristy    bytes_per_line,
4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
4864c08aed51c5899665ade97263692328eea4af106cristy    bit,
4874c08aed51c5899665ade97263692328eea4af106cristy    count,
4884c08aed51c5899665ade97263692328eea4af106cristy    y;
4894c08aed51c5899665ade97263692328eea4af106cristy
4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *pixels;
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
5049950d57e1124b73f684fb5946e206994cefda628cristy  image=AcquireImage(image_info,exception);
5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Determine if this a DIB file.
5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(&dib_info,0,sizeof(dib_info));
5153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.size=ReadBlobLSBLong(image);
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (dib_info.size!=40)
5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Microsoft Windows 3.X DIB image file.
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.width=(short) ReadBlobLSBLong(image);
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.height=(short) ReadBlobLSBLong(image);
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.planes=ReadBlobLSBShort(image);
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.bits_per_pixel=ReadBlobLSBShort(image);
5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.compression=ReadBlobLSBLong(image);
5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.image_size=ReadBlobLSBLong(image);
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.x_pixels=ReadBlobLSBLong(image);
5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.y_pixels=ReadBlobLSBLong(image);
5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.number_colors=ReadBlobLSBLong(image);
5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.colors_important=ReadBlobLSBLong(image);
5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((dib_info.compression == BI_BITFIELDS) &&
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((dib_info.bits_per_pixel == 16) || (dib_info.bits_per_pixel == 32)))
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      dib_info.red_mask=ReadBlobLSBLong(image);
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      dib_info.green_mask=ReadBlobLSBLong(image);
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      dib_info.blue_mask=ReadBlobLSBLong(image);
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
538b0a657e13c4aefba39c51292005427b47277869dcristy  image->alpha_trait=dib_info.bits_per_pixel == 32 ? BlendPixelTrait :
539b0a657e13c4aefba39c51292005427b47277869dcristy    UndefinedPixelTrait;
540bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->columns=(size_t) MagickAbsoluteValue(dib_info.width);
541bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->rows=(size_t) MagickAbsoluteValue(dib_info.height);
5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=8;
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((dib_info.number_colors != 0) || (dib_info.bits_per_pixel < 16))
5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
545eaedf06777741da32408da72c1e512975c600c48cristy      size_t
546eaedf06777741da32408da72c1e512975c600c48cristy        one;
547eaedf06777741da32408da72c1e512975c600c48cristy
5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=dib_info.number_colors;
550eaedf06777741da32408da72c1e512975c600c48cristy      one=1;
5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors == 0)
552eaedf06777741da32408da72c1e512975c600c48cristy        image->colors=one << dib_info.bits_per_pixel;
5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->size)
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      RectangleInfo
5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        geometry;
5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MagickStatusType
5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        flags;
5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      flags=ParseAbsoluteGeometry(image_info->size,&geometry);
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (flags & WidthValue)
5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((geometry.width != 0) && (geometry.width < image->columns))
5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->columns=geometry.width;
5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (flags & HeightValue)
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((geometry.height != 0) && (geometry.height < image->rows))
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->rows=geometry.height;
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      size_t
5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length,
5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        packet_size;
5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned char
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *dib_colormap;
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Read DIB raster colormap.
5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
582018f07f7333b25743d0afff892450cebdb905c1acristy      if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      length=(size_t) image->colors;
5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      dib_colormap=(unsigned char *) AcquireQuantumMemory(length,
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        4*sizeof(*dib_colormap));
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (dib_colormap == (unsigned char *) NULL)
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      packet_size=4;
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=ReadBlob(image,packet_size*image->colors,dib_colormap);
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (count != (ssize_t) (packet_size*image->colors))
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p=dib_colormap;
594bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (i=0; i < (ssize_t) image->colors; i++)
5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colormap[i].blue=ScaleCharToQuantum(*p++);
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colormap[i].green=ScaleCharToQuantum(*p++);
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colormap[i].red=ScaleCharToQuantum(*p++);
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (packet_size == 4)
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      dib_colormap=(unsigned char *) RelinquishMagickMemory(dib_colormap);
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image data.
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (dib_info.compression == BI_RLE4)
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    dib_info.bits_per_pixel<<=1;
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bytes_per_line=4*((image->columns*dib_info.bits_per_pixel+31)/32);
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  length=bytes_per_line*image->rows;
6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pixels=(unsigned char *) AcquireQuantumMemory((size_t) image->rows,
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    MagickMax(bytes_per_line,image->columns+256UL)*sizeof(*pixels));
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (pixels == (unsigned char *) NULL)
6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((dib_info.compression == BI_RGB) ||
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (dib_info.compression == BI_BITFIELDS))
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=ReadBlob(image,length,pixels);
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (count != (ssize_t) (length))
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert run-length encoded raster pixels.
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=DecodeImage(image,dib_info.compression ? MagickTrue : MagickFalse,
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        pixels);
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (status == MagickFalse)
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"UnableToRunlengthDecodeImage");
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->units=PixelsPerCentimeterResolution;
6362a11befa48257796843468409d77bb8cfb129cdccristy  image->resolution.x=(double) dib_info.x_pixels/100.0;
6372a11befa48257796843468409d77bb8cfb129cdccristy  image->resolution.y=(double) dib_info.y_pixels/100.0;
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert DIB raster image to pixel packets.
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (dib_info.bits_per_pixel)
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 1:
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert bitmap scanline.
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
648bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=(ssize_t) image->rows-1; y >= 0; y--)
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=pixels+(image->rows-y-1)*bytes_per_line;
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
652acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
654bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < ((ssize_t) image->columns-7); x+=8)
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (bit=0; bit < 8; bit++)
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
6584c08aed51c5899665ade97263692328eea4af106cristy            index=(Quantum) ((*p) & (0x80 >> bit) ? 0x01 : 0x00);
6594c08aed51c5899665ade97263692328eea4af106cristy            SetPixelIndex(image,index,q);
660ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy            q+=GetPixelChannels(image);
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image->columns % 8) != 0)
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
666bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (bit=0; bit < (ssize_t) (image->columns % 8); bit++)
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
6684c08aed51c5899665ade97263692328eea4af106cristy              index=(Quantum) ((*p) & (0x80 >> bit) ? 0x01 : 0x00);
6694c08aed51c5899665ade97263692328eea4af106cristy              SetPixelIndex(image,index,q);
670ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy              q+=GetPixelChannels(image);
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p++;
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->rows);
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
684ea1a8aa04a9fe1500104284407c1cc06d20da699cristy      (void) SyncImage(image,exception);
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 4:
6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert PseudoColor scanline.
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
692bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=(ssize_t) image->rows-1; y >= 0; y--)
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=pixels+(image->rows-y-1)*bytes_per_line;
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
696acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
698bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < ((ssize_t) image->columns-1); x+=2)
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
700c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,(*p >> 4) & 0xf,exception);
7014c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
702ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
703c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,*p & 0xf,exception);
7044c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
706ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image->columns % 2) != 0)
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
710c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy            index=ConstrainColormapIndex(image,(*p >> 4) & 0xf,exception);
7114c08aed51c5899665ade97263692328eea4af106cristy            SetPixelIndex(image,index,q);
712ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy            q+=GetPixelChannels(image);
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p++;
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->rows);
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
725ea1a8aa04a9fe1500104284407c1cc06d20da699cristy      (void) SyncImage(image,exception);
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 8:
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert PseudoColor scanline.
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((dib_info.compression == BI_RLE8) ||
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (dib_info.compression == BI_RLE4))
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        bytes_per_line=image->columns;
736bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=(ssize_t) image->rows-1; y >= 0; y--)
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=pixels+(image->rows-y-1)*bytes_per_line;
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
740acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
742bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
744c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,*p,exception);
7454c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
747ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->rows);
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
759ea1a8aa04a9fe1500104284407c1cc06d20da699cristy      (void) SyncImage(image,exception);
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 16:
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        word;
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert PseudoColor scanline.
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (dib_info.compression == BI_RLE8)
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        bytes_per_line=2*image->columns;
773bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=(ssize_t) image->rows-1; y >= 0; y--)
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=pixels+(image->rows-y-1)*bytes_per_line;
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
777acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
779bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          word=(*p++);
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          word|=(*p++ << 8);
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (dib_info.red_mask == 0)
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
7854c08aed51c5899665ade97263692328eea4af106cristy              SetPixelRed(image,ScaleCharToQuantum(ScaleColor5to8(
7864c08aed51c5899665ade97263692328eea4af106cristy                (unsigned char) ((word >> 10) & 0x1f))),q);
7874c08aed51c5899665ade97263692328eea4af106cristy              SetPixelGreen(image,ScaleCharToQuantum(ScaleColor5to8(
7884c08aed51c5899665ade97263692328eea4af106cristy                (unsigned char) ((word >> 5) & 0x1f))),q);
7894c08aed51c5899665ade97263692328eea4af106cristy              SetPixelBlue(image,ScaleCharToQuantum(ScaleColor5to8(
7904c08aed51c5899665ade97263692328eea4af106cristy                (unsigned char) (word & 0x1f))),q);
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
7944c08aed51c5899665ade97263692328eea4af106cristy              SetPixelRed(image,ScaleCharToQuantum(ScaleColor5to8(
7954c08aed51c5899665ade97263692328eea4af106cristy                (unsigned char) ((word >> 11) & 0x1f))),q);
7964c08aed51c5899665ade97263692328eea4af106cristy              SetPixelGreen(image,ScaleCharToQuantum(ScaleColor6to8(
7974c08aed51c5899665ade97263692328eea4af106cristy                (unsigned char) ((word >> 5) & 0x3f))),q);
7984c08aed51c5899665ade97263692328eea4af106cristy              SetPixelBlue(image,ScaleCharToQuantum(ScaleColor5to8(
7994c08aed51c5899665ade97263692328eea4af106cristy                (unsigned char) (word & 0x1f))),q);
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
801ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->rows);
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 24:
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 32:
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert DirectColor scanline.
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
821bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=(ssize_t) image->rows-1; y >= 0; y--)
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=pixels+(image->rows-y-1)*bytes_per_line;
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
825acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
827bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8294c08aed51c5899665ade97263692328eea4af106cristy          SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
8304c08aed51c5899665ade97263692328eea4af106cristy          SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
8314c08aed51c5899665ade97263692328eea4af106cristy          SetPixelRed(image,ScaleCharToQuantum(*p++),q);
8328a46d827a124555f0c48fb2368ec1bba8e079ab6cristy          if (image->alpha_trait == BlendPixelTrait)
8334c08aed51c5899665ade97263692328eea4af106cristy            SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
834ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->rows);
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default:
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pixels=(unsigned char *) RelinquishMagickMemory(pixels);
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (EOFBlob(image) != MagickFalse)
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->filename);
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (dib_info.height < 0)
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *flipped_image;
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Correct image orientation.
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      flipped_image=FlipImage(image,exception);
864bbfd4cd2bb2c9d59a20738b8cefce4c12307722dcristy      if (flipped_image != (Image *) NULL)
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
866bbfd4cd2bb2c9d59a20738b8cefce4c12307722dcristy          DuplicateBlob(flipped_image,image);
867bbfd4cd2bb2c9d59a20738b8cefce4c12307722dcristy          image=DestroyImage(image);
868bbfd4cd2bb2c9d59a20738b8cefce4c12307722dcristy          image=flipped_image;
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r D I B I m a g e                                           %
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterDIBImage() adds attributes for the DIB image format to
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The attributes include the image format
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterDIBImage method is:
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
895bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterDIBImage(void)
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
898bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterDIBImage(void)
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("DIB");
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadDIBImage;
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteDIBImage;
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsDIB;
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->stealth=MagickTrue;
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "Microsoft Windows 3.X Packed Device-Independent Bitmap");
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("DIB");
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r D I B I m a g e                                       %
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterDIBImage() removes format registrations made by the
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  DIB module from the list of supported formats.
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterDIBImage method is:
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterDIBImage(void)
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterDIBImage(void)
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("DIB");
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e D I B I m a g e                                                 %
9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteDIBImage() writes an image in Microsoft Windows bitmap encoded
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image format.
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteDIBImage method is:
9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9561e178e70fb3c956f9fc1e30c3ba863e882666465cristy%      MagickBooleanType WriteDIBImage(const ImageInfo *image_info,
9571e178e70fb3c956f9fc1e30c3ba863e882666465cristy%        Image *image,ExceptionInfo *exception)
9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9651e178e70fb3c956f9fc1e30c3ba863e882666465cristy%    o exception: return any errors or warnings in this structure.
9661e178e70fb3c956f9fc1e30c3ba863e882666465cristy%
9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9681e178e70fb3c956f9fc1e30c3ba863e882666465cristystatic MagickBooleanType WriteDIBImage(const ImageInfo *image_info,Image *image,
9691e178e70fb3c956f9fc1e30c3ba863e882666465cristy  ExceptionInfo *exception)
9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  DIBInfo
9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    dib_info;
9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9774c08aed51c5899665ade97263692328eea4af106cristy  register const Quantum
9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
980bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
987ddbc41b8cf3749a1d8fbad1dd5dede5cb62aabefcristy  size_t
988ddbc41b8cf3749a1d8fbad1dd5dede5cb62aabefcristy    bytes_per_line;
989ddbc41b8cf3749a1d8fbad1dd5dede5cb62aabefcristy
990ddbc41b8cf3749a1d8fbad1dd5dede5cb62aabefcristy  ssize_t
991ddbc41b8cf3749a1d8fbad1dd5dede5cb62aabefcristy    y;
992ddbc41b8cf3749a1d8fbad1dd5dede5cb62aabefcristy
9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *dib_data,
9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *pixels;
9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open output image file.
9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
10063a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy  assert(exception != (ExceptionInfo *) NULL);
10073a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy  assert(exception->signature == MagickSignature);
10081e178e70fb3c956f9fc1e30c3ba863e882666465cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize DIB raster file header.
10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
10143d9f5ba107b160e1819bb6baeeb3a9f521e9f450cristy  if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
10158d95109eca7aee289423a1ee81c232e309b383aecristy    (void) TransformImageColorspace(image,sRGBColorspace,exception);
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Full color DIB raster.
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      dib_info.number_colors=0;
10228a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      dib_info.bits_per_pixel=(unsigned short) (image->alpha_trait ? 32 : 24);
10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Colormapped DIB raster.
10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      dib_info.bits_per_pixel=8;
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->depth > 8)
10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        dib_info.bits_per_pixel=16;
10321e178e70fb3c956f9fc1e30c3ba863e882666465cristy      if (IsImageMonochrome(image,exception) != MagickFalse)
10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        dib_info.bits_per_pixel=1;
10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      dib_info.number_colors=(dib_info.bits_per_pixel == 16) ? 0 :
10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (1UL << dib_info.bits_per_pixel);
10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bytes_per_line=4*((image->columns*dib_info.bits_per_pixel+31)/32);
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.size=40;
1039bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  dib_info.width=(ssize_t) image->columns;
1040bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  dib_info.height=(ssize_t) image->rows;
10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.planes=1;
1042bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  dib_info.compression=(size_t) (dib_info.bits_per_pixel == 16 ?
10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    BI_BITFIELDS : BI_RGB);
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.image_size=bytes_per_line*image->rows;
10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.x_pixels=75*39;
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.y_pixels=75*39;
10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (image->units)
10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
10493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case UndefinedResolution:
10503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case PixelsPerInchResolution:
10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10522a11befa48257796843468409d77bb8cfb129cdccristy      dib_info.x_pixels=(size_t) (100.0*image->resolution.x/2.54);
10532a11befa48257796843468409d77bb8cfb129cdccristy      dib_info.y_pixels=(size_t) (100.0*image->resolution.y/2.54);
10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case PixelsPerCentimeterResolution:
10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10582a11befa48257796843468409d77bb8cfb129cdccristy      dib_info.x_pixels=(size_t) (100.0*image->resolution.x);
10592a11befa48257796843468409d77bb8cfb129cdccristy      dib_info.y_pixels=(size_t) (100.0*image->resolution.y);
10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
10613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.colors_important=dib_info.number_colors;
10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert MIFF to DIB raster pixels.
10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
10673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pixels=(unsigned char *) AcquireQuantumMemory(dib_info.image_size,
10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*pixels));
10693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (pixels == (unsigned char *) NULL)
10703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(pixels,0,dib_info.image_size);
10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (dib_info.bits_per_pixel)
10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 1:
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register unsigned char
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        bit,
10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        byte;
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert PseudoClass image to a DIB monochrome image.
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
1083bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10851e178e70fb3c956f9fc1e30c3ba863e882666465cristy        p=GetVirtualPixels(image,0,y,image->columns,1,exception);
10864c08aed51c5899665ade97263692328eea4af106cristy        if (p == (const Quantum *) NULL)
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=pixels+(image->rows-y-1)*bytes_per_line;
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        bit=0;
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        byte=0;
1091bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          byte<<=1;
10944c08aed51c5899665ade97263692328eea4af106cristy          byte|=GetPixelIndex(image,p) != 0 ? 0x01 : 0x00;
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          bit++;
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (bit == 8)
10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *q++=byte;
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              bit=0;
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              byte=0;
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
1102ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy           p+=GetPixelChannels(image);
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (bit != 0)
11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             *q++=(unsigned char) (byte << (8-bit));
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             x++;
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
1109bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=(ssize_t) (image->columns+7)/8; x < (ssize_t) bytes_per_line; x++)
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *q++=0x00;
1111cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy        status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1112ddbc41b8cf3749a1d8fbad1dd5dede5cb62aabefcristy          image->rows);
11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 8:
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert PseudoClass packet to DIB pixel.
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
1123bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11251e178e70fb3c956f9fc1e30c3ba863e882666465cristy        p=GetVirtualPixels(image,0,y,image->columns,1,exception);
11264c08aed51c5899665ade97263692328eea4af106cristy        if (p == (const Quantum *) NULL)
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=pixels+(image->rows-y-1)*bytes_per_line;
1129bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
11304c08aed51c5899665ade97263692328eea4af106cristy        {
11314c08aed51c5899665ade97263692328eea4af106cristy          *q++=(unsigned char) GetPixelIndex(image,p);
1132ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          p+=GetPixelChannels(image);
11334c08aed51c5899665ade97263692328eea4af106cristy        }
1134bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for ( ; x < (ssize_t) bytes_per_line; x++)
11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *q++=0x00;
1136cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy        status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1137ddbc41b8cf3749a1d8fbad1dd5dede5cb62aabefcristy          image->rows);
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 16:
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        word;
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert PseudoClass packet to DIB pixel.
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
1150bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11521e178e70fb3c956f9fc1e30c3ba863e882666465cristy        p=GetVirtualPixels(image,0,y,image->columns,1,exception);
11534c08aed51c5899665ade97263692328eea4af106cristy        if (p == (const Quantum *) NULL)
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=pixels+(image->rows-y-1)*bytes_per_line;
1156bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          word=(unsigned short) ((ScaleColor8to5((unsigned char)
11594c08aed51c5899665ade97263692328eea4af106cristy            ScaleQuantumToChar(GetPixelRed(image,p))) << 11) | (ScaleColor8to6(
11604c08aed51c5899665ade97263692328eea4af106cristy            (unsigned char) ScaleQuantumToChar(GetPixelGreen(image,p))) << 5) |
11614c08aed51c5899665ade97263692328eea4af106cristy            (ScaleColor8to5((unsigned char) ScaleQuantumToChar((unsigned char)
11624c08aed51c5899665ade97263692328eea4af106cristy            GetPixelBlue(image,p)) << 0)));
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *q++=(unsigned char)(word & 0xff);
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *q++=(unsigned char)(word >> 8);
1165ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          p+=GetPixelChannels(image);
11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
1167f6fe0a138e6b5879b6c11a27d715412479acf128cristy        for (x=(ssize_t) (2*image->columns); x < (ssize_t) bytes_per_line; x++)
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *q++=0x00;
1169cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy        status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1170ddbc41b8cf3749a1d8fbad1dd5dede5cb62aabefcristy          image->rows);
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 24:
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 32:
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert DirectClass packet to DIB RGB pixel.
11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
1182bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11841e178e70fb3c956f9fc1e30c3ba863e882666465cristy        p=GetVirtualPixels(image,0,y,image->columns,1,exception);
11854c08aed51c5899665ade97263692328eea4af106cristy        if (p == (const Quantum *) NULL)
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=pixels+(image->rows-y-1)*bytes_per_line;
1188bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
11904c08aed51c5899665ade97263692328eea4af106cristy          *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
11914c08aed51c5899665ade97263692328eea4af106cristy          *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
11924c08aed51c5899665ade97263692328eea4af106cristy          *q++=ScaleQuantumToChar(GetPixelRed(image,p));
11938a46d827a124555f0c48fb2368ec1bba8e079ab6cristy          if (image->alpha_trait == BlendPixelTrait)
11944c08aed51c5899665ade97263692328eea4af106cristy            *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
1195ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          p+=GetPixelChannels(image);
11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (dib_info.bits_per_pixel == 24)
1198f6fe0a138e6b5879b6c11a27d715412479acf128cristy          for (x=(ssize_t) (3*image->columns); x < (ssize_t) bytes_per_line; x++)
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *q++=0x00;
1200cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy        status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1201ddbc41b8cf3749a1d8fbad1dd5dede5cb62aabefcristy          image->rows);
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (dib_info.bits_per_pixel == 8)
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->compression != NoCompression)
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        size_t
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length;
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert run-length encoded raster pixels.
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=2UL*(bytes_per_line+2UL)+2UL;
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        dib_data=(unsigned char *) AcquireQuantumMemory(length,
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->rows+2UL)*sizeof(*dib_data));
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (pixels == (unsigned char *) NULL)
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            pixels=(unsigned char *) RelinquishMagickMemory(pixels);
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
1225bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        dib_info.image_size=(size_t) EncodeImage(image,bytes_per_line,
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          pixels,dib_data);
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        pixels=(unsigned char *) RelinquishMagickMemory(pixels);
12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        pixels=dib_data;
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        dib_info.compression = BI_RLE8;
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Write DIB header.
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1234f6fe0a138e6b5879b6c11a27d715412479acf128cristy  (void) WriteBlobLSBLong(image,(unsigned int) dib_info.size);
1235eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobLSBLong(image,dib_info.width);
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobLSBLong(image,(unsigned short) dib_info.height);
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobLSBShort(image,(unsigned short) dib_info.planes);
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobLSBShort(image,dib_info.bits_per_pixel);
1239f6fe0a138e6b5879b6c11a27d715412479acf128cristy  (void) WriteBlobLSBLong(image,(unsigned int) dib_info.compression);
1240f6fe0a138e6b5879b6c11a27d715412479acf128cristy  (void) WriteBlobLSBLong(image,(unsigned int) dib_info.image_size);
1241f6fe0a138e6b5879b6c11a27d715412479acf128cristy  (void) WriteBlobLSBLong(image,(unsigned int) dib_info.x_pixels);
1242f6fe0a138e6b5879b6c11a27d715412479acf128cristy  (void) WriteBlobLSBLong(image,(unsigned int) dib_info.y_pixels);
1243f6fe0a138e6b5879b6c11a27d715412479acf128cristy  (void) WriteBlobLSBLong(image,(unsigned int) dib_info.number_colors);
1244f6fe0a138e6b5879b6c11a27d715412479acf128cristy  (void) WriteBlobLSBLong(image,(unsigned int) dib_info.colors_important);
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (dib_info.bits_per_pixel <= 8)
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *dib_colormap;
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Dump colormap to file.
12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          dib_colormap=(unsigned char *) AcquireQuantumMemory((size_t)
12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (1UL << dib_info.bits_per_pixel),4*sizeof(dib_colormap));
12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (dib_colormap == (unsigned char *) NULL)
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          q=dib_colormap;
1260bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) MagickMin(image->colors,dib_info.number_colors); i++)
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *q++=ScaleQuantumToChar(image->colormap[i].blue);
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *q++=ScaleQuantumToChar(image->colormap[i].green);
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *q++=ScaleQuantumToChar(image->colormap[i].red);
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *q++=(Quantum) 0x0;
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
1267bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for ( ; i < (ssize_t) (1L << dib_info.bits_per_pixel); i++)
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *q++=(Quantum) 0x0;
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *q++=(Quantum) 0x0;
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *q++=(Quantum) 0x0;
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *q++=(Quantum) 0x0;
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,(size_t) (4*(1 << dib_info.bits_per_pixel)),
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            dib_colormap);
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          dib_colormap=(unsigned char *) RelinquishMagickMemory(dib_colormap);
12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((dib_info.bits_per_pixel == 16) &&
12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (dib_info.compression == BI_BITFIELDS))
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobLSBLong(image,0xf800);
12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobLSBLong(image,0x07e0);
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobLSBLong(image,0x001f);
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,dib_info.image_size,pixels);
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pixels=(unsigned char *) RelinquishMagickMemory(pixels);
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1292