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