icon.c revision 0e8200f78c4cb859725d32da48fcaf6f41f6ca02
13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                        IIIII   CCCC   OOO   N   N                           %
73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                          I    C      O   O  NN  N                           %
83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                          I    C      O   O  N N N                           %
93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                          I    C      O   O  N  NN                           %
103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                        IIIII   CCCC   OOO   N   N                           %
113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                   Read Microsoft Windows Icon Format                        %
143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              Software Design                                %
163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                John Cristy                                  %
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                 July 1992                                   %
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Copyright 1999-2009 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*/
423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/studio.h"
433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/blob.h"
443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/blob-private.h"
453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/cache.h"
463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/colorspace.h"
473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/exception.h"
483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/exception-private.h"
493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/image.h"
503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/image-private.h"
513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/list.h"
523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/log.h"
533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/magick.h"
543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/memory_.h"
553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/monitor.h"
563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/monitor-private.h"
573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/nt-feature.h"
583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/quantize.h"
593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/quantum-private.h"
603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/static.h"
613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/string_.h"
623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/module.h"
633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Define declarations.
663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(__WINDOWS__) || defined(__MINGW32__)
683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define BI_RGB  0
693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define BI_RLE8  1
703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define BI_BITFIELDS  3
713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MaxIcons  1024
733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Typedef declarations.
763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
773ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _IconEntry
783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width,
813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height,
823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    colors,
833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reserved;
843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned short int
863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    planes,
873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bits_per_pixel;
883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    size,
913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} IconEntry;
933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
943ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _IconFile
953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  short
973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reserved,
983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    resource_type,
993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  IconEntry
1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    directory[MaxIcons];
1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} IconFile;
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _IconInfo
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    file_size,
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ba_offset,
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset_bits,
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    size;
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  long
1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width,
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height;
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned short
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    planes,
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bits_per_pixel;
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    compression,
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_size,
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x_pixels,
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y_pixels,
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    number_colors,
1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red_mask,
1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green_mask,
1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue_mask,
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    alpha_mask,
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    colors_important;
1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  long
1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    colorspace;
1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} IconInfo;
1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declaractions.
1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteICONImage(const ImageInfo *,Image *);
1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d I C O N I m a g e                                                 %
1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadICONImage() reads a Microsoft icon image file and returns it.  It
1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
1563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image.
1573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadICONImage method is:
1593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadICONImage(const ImageInfo *image_info,
1613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ExceptionInfo *exception)
1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1703ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadICONImage(const ImageInfo *image_info,
1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ExceptionInfo *exception)
1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  IconFile
1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    icon_file;
1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  IconInfo
1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    icon_info;
1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  long
1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register IndexPacket
1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *indexes;
1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register long
1923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
1933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
1943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
1963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
2003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count,
2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bit,
2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    byte;
2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bytes_per_line,
2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scanline_pad;
2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
2173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(CoderEvent,GetMagickModule(),"%s",image_info->filename);
2193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
2213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
2223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  icon_file.reserved=(short) ReadBlobLSBShort(image);
2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  icon_file.resource_type=(short) ReadBlobLSBShort(image);
2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  icon_file.count=(short) ReadBlobLSBShort(image);
2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((icon_file.reserved != 0) ||
2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((icon_file.resource_type != 1) && (icon_file.resource_type != 2)) ||
2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (icon_file.count > MaxIcons))
2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < icon_file.count; i++)
2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    icon_file.directory[i].width=(unsigned char) ReadBlobByte(image);
2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    icon_file.directory[i].height=(unsigned char) ReadBlobByte(image);
2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    icon_file.directory[i].colors=(unsigned char) ReadBlobByte(image);
2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    icon_file.directory[i].reserved=(unsigned char) ReadBlobByte(image);
2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    icon_file.directory[i].planes=(unsigned short) ReadBlobLSBShort(image);
2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    icon_file.directory[i].bits_per_pixel=(unsigned short)
2433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ReadBlobLSBShort(image);
2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    icon_file.directory[i].size=ReadBlobLSBLong(image);
2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    icon_file.directory[i].offset=ReadBlobLSBLong(image);
2463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < icon_file.count; i++)
2483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
2493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
2503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Verify Icon identifier.
2513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
2523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset=(ssize_t) SeekBlob(image,(MagickOffsetType)
2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      icon_file.directory[i].offset,SEEK_SET);
2543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (offset < 0)
2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    icon_info.size=ReadBlobLSBLong(image);
2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    icon_info.width=(unsigned char) ReadBlobLSBLong(image);
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    icon_info.height=(unsigned char) ReadBlobLSBLong(image)/2;
2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((icon_file.directory[i].width == 0) &&
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (icon_file.directory[i].height == 0))
2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *icon_image;
2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ImageInfo
2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *read_info;
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        size_t
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length;
2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *png;
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Icon image encoded as a compressed PNG image.
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=icon_file.directory[i].size;
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png=(unsigned char *) AcquireQuantumMemory(length+12,sizeof(*png));
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (png == (unsigned char *) NULL)
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CopyMagickMemory(png,"\211PNG\r\n\032\n\000\000\000\015",12);
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=ReadBlob(image,length,png+12);
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count != (ssize_t) length)
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png=(unsigned char *) RelinquishMagickMemory(png);
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "InsufficientImageDataInFile");
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_info=CloneImageInfo(image_info);
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CopyMagickString(read_info->magick,"PNG",MaxTextExtent);
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_image=BlobToImage(read_info,png,length+12,exception);
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_info=DestroyImageInfo(read_info);
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png=(unsigned char *) RelinquishMagickMemory(png);
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (icon_image == (Image *) NULL)
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=DestroyImageList(image);
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            return((Image *) NULL);
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        DestroyBlob(icon_image);
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_image->blob=ReferenceBlob(image->blob);
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ReplaceImageInList(&image,icon_image);
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.planes=ReadBlobLSBShort(image);
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.bits_per_pixel=ReadBlobLSBShort(image);
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (icon_info.bits_per_pixel > 32)
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.compression=ReadBlobLSBLong(image);
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.image_size=ReadBlobLSBLong(image);
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.x_pixels=ReadBlobLSBLong(image);
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.y_pixels=ReadBlobLSBLong(image);
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.number_colors=ReadBlobLSBLong(image);
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.colors_important=ReadBlobLSBLong(image);
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->matte=MagickTrue;
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->columns=(unsigned long) icon_file.directory[i].width;
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->rows=(unsigned long) icon_file.directory[i].height;
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->depth=8;
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->debug != MagickFalse)
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              " scene    = %ld",i);
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "   size   = %ld",icon_info.size);
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "   width  = %d",icon_file.directory[i].width);
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "   height = %d",icon_file.directory[i].height);
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "   colors = %ld",icon_info.number_colors);
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "   planes = %d",icon_info.planes);
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "   bpp    = %d",icon_info.bits_per_pixel);
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((icon_info.number_colors != 0) || (icon_info.bits_per_pixel <= 16))
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->storage_class=PseudoClass;
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->colors=icon_info.number_colors;
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->colors == 0)
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colors=1 << icon_info.bits_per_pixel;
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->storage_class == PseudoClass)
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          register long
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *icon_colormap;
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned long
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Read Icon raster colormap.
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          number_colors=1UL << icon_info.bits_per_pixel;
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (AcquireImageColormap(image,number_colors) == MagickFalse)
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          icon_colormap=(unsigned char *) AcquireQuantumMemory((size_t)
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colors,4UL*sizeof(*icon_colormap));
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (icon_colormap == (unsigned char *) NULL)
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          count=ReadBlob(image,(size_t) (4*image->colors),icon_colormap);
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (count != (ssize_t) (4*image->colors))
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "InsufficientImageDataInFile");
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=icon_colormap;
3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (i=0; i < (long) image->colors; i++)
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) ScaleCharToQuantum(*p++);
3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) ScaleCharToQuantum(*p++);
3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) ScaleCharToQuantum(*p++);
3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p++;
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          icon_colormap=(unsigned char *) RelinquishMagickMemory(icon_colormap);
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert Icon raster image to pixel packets.
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping != MagickFalse) &&
3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image_info->number_scenes != 0))
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->scene >= (image_info->scene+image_info->number_scenes-1))
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        bytes_per_line=(((image->columns*icon_info.bits_per_pixel)+31) &
3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ~31) >> 3;
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scanline_pad=((((image->columns*icon_info.bits_per_pixel)+31) & ~31)-
3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->columns*icon_info.bits_per_pixel)) >> 3;
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        switch (icon_info.bits_per_pixel)
3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 1:
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Convert bitmap scanline.
3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (y=(long) image->rows-1; y >= 0; y--)
3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (q == (PixelPacket *) NULL)
4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              indexes=GetAuthenticIndexQueue(image);
4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=0; x < (long) (image->columns-7); x+=8)
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                byte=(unsigned long) ReadBlobByte(image);
4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (bit=0; bit < 8; bit++)
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  indexes[x+bit]=(IndexPacket)
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ((byte & (0x80 >> bit)) != 0 ? 0x01 : 0x00);
4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if ((image->columns % 8) != 0)
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  byte=(unsigned long) ReadBlobByte(image);
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (bit=0; bit < (image->columns % 8); bit++)
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    indexes[x+bit]=(IndexPacket)
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ((byte & (0x80 >> bit)) != 0 ? 0x01 : 0x00);
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=0; x < (long) scanline_pad; x++)
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ReadBlobByte(image);
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (SyncAuthenticPixels(image,exception) == MagickFalse)
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->previous == (Image *) NULL)
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows);
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (status == MagickFalse)
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 4:
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read 4-bit Icon scanline.
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (y=(long) image->rows-1; y >= 0; y--)
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (q == (PixelPacket *) NULL)
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              indexes=GetAuthenticIndexQueue(image);
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=0; x < ((long) image->columns-1); x+=2)
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                byte=(unsigned long) ReadBlobByte(image);
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                indexes[x]=(IndexPacket) ((byte >> 4) & 0xf);
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                indexes[x+1]=(IndexPacket) ((byte) & 0xf);
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if ((image->columns % 2) != 0)
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  byte=(unsigned long) ReadBlobByte(image);
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  indexes[x]=(IndexPacket) ((byte >> 4) & 0xf);
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=0; x < (long) scanline_pad; x++)
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ReadBlobByte(image);
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (SyncAuthenticPixels(image,exception) == MagickFalse)
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->previous == (Image *) NULL)
4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows);
4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (status == MagickFalse)
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
4693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Convert PseudoColor scanline.
4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (y=(long) image->rows-1; y >= 0; y--)
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (q == (PixelPacket *) NULL)
4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              indexes=GetAuthenticIndexQueue(image);
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=0; x < (long) image->columns; x++)
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                byte=(unsigned long) ReadBlobByte(image);
4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                indexes[x]=(IndexPacket) byte;
4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=0; x < (long) scanline_pad; x++)
4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ReadBlobByte(image);
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (SyncAuthenticPixels(image,exception) == MagickFalse)
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->previous == (Image *) NULL)
4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows);
4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (status == MagickFalse)
4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Convert PseudoColor scanline.
5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (y=(long) image->rows-1; y >= 0; y--)
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (q == (PixelPacket *) NULL)
5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              indexes=GetAuthenticIndexQueue(image);
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=0; x < (long) image->columns; x++)
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                byte=(unsigned long) ReadBlobByte(image);
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                byte|=(unsigned long) (ReadBlobByte(image) << 8);
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                indexes[x]=(IndexPacket) byte;
5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=0; x < (long) scanline_pad; x++)
5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ReadBlobByte(image);
5153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (SyncAuthenticPixels(image,exception) == MagickFalse)
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->previous == (Image *) NULL)
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows);
5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (status == MagickFalse)
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 24:
5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 32:
5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Convert DirectColor scanline.
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (y=(long) image->rows-1; y >= 0; y--)
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (q == (PixelPacket *) NULL)
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=0; x < (long) image->columns; x++)
5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->blue=ScaleCharToQuantum((unsigned char) ReadBlobByte(image));
5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->green=ScaleCharToQuantum((unsigned char)
5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ReadBlobByte(image));
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->red=ScaleCharToQuantum((unsigned char) ReadBlobByte(image));
5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (icon_info.bits_per_pixel == 32)
5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-ScaleCharToQuantum(
5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (unsigned char) ReadBlobByte(image)));
5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (icon_info.bits_per_pixel == 24)
5503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (x=0; x < (long) scanline_pad; x++)
5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ReadBlobByte(image);
5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (SyncAuthenticPixels(image,exception) == MagickFalse)
5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->previous == (Image *) NULL)
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  status=SetImageProgress(image,LoadImageTag,image->rows-y-1,
5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows);
5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (status == MagickFalse)
5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,"ImproperImageHeader");
5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) SyncImage(image);
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (icon_info.bits_per_pixel != 32)
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read the ICON alpha mask.
5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->storage_class=DirectClass;
5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (y=(long) image->rows-1; y >= 0; y--)
5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (q == (PixelPacket *) NULL)
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=0; x < ((long) image->columns-7); x+=8)
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                byte=(unsigned long) ReadBlobByte(image);
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (bit=0; bit < 8; bit++)
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q[x+bit].opacity=(Quantum) (((byte & (0x80 >> bit)) != 0) ?
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    TransparentOpacity : OpaqueOpacity);
5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if ((image->columns % 8) != 0)
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  byte=(unsigned long) ReadBlobByte(image);
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (bit=0; bit < (image->columns % 8); bit++)
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q[x+bit].opacity=(Quantum) (((byte & (0x80 >> bit)) != 0) ?
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      TransparentOpacity : OpaqueOpacity);
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
5930e8200f78c4cb859725d32da48fcaf6f41f6ca02cristy              if ((image->columns % 32) != 0)
5940e8200f78c4cb859725d32da48fcaf6f41f6ca02cristy                for (x=0; x < (long) ((32-(image->columns % 32))/8); x++)
5950e8200f78c4cb859725d32da48fcaf6f41f6ca02cristy                  (void) ReadBlobByte(image);
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (SyncAuthenticPixels(image,exception) == MagickFalse)
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (EOFBlob(image) != MagickFalse)
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowFileException(exception,CorruptImageError,
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "UnexpectedEndOfFile",image->filename);
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Proceed to next image.
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->number_scenes != 0)
6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i < (long) (icon_file.count-1))
6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Allocate next image structure.
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        AcquireNextImage(image_info,image);
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(image) == (Image *) NULL)
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=DestroyImageList(image);
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            return((Image *) NULL);
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=SyncNextImageInList(image);
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r I C O N I m a g e                                         %
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterICONImage() adds attributes for the Icon image format to
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The attributes include the image format
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterICONImage method is:
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      unsigned long RegisterICONImage(void)
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport unsigned long RegisterICONImage(void)
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("CUR");
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadICONImage;
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteICONImage;
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Microsoft icon");
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("CUR");
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("ICO");
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadICONImage;
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteICONImage;
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickTrue;
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Microsoft icon");
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("ICON");
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("ICON");
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadICONImage;
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteICONImage;
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Microsoft icon");
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("ICON");
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r I C O N I m a g e                                     %
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterICONImage() removes format registrations made by the
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ICON module from the list of supported formats.
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterICONImage method is:
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterICONImage(void)
7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterICONImage(void)
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("CUR");
7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("ICO");
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("ICON");
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e I C O N I m a g e                                               %
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteICONImage() writes an image in Microsoft Windows bitmap encoded
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image format, version 3 for Windows or (if the image has a matte channel)
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  version 4.
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteICONImage method is:
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteICONImage(const ImageInfo *image_info,
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        Image *image)
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteICONImage(const ImageInfo *image_info,
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *image)
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  IconFile
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    icon_file;
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  IconInfo
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    icon_info;
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next;
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  long
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset,
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const IndexPacket
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *indexes;
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register long
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bit,
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    byte,
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *pixels;
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bytes_per_line,
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scanline_pad;
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open output image file.
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"%s",image->filename);
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  next=image;
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((image->columns > 256L) || (image->rows > 256L))
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ImageError,"WidthOrHeightExceedsLimit");
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene++;
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    next=SyncNextImageInList(next);
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while ((next != (Image *) NULL) && (image_info->adjoin != MagickFalse));
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Dump out a ICON header template to be properly initialized later.
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobLSBShort(image,0);
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobLSBShort(image,1);
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobLSBShort(image,(unsigned char) scene);
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(&icon_file,0,sizeof(icon_file));
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(&icon_info,0,sizeof(icon_info));
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  next=image;
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobByte(image,icon_file.directory[scene].width);
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobByte(image,icon_file.directory[scene].height);
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobByte(image,icon_file.directory[scene].colors);
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobByte(image,icon_file.directory[scene].reserved);
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobLSBShort(image,icon_file.directory[scene].planes);
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobLSBShort(image,icon_file.directory[scene].bits_per_pixel);
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobLSBLong(image,icon_file.directory[scene].size);
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobLSBLong(image,icon_file.directory[scene].offset);
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene++;
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    next=SyncNextImageInList(next);
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while ((next != (Image *) NULL) && (image_info->adjoin != MagickFalse));
8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  next=image;
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((next->columns == 256) && (next->rows == 256))
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *write_image;
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ImageInfo
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *write_info;
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        size_t
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length;
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *png;
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Icon image encoded as a compressed PNG image.
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        write_image=CloneImage(next,0,0,MagickTrue,&image->exception);
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (write_image == (Image *) NULL)
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        write_info=CloneImageInfo(image_info);
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CopyMagickString(write_info->filename,"PNG:",MaxTextExtent);
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png=(unsigned char *) ImageToBlob(write_info,write_image,&length,
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          &image->exception);
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        write_image=DestroyImage(write_image);
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        write_info=DestroyImageInfo(write_info);
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (png == (unsigned char *) NULL)
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_file.directory[scene].width=0;
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_file.directory[scene].height=0;
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_file.directory[scene].colors=0;
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_file.directory[scene].reserved=0;
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_file.directory[scene].planes=1;
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_file.directory[scene].bits_per_pixel=32;
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_file.directory[scene].size=(unsigned long) length;
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_file.directory[scene].offset=(unsigned long) TellBlob(image);
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(image,(size_t) length,png);
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png=(unsigned char *) RelinquishMagickMemory(png);
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Initialize ICON raster file header.
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next->colorspace != RGBColorspace)
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) TransformImageColorspace(next,RGBColorspace);
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.file_size=14+12+28;
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.offset_bits=icon_info.file_size;
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.compression=BI_RGB;
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((next->storage_class != DirectClass) && (next->colors > 256))
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageStorageClass(next,DirectClass);
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next->storage_class == DirectClass)
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Full color ICON raster.
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            icon_info.number_colors=0;
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            icon_info.bits_per_pixel=32;
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            icon_info.compression=(unsigned long) BI_RGB;
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Colormapped ICON raster.
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            icon_info.bits_per_pixel=8;
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next->colors <= 256)
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              icon_info.bits_per_pixel=8;
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next->colors <= 16)
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              icon_info.bits_per_pixel=4;
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next->colors <= 2)
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              icon_info.bits_per_pixel=1;
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            icon_info.number_colors=1 << icon_info.bits_per_pixel;
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (icon_info.number_colors < next->colors)
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageStorageClass(next,DirectClass);
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                icon_info.number_colors=0;
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                icon_info.bits_per_pixel=(unsigned short) 24;
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                icon_info.compression=(unsigned long) BI_RGB;
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                icon_info.file_size+=3*(1UL << icon_info.bits_per_pixel);
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                icon_info.offset_bits+=3*(1UL << icon_info.bits_per_pixel);
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                icon_info.file_size+=(1UL << icon_info.bits_per_pixel);
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                icon_info.offset_bits+=(1UL << icon_info.bits_per_pixel);
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        bytes_per_line=(((next->columns*icon_info.bits_per_pixel)+31) &
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ~31) >> 3;
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.ba_offset=0;
9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.width=(long) next->columns;
9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.height=(long) next->rows;
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.planes=1;
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.image_size=bytes_per_line*next->rows;
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.size=40;
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.size+=(4*icon_info.number_colors);
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.size+=icon_info.image_size;
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.size+=(((icon_info.width+31) & ~31) >> 3)*icon_info.height;
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.file_size+=icon_info.image_size;
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.x_pixels=0;
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.y_pixels=0;
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        switch (next->units)
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case UndefinedResolution:
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case PixelsPerInchResolution:
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            icon_info.x_pixels=(unsigned long) (100.0*next->x_resolution/2.54);
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            icon_info.y_pixels=(unsigned long) (100.0*next->y_resolution/2.54);
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case PixelsPerCentimeterResolution:
9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            icon_info.x_pixels=(unsigned long) (100.0*next->x_resolution);
9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            icon_info.y_pixels=(unsigned long) (100.0*next->y_resolution);
9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_info.colors_important=icon_info.number_colors;
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert MIFF to ICON raster pixels.
9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        pixels=(unsigned char *) AcquireQuantumMemory((size_t)
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          icon_info.image_size,sizeof(*pixels));
9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (pixels == (unsigned char *) NULL)
9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ResetMagickMemory(pixels,0,(size_t) icon_info.image_size);
9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        switch (icon_info.bits_per_pixel)
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 1:
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned long
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              bit,
9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              byte;
9683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Convert PseudoClass image to a ICON monochrome image.
9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (y=0; y < (long) next->rows; y++)
9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p=GetVirtualPixels(next,0,y,next->columns,1,&next->exception);
9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p == (const PixelPacket *) NULL)
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              indexes=GetVirtualIndexQueue(next);
9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              q=pixels+(next->rows-y-1)*bytes_per_line;
9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              bit=0;
9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              byte=0;
9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=0; x < (long) next->columns; x++)
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                byte<<=1;
9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                byte|=indexes[x] != 0 ? 0x01 : 0x00;
9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                bit++;
9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (bit == 8)
9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *q++=(unsigned char) byte;
9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    bit=0;
9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    byte=0;
9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (bit != 0)
9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *q++=(unsigned char) (byte << (8-bit));
9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (next->previous == (Image *) NULL)
9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  status=SetImageProgress(next,SaveImageTag,y,next->rows);
9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (status == MagickFalse)
9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 4:
10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned long
10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              nibble,
10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              byte;
10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Convert PseudoClass image to a ICON monochrome image.
10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (y=0; y < (long) next->rows; y++)
10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p=GetVirtualPixels(next,0,y,next->columns,1,&next->exception);
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p == (const PixelPacket *) NULL)
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              indexes=GetVirtualIndexQueue(next);
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              q=pixels+(next->rows-y-1)*bytes_per_line;
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              nibble=0;
10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              byte=0;
10223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=0; x < (long) next->columns; x++)
10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                byte<<=4;
10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                byte|=((unsigned long) indexes[x] & 0x0f);
10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                nibble++;
10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (nibble == 2)
10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *q++=(unsigned char) byte;
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    nibble=0;
10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    byte=0;
10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (nibble != 0)
10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *q++=(unsigned char) (byte << 4);
10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (next->previous == (Image *) NULL)
10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  status=SetImageProgress(next,SaveImageTag,y,next->rows);
10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (status == MagickFalse)
10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Convert PseudoClass packet to ICON pixel.
10493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
10503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (y=0; y < (long) next->rows; y++)
10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
10523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p=GetVirtualPixels(next,0,y,next->columns,1,&next->exception);
10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p == (const PixelPacket *) NULL)
10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              indexes=GetVirtualIndexQueue(next);
10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              q=pixels+(next->rows-y-1)*bytes_per_line;
10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=0; x < (long) next->columns; x++)
10583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *q++=(unsigned char) indexes[x];
10593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (next->previous == (Image *) NULL)
10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
10613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  status=SetImageProgress(next,SaveImageTag,y,next->rows);
10623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (status == MagickFalse)
10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
10673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 24:
10693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 32:
10703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Convert DirectClass packet to ICON BGR888 or BGRA8888 pixel.
10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (y=0; y < (long) next->rows; y++)
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p=GetVirtualPixels(next,0,y,next->columns,1,&next->exception);
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p == (const PixelPacket *) NULL)
10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              q=pixels+(next->rows-y-1)*bytes_per_line;
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=0; x < (long) next->columns; x++)
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *q++=ScaleQuantumToChar(p->blue);
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *q++=ScaleQuantumToChar(p->green);
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *q++=ScaleQuantumToChar(p->red);
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next->matte == MagickFalse)
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q++=ScaleQuantumToChar(QuantumRange);
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q++=ScaleQuantumToChar(QuantumRange-p->opacity);
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (icon_info.bits_per_pixel == 24)
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (x=3L*(long) next->columns; x < (long) bytes_per_line; x++)
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q++=0x00;
10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (next->previous == (Image *) NULL)
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  status=SetImageProgress(next,SaveImageTag,y,next->rows);
10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (status == MagickFalse)
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Write 40-byte version 3+ bitmap header.
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_file.directory[scene].width=(unsigned char) icon_info.width;
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_file.directory[scene].height=(unsigned char) icon_info.height;
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_file.directory[scene].colors=(unsigned char)
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          icon_info.number_colors;
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_file.directory[scene].reserved=0;
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_file.directory[scene].planes=icon_info.planes;
11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_file.directory[scene].bits_per_pixel=icon_info.bits_per_pixel;
11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_file.directory[scene].size=icon_info.size;
11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        icon_file.directory[scene].offset=(unsigned long) TellBlob(image);
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobLSBLong(image,(unsigned long) 40);
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobLSBLong(image,(unsigned long) icon_info.width);
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobLSBLong(image,(unsigned long) icon_info.height*2);
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobLSBShort(image,icon_info.planes);
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobLSBShort(image,icon_info.bits_per_pixel);
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobLSBLong(image,icon_info.compression);
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobLSBLong(image,icon_info.image_size);
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobLSBLong(image,icon_info.x_pixels);
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobLSBLong(image,icon_info.y_pixels);
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobLSBLong(image,icon_info.number_colors);
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlobLSBLong(image,icon_info.colors_important);
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next->storage_class == PseudoClass)
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned char
11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *icon_colormap;
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Dump colormap to file.
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            icon_colormap=(unsigned char *) AcquireQuantumMemory((size_t)
11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (1UL << icon_info.bits_per_pixel),4UL*sizeof(*icon_colormap));
11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (icon_colormap == (unsigned char *) NULL)
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            q=icon_colormap;
11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < (long) next->colors; i++)
11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *q++=ScaleQuantumToChar(next->colormap[i].blue);
11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *q++=ScaleQuantumToChar(next->colormap[i].green);
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *q++=ScaleQuantumToChar(next->colormap[i].red);
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *q++=(unsigned char) 0x0;
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < (long) (1UL << icon_info.bits_per_pixel); i++)
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *q++=(unsigned char) 0x00;
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *q++=(unsigned char) 0x00;
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *q++=(unsigned char) 0x00;
11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *q++=(unsigned char) 0x00;
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(image,(size_t) (4UL*(1UL <<
11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              icon_info.bits_per_pixel)),icon_colormap);
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            icon_colormap=(unsigned char *) RelinquishMagickMemory(
11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              icon_colormap);
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(image,(size_t) icon_info.image_size,pixels);
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        pixels=(unsigned char *) RelinquishMagickMemory(pixels);
11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Write matte mask.
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scanline_pad=(((next->columns+31) & ~31)-next->columns) >> 3;
11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (y=((long) next->rows - 1); y >= 0; y--)
11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(next,0,y,next->columns,1,&next->exception);
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          bit=0;
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          byte=0;
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (x=0; x < (long) next->columns; x++)
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            byte<<=1;
11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next->matte == MagickTrue) &&
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p->opacity == (Quantum) TransparentOpacity))
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              byte|=0x01;
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            bit++;
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (bit == 8)
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobByte(image,(unsigned char) byte);
11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                bit=0;
11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                byte=0;
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
11853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p++;
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (bit != 0)
11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobByte(image,(unsigned char) (byte << (8-bit)));
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (i=0; i < (long) scanline_pad; i++)
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobByte(image,(unsigned char) 0);
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(next) == (Image *) NULL)
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    next=SyncNextImageInList(next);
11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(next,SaveImagesTag,scene++,
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(next));
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while ((next != (Image *) NULL) && (image_info->adjoin != MagickFalse));
12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  offset=SeekBlob(image,0,SEEK_SET);
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobLSBShort(image,0);
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobLSBShort(image,1);
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobLSBShort(image,(unsigned short) (scene+1));
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  next=image;
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobByte(image,icon_file.directory[scene].width);
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobByte(image,icon_file.directory[scene].height);
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobByte(image,icon_file.directory[scene].colors);
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobByte(image,icon_file.directory[scene].reserved);
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobLSBShort(image,icon_file.directory[scene].planes);
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobLSBShort(image,icon_file.directory[scene].bits_per_pixel);
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobLSBLong(image,icon_file.directory[scene].size);
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobLSBLong(image,icon_file.directory[scene].offset);
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene++;
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    next=SyncNextImageInList(next);
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while ((next != (Image *) NULL) && (image_info->adjoin != MagickFalse));
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1223