dib.c revision af8d391906d11f0a1f2bbf4e2adbc4995c852d33
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                                %
16de984cdc3631106b1cbbb8d3972b76a0fc27e8e8cristy%                                   Cristy                                    %
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                 July 1992                                   %
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
20fe676ee3a9cf43404bdc9ba8b27f597b5e4e28f7cristy%  Copyright 1999-2014 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{
15707a3cca00593c795eb8e0427f5bc4c2bcad3f0fbcristy#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__MINGW32__) || defined(__MINGW64__)
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
4660553bd5babdbdf65b95f91ed401c98fead17ab54cristy  MemoryInfo
4670553bd5babdbdf65b95f91ed401c98fead17ab54cristy    *pixel_info;
4680553bd5babdbdf65b95f91ed401c98fead17ab54cristy
4694c08aed51c5899665ade97263692328eea4af106cristy  Quantum
4704c08aed51c5899665ade97263692328eea4af106cristy    index;
4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
472bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4754c08aed51c5899665ade97263692328eea4af106cristy  register Quantum
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
478bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
485ddbc41b8cf3749a1d8fbad1dd5dede5cb62aabefcristy    bytes_per_line,
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
4894c08aed51c5899665ade97263692328eea4af106cristy    bit,
4904c08aed51c5899665ade97263692328eea4af106cristy    count,
4914c08aed51c5899665ade97263692328eea4af106cristy    y;
4924c08aed51c5899665ade97263692328eea4af106cristy
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *pixels;
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
5079950d57e1124b73f684fb5946e206994cefda628cristy  image=AcquireImage(image_info,exception);
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
5153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Determine if this a DIB file.
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(&dib_info,0,sizeof(dib_info));
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.size=ReadBlobLSBLong(image);
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (dib_info.size!=40)
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Microsoft Windows 3.X DIB image file.
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.width=(short) ReadBlobLSBLong(image);
5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.height=(short) ReadBlobLSBLong(image);
5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.planes=ReadBlobLSBShort(image);
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.bits_per_pixel=ReadBlobLSBShort(image);
5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.compression=ReadBlobLSBLong(image);
5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.image_size=ReadBlobLSBLong(image);
5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.x_pixels=ReadBlobLSBLong(image);
5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.y_pixels=ReadBlobLSBLong(image);
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.number_colors=ReadBlobLSBLong(image);
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.colors_important=ReadBlobLSBLong(image);
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((dib_info.compression == BI_BITFIELDS) &&
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((dib_info.bits_per_pixel == 16) || (dib_info.bits_per_pixel == 32)))
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      dib_info.red_mask=ReadBlobLSBLong(image);
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      dib_info.green_mask=ReadBlobLSBLong(image);
5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      dib_info.blue_mask=ReadBlobLSBLong(image);
5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
541b0a657e13c4aefba39c51292005427b47277869dcristy  image->alpha_trait=dib_info.bits_per_pixel == 32 ? BlendPixelTrait :
542b0a657e13c4aefba39c51292005427b47277869dcristy    UndefinedPixelTrait;
543bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->columns=(size_t) MagickAbsoluteValue(dib_info.width);
544bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->rows=(size_t) MagickAbsoluteValue(dib_info.height);
5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=8;
5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((dib_info.number_colors != 0) || (dib_info.bits_per_pixel < 16))
5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
548eaedf06777741da32408da72c1e512975c600c48cristy      size_t
549eaedf06777741da32408da72c1e512975c600c48cristy        one;
550eaedf06777741da32408da72c1e512975c600c48cristy
5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=dib_info.number_colors;
553eaedf06777741da32408da72c1e512975c600c48cristy      one=1;
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors == 0)
555eaedf06777741da32408da72c1e512975c600c48cristy        image->colors=one << dib_info.bits_per_pixel;
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->size)
5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      RectangleInfo
5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        geometry;
5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MagickStatusType
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        flags;
5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      flags=ParseAbsoluteGeometry(image_info->size,&geometry);
5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (flags & WidthValue)
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((geometry.width != 0) && (geometry.width < image->columns))
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->columns=geometry.width;
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (flags & HeightValue)
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((geometry.height != 0) && (geometry.height < image->rows))
5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->rows=geometry.height;
5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      size_t
5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length,
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        packet_size;
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned char
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *dib_colormap;
5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Read DIB raster colormap.
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
585018f07f7333b25743d0afff892450cebdb905c1acristy      if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      length=(size_t) image->colors;
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      dib_colormap=(unsigned char *) AcquireQuantumMemory(length,
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        4*sizeof(*dib_colormap));
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (dib_colormap == (unsigned char *) NULL)
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      packet_size=4;
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=ReadBlob(image,packet_size*image->colors,dib_colormap);
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (count != (ssize_t) (packet_size*image->colors))
5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p=dib_colormap;
597bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (i=0; i < (ssize_t) image->colors; i++)
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colormap[i].blue=ScaleCharToQuantum(*p++);
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colormap[i].green=ScaleCharToQuantum(*p++);
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colormap[i].red=ScaleCharToQuantum(*p++);
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (packet_size == 4)
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      dib_colormap=(unsigned char *) RelinquishMagickMemory(dib_colormap);
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image data.
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (dib_info.compression == BI_RLE4)
6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    dib_info.bits_per_pixel<<=1;
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bytes_per_line=4*((image->columns*dib_info.bits_per_pixel+31)/32);
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  length=bytes_per_line*image->rows;
6140553bd5babdbdf65b95f91ed401c98fead17ab54cristy  pixel_info=AcquireVirtualMemory((size_t) image->rows,MagickMax(
6150553bd5babdbdf65b95f91ed401c98fead17ab54cristy    bytes_per_line,image->columns+256UL)*sizeof(*pixels));
6160553bd5babdbdf65b95f91ed401c98fead17ab54cristy  if (pixel_info == (MemoryInfo *) NULL)
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
6180553bd5babdbdf65b95f91ed401c98fead17ab54cristy  pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((dib_info.compression == BI_RGB) ||
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (dib_info.compression == BI_BITFIELDS))
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=ReadBlob(image,length,pixels);
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (count != (ssize_t) (length))
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert run-length encoded raster pixels.
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=DecodeImage(image,dib_info.compression ? MagickTrue : MagickFalse,
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        pixels);
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (status == MagickFalse)
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"UnableToRunlengthDecodeImage");
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->units=PixelsPerCentimeterResolution;
6402a11befa48257796843468409d77bb8cfb129cdccristy  image->resolution.x=(double) dib_info.x_pixels/100.0;
6412a11befa48257796843468409d77bb8cfb129cdccristy  image->resolution.y=(double) dib_info.y_pixels/100.0;
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert DIB raster image to pixel packets.
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (dib_info.bits_per_pixel)
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 1:
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert bitmap scanline.
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
652bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=(ssize_t) image->rows-1; y >= 0; y--)
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=pixels+(image->rows-y-1)*bytes_per_line;
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
656acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
658bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < ((ssize_t) image->columns-7); x+=8)
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (bit=0; bit < 8; bit++)
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
6624c08aed51c5899665ade97263692328eea4af106cristy            index=(Quantum) ((*p) & (0x80 >> bit) ? 0x01 : 0x00);
6634c08aed51c5899665ade97263692328eea4af106cristy            SetPixelIndex(image,index,q);
664ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy            q+=GetPixelChannels(image);
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image->columns % 8) != 0)
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
670bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (bit=0; bit < (ssize_t) (image->columns % 8); bit++)
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
6724c08aed51c5899665ade97263692328eea4af106cristy              index=(Quantum) ((*p) & (0x80 >> bit) ? 0x01 : 0x00);
6734c08aed51c5899665ade97263692328eea4af106cristy              SetPixelIndex(image,index,q);
674ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy              q+=GetPixelChannels(image);
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p++;
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->rows);
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
688ea1a8aa04a9fe1500104284407c1cc06d20da699cristy      (void) SyncImage(image,exception);
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 4:
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert PseudoColor scanline.
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
696bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=(ssize_t) image->rows-1; y >= 0; y--)
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=pixels+(image->rows-y-1)*bytes_per_line;
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
700acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
702bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < ((ssize_t) image->columns-1); x+=2)
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
704c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,(*p >> 4) & 0xf,exception);
7054c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
706ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
707c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,*p & 0xf,exception);
7084c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
710ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image->columns % 2) != 0)
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
714c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy            index=ConstrainColormapIndex(image,(*p >> 4) & 0xf,exception);
7154c08aed51c5899665ade97263692328eea4af106cristy            SetPixelIndex(image,index,q);
716ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy            q+=GetPixelChannels(image);
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p++;
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->rows);
7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
729ea1a8aa04a9fe1500104284407c1cc06d20da699cristy      (void) SyncImage(image,exception);
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 8:
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert PseudoColor scanline.
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((dib_info.compression == BI_RLE8) ||
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (dib_info.compression == BI_RLE4))
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        bytes_per_line=image->columns;
740bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=(ssize_t) image->rows-1; y >= 0; y--)
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=pixels+(image->rows-y-1)*bytes_per_line;
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
744acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
746bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
748c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,*p,exception);
7494c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
751ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->rows);
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
763ea1a8aa04a9fe1500104284407c1cc06d20da699cristy      (void) SyncImage(image,exception);
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 16:
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        word;
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert PseudoColor scanline.
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (dib_info.compression == BI_RLE8)
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        bytes_per_line=2*image->columns;
777bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=(ssize_t) image->rows-1; y >= 0; y--)
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=pixels+(image->rows-y-1)*bytes_per_line;
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
781acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
783bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          word=(*p++);
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          word|=(*p++ << 8);
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (dib_info.red_mask == 0)
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
7894c08aed51c5899665ade97263692328eea4af106cristy              SetPixelRed(image,ScaleCharToQuantum(ScaleColor5to8(
7904c08aed51c5899665ade97263692328eea4af106cristy                (unsigned char) ((word >> 10) & 0x1f))),q);
7914c08aed51c5899665ade97263692328eea4af106cristy              SetPixelGreen(image,ScaleCharToQuantum(ScaleColor5to8(
7924c08aed51c5899665ade97263692328eea4af106cristy                (unsigned char) ((word >> 5) & 0x1f))),q);
7934c08aed51c5899665ade97263692328eea4af106cristy              SetPixelBlue(image,ScaleCharToQuantum(ScaleColor5to8(
7944c08aed51c5899665ade97263692328eea4af106cristy                (unsigned char) (word & 0x1f))),q);
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
7984c08aed51c5899665ade97263692328eea4af106cristy              SetPixelRed(image,ScaleCharToQuantum(ScaleColor5to8(
7994c08aed51c5899665ade97263692328eea4af106cristy                (unsigned char) ((word >> 11) & 0x1f))),q);
8004c08aed51c5899665ade97263692328eea4af106cristy              SetPixelGreen(image,ScaleCharToQuantum(ScaleColor6to8(
8014c08aed51c5899665ade97263692328eea4af106cristy                (unsigned char) ((word >> 5) & 0x3f))),q);
8024c08aed51c5899665ade97263692328eea4af106cristy              SetPixelBlue(image,ScaleCharToQuantum(ScaleColor5to8(
8034c08aed51c5899665ade97263692328eea4af106cristy                (unsigned char) (word & 0x1f))),q);
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
805ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->rows);
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 24:
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 32:
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert DirectColor scanline.
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
825bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=(ssize_t) image->rows-1; y >= 0; y--)
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=pixels+(image->rows-y-1)*bytes_per_line;
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
829acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
831bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8334c08aed51c5899665ade97263692328eea4af106cristy          SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
8344c08aed51c5899665ade97263692328eea4af106cristy          SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
8354c08aed51c5899665ade97263692328eea4af106cristy          SetPixelRed(image,ScaleCharToQuantum(*p++),q);
8368a46d827a124555f0c48fb2368ec1bba8e079ab6cristy          if (image->alpha_trait == BlendPixelTrait)
8374c08aed51c5899665ade97263692328eea4af106cristy            SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
838ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->rows);
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default:
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8550553bd5babdbdf65b95f91ed401c98fead17ab54cristy  pixel_info=RelinquishVirtualMemory(pixel_info);
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (EOFBlob(image) != MagickFalse)
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->filename);
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (dib_info.height < 0)
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *flipped_image;
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Correct image orientation.
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      flipped_image=FlipImage(image,exception);
868bbfd4cd2bb2c9d59a20738b8cefce4c12307722dcristy      if (flipped_image != (Image *) NULL)
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
870bbfd4cd2bb2c9d59a20738b8cefce4c12307722dcristy          DuplicateBlob(flipped_image,image);
871bbfd4cd2bb2c9d59a20738b8cefce4c12307722dcristy          image=DestroyImage(image);
872bbfd4cd2bb2c9d59a20738b8cefce4c12307722dcristy          image=flipped_image;
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r D I B I m a g e                                           %
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterDIBImage() adds attributes for the DIB image format to
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The attributes include the image format
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterDIBImage method is:
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
899bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterDIBImage(void)
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
902bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterDIBImage(void)
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("DIB");
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadDIBImage;
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteDIBImage;
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsDIB;
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->stealth=MagickTrue;
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "Microsoft Windows 3.X Packed Device-Independent Bitmap");
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("DIB");
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r D I B I m a g e                                       %
9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterDIBImage() removes format registrations made by the
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  DIB module from the list of supported formats.
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterDIBImage method is:
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterDIBImage(void)
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterDIBImage(void)
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("DIB");
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e D I B I m a g e                                                 %
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteDIBImage() writes an image in Microsoft Windows bitmap encoded
9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image format.
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteDIBImage method is:
9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9601e178e70fb3c956f9fc1e30c3ba863e882666465cristy%      MagickBooleanType WriteDIBImage(const ImageInfo *image_info,
9611e178e70fb3c956f9fc1e30c3ba863e882666465cristy%        Image *image,ExceptionInfo *exception)
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
9683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9691e178e70fb3c956f9fc1e30c3ba863e882666465cristy%    o exception: return any errors or warnings in this structure.
9701e178e70fb3c956f9fc1e30c3ba863e882666465cristy%
9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9721e178e70fb3c956f9fc1e30c3ba863e882666465cristystatic MagickBooleanType WriteDIBImage(const ImageInfo *image_info,Image *image,
9731e178e70fb3c956f9fc1e30c3ba863e882666465cristy  ExceptionInfo *exception)
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  DIBInfo
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    dib_info;
9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9814c08aed51c5899665ade97263692328eea4af106cristy  register const Quantum
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
984bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
991ddbc41b8cf3749a1d8fbad1dd5dede5cb62aabefcristy  size_t
992ddbc41b8cf3749a1d8fbad1dd5dede5cb62aabefcristy    bytes_per_line;
993ddbc41b8cf3749a1d8fbad1dd5dede5cb62aabefcristy
994ddbc41b8cf3749a1d8fbad1dd5dede5cb62aabefcristy  ssize_t
995ddbc41b8cf3749a1d8fbad1dd5dede5cb62aabefcristy    y;
996ddbc41b8cf3749a1d8fbad1dd5dede5cb62aabefcristy
9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *dib_data,
9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *pixels;
10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open output image file.
10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
10103a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy  assert(exception != (ExceptionInfo *) NULL);
10113a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy  assert(exception->signature == MagickSignature);
10121e178e70fb3c956f9fc1e30c3ba863e882666465cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize DIB raster file header.
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1018af8d391906d11f0a1f2bbf4e2adbc4995c852d33cristy  (void) TransformImageColorspace(image,sRGBColorspace,exception);
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
10223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Full color DIB raster.
10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      dib_info.number_colors=0;
10258a46d827a124555f0c48fb2368ec1bba8e079ab6cristy      dib_info.bits_per_pixel=(unsigned short) (image->alpha_trait ? 32 : 24);
10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Colormapped DIB raster.
10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      dib_info.bits_per_pixel=8;
10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->depth > 8)
10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        dib_info.bits_per_pixel=16;
10351e178e70fb3c956f9fc1e30c3ba863e882666465cristy      if (IsImageMonochrome(image,exception) != MagickFalse)
10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        dib_info.bits_per_pixel=1;
10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      dib_info.number_colors=(dib_info.bits_per_pixel == 16) ? 0 :
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (1UL << dib_info.bits_per_pixel);
10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bytes_per_line=4*((image->columns*dib_info.bits_per_pixel+31)/32);
10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.size=40;
1042bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  dib_info.width=(ssize_t) image->columns;
1043bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  dib_info.height=(ssize_t) image->rows;
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.planes=1;
1045bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  dib_info.compression=(size_t) (dib_info.bits_per_pixel == 16 ?
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    BI_BITFIELDS : BI_RGB);
10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.image_size=bytes_per_line*image->rows;
10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.x_pixels=75*39;
10493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.y_pixels=75*39;
10503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (image->units)
10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
10523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case UndefinedResolution:
10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case PixelsPerInchResolution:
10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10552a11befa48257796843468409d77bb8cfb129cdccristy      dib_info.x_pixels=(size_t) (100.0*image->resolution.x/2.54);
10562a11befa48257796843468409d77bb8cfb129cdccristy      dib_info.y_pixels=(size_t) (100.0*image->resolution.y/2.54);
10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
10583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case PixelsPerCentimeterResolution:
10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10612a11befa48257796843468409d77bb8cfb129cdccristy      dib_info.x_pixels=(size_t) (100.0*image->resolution.x);
10622a11befa48257796843468409d77bb8cfb129cdccristy      dib_info.y_pixels=(size_t) (100.0*image->resolution.y);
10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dib_info.colors_important=dib_info.number_colors;
10673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert MIFF to DIB raster pixels.
10693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
10703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pixels=(unsigned char *) AcquireQuantumMemory(dib_info.image_size,
10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*pixels));
10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (pixels == (unsigned char *) NULL)
10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(pixels,0,dib_info.image_size);
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (dib_info.bits_per_pixel)
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 1:
10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register unsigned char
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        bit,
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        byte;
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert PseudoClass image to a DIB monochrome image.
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
1086bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10881e178e70fb3c956f9fc1e30c3ba863e882666465cristy        p=GetVirtualPixels(image,0,y,image->columns,1,exception);
10894c08aed51c5899665ade97263692328eea4af106cristy        if (p == (const Quantum *) NULL)
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=pixels+(image->rows-y-1)*bytes_per_line;
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        bit=0;
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        byte=0;
1094bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          byte<<=1;
10974c08aed51c5899665ade97263692328eea4af106cristy          byte|=GetPixelIndex(image,p) != 0 ? 0x01 : 0x00;
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          bit++;
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (bit == 8)
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *q++=byte;
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              bit=0;
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              byte=0;
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
1105ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy           p+=GetPixelChannels(image);
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (bit != 0)
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             *q++=(unsigned char) (byte << (8-bit));
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             x++;
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
1112bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=(ssize_t) (image->columns+7)/8; x < (ssize_t) bytes_per_line; x++)
11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *q++=0x00;
1114cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy        status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1115ddbc41b8cf3749a1d8fbad1dd5dede5cb62aabefcristy          image->rows);
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 8:
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert PseudoClass packet to DIB pixel.
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
1126bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11281e178e70fb3c956f9fc1e30c3ba863e882666465cristy        p=GetVirtualPixels(image,0,y,image->columns,1,exception);
11294c08aed51c5899665ade97263692328eea4af106cristy        if (p == (const Quantum *) NULL)
11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=pixels+(image->rows-y-1)*bytes_per_line;
1132bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
11334c08aed51c5899665ade97263692328eea4af106cristy        {
11344c08aed51c5899665ade97263692328eea4af106cristy          *q++=(unsigned char) GetPixelIndex(image,p);
1135ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          p+=GetPixelChannels(image);
11364c08aed51c5899665ade97263692328eea4af106cristy        }
1137bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for ( ; x < (ssize_t) bytes_per_line; x++)
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *q++=0x00;
1139cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy        status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1140ddbc41b8cf3749a1d8fbad1dd5dede5cb62aabefcristy          image->rows);
11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 16:
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        word;
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert PseudoClass packet to DIB pixel.
11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
1153bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11551e178e70fb3c956f9fc1e30c3ba863e882666465cristy        p=GetVirtualPixels(image,0,y,image->columns,1,exception);
11564c08aed51c5899665ade97263692328eea4af106cristy        if (p == (const Quantum *) NULL)
11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=pixels+(image->rows-y-1)*bytes_per_line;
1159bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          word=(unsigned short) ((ScaleColor8to5((unsigned char)
11624c08aed51c5899665ade97263692328eea4af106cristy            ScaleQuantumToChar(GetPixelRed(image,p))) << 11) | (ScaleColor8to6(
11634c08aed51c5899665ade97263692328eea4af106cristy            (unsigned char) ScaleQuantumToChar(GetPixelGreen(image,p))) << 5) |
11644c08aed51c5899665ade97263692328eea4af106cristy            (ScaleColor8to5((unsigned char) ScaleQuantumToChar((unsigned char)
11654c08aed51c5899665ade97263692328eea4af106cristy            GetPixelBlue(image,p)) << 0)));
11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *q++=(unsigned char)(word & 0xff);
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *q++=(unsigned char)(word >> 8);
1168ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          p+=GetPixelChannels(image);
11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
1170f6fe0a138e6b5879b6c11a27d715412479acf128cristy        for (x=(ssize_t) (2*image->columns); x < (ssize_t) bytes_per_line; x++)
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *q++=0x00;
1172cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy        status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1173ddbc41b8cf3749a1d8fbad1dd5dede5cb62aabefcristy          image->rows);
11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 24:
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 32:
11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert DirectClass packet to DIB RGB pixel.
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
1185bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11871e178e70fb3c956f9fc1e30c3ba863e882666465cristy        p=GetVirtualPixels(image,0,y,image->columns,1,exception);
11884c08aed51c5899665ade97263692328eea4af106cristy        if (p == (const Quantum *) NULL)
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=pixels+(image->rows-y-1)*bytes_per_line;
1191bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
11934c08aed51c5899665ade97263692328eea4af106cristy          *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
11944c08aed51c5899665ade97263692328eea4af106cristy          *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
11954c08aed51c5899665ade97263692328eea4af106cristy          *q++=ScaleQuantumToChar(GetPixelRed(image,p));
11968a46d827a124555f0c48fb2368ec1bba8e079ab6cristy          if (image->alpha_trait == BlendPixelTrait)
11974c08aed51c5899665ade97263692328eea4af106cristy            *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
1198ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          p+=GetPixelChannels(image);
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (dib_info.bits_per_pixel == 24)
1201f6fe0a138e6b5879b6c11a27d715412479acf128cristy          for (x=(ssize_t) (3*image->columns); x < (ssize_t) bytes_per_line; x++)
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *q++=0x00;
1203cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy        status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1204ddbc41b8cf3749a1d8fbad1dd5dede5cb62aabefcristy          image->rows);
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (dib_info.bits_per_pixel == 8)
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->compression != NoCompression)
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        size_t
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length;
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert run-length encoded raster pixels.
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=2UL*(bytes_per_line+2UL)+2UL;
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        dib_data=(unsigned char *) AcquireQuantumMemory(length,
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->rows+2UL)*sizeof(*dib_data));
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (pixels == (unsigned char *) NULL)
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            pixels=(unsigned char *) RelinquishMagickMemory(pixels);
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
1228bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        dib_info.image_size=(size_t) EncodeImage(image,bytes_per_line,
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          pixels,dib_data);
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        pixels=(unsigned char *) RelinquishMagickMemory(pixels);
12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        pixels=dib_data;
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        dib_info.compression = BI_RLE8;
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Write DIB header.
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1237f6fe0a138e6b5879b6c11a27d715412479acf128cristy  (void) WriteBlobLSBLong(image,(unsigned int) dib_info.size);
1238eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobLSBLong(image,dib_info.width);
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobLSBLong(image,(unsigned short) dib_info.height);
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobLSBShort(image,(unsigned short) dib_info.planes);
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobLSBShort(image,dib_info.bits_per_pixel);
1242f6fe0a138e6b5879b6c11a27d715412479acf128cristy  (void) WriteBlobLSBLong(image,(unsigned int) dib_info.compression);
1243f6fe0a138e6b5879b6c11a27d715412479acf128cristy  (void) WriteBlobLSBLong(image,(unsigned int) dib_info.image_size);
1244f6fe0a138e6b5879b6c11a27d715412479acf128cristy  (void) WriteBlobLSBLong(image,(unsigned int) dib_info.x_pixels);
1245f6fe0a138e6b5879b6c11a27d715412479acf128cristy  (void) WriteBlobLSBLong(image,(unsigned int) dib_info.y_pixels);
1246f6fe0a138e6b5879b6c11a27d715412479acf128cristy  (void) WriteBlobLSBLong(image,(unsigned int) dib_info.number_colors);
1247f6fe0a138e6b5879b6c11a27d715412479acf128cristy  (void) WriteBlobLSBLong(image,(unsigned int) dib_info.colors_important);
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (dib_info.bits_per_pixel <= 8)
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *dib_colormap;
12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Dump colormap to file.
12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          dib_colormap=(unsigned char *) AcquireQuantumMemory((size_t)
12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (1UL << dib_info.bits_per_pixel),4*sizeof(dib_colormap));
12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (dib_colormap == (unsigned char *) NULL)
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          q=dib_colormap;
1263bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) MagickMin(image->colors,dib_info.number_colors); i++)
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *q++=ScaleQuantumToChar(image->colormap[i].blue);
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *q++=ScaleQuantumToChar(image->colormap[i].green);
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *q++=ScaleQuantumToChar(image->colormap[i].red);
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *q++=(Quantum) 0x0;
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
1270bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for ( ; i < (ssize_t) (1L << dib_info.bits_per_pixel); i++)
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *q++=(Quantum) 0x0;
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *q++=(Quantum) 0x0;
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *q++=(Quantum) 0x0;
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *q++=(Quantum) 0x0;
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,(size_t) (4*(1 << dib_info.bits_per_pixel)),
12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            dib_colormap);
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          dib_colormap=(unsigned char *) RelinquishMagickMemory(dib_colormap);
12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((dib_info.bits_per_pixel == 16) &&
12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (dib_info.compression == BI_BITFIELDS))
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobLSBLong(image,0xf800);
12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobLSBLong(image,0x07e0);
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobLSBLong(image,0x001f);
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,dib_info.image_size,pixels);
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pixels=(unsigned char *) RelinquishMagickMemory(pixels);
12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1295