13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              CCC  U   U  TTTTT                              %
63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                             C     U   U    T                                %
73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                             C     U   U    T                                %
83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                             C     U   U    T                                %
93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              CCC   UUU     T                                %
103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                         Read DR Halo Image Format                           %
133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              Software Design                                %
153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              Jaroslav Fojtik                                %
163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                 June 2000                                   %
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Permission is hereby granted, free of charge, to any person obtaining a    %
203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  copy of this software and associated documentation files ("ImageMagick"),  %
213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  to deal in ImageMagick without restriction, including without limitation   %
223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the rights to use, copy, modify, merge, publish, distribute, sublicense,   %
233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  and/or sell copies of ImageMagick, and to permit persons to whom the       %
243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ImageMagick is furnished to do so, subject to the following conditions:    %
253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The above copyright notice and this permission notice shall be included in %
273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  all copies or substantial portions of ImageMagick.                         %
283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The software is provided "as is", without warranty of any kind, express or %
303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  implied, including but not limited to the warranties of merchantability,   %
313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  fitness for a particular purpose and noninfringement.  In no event shall   %
323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ImageMagick Studio be liable for any claim, damages or other liability,    %
333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether in an action of contract, tort or otherwise, arising from, out of  %
343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or in connection with ImageMagick or the use or other dealings in          %
353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ImageMagick.                                                               %
363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Except as contained in this notice, the name of the ImageMagick Studio     %
383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  shall not be used in advertising or otherwise to promote the sale, use or  %
393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  other dealings in ImageMagick without prior written authorization from the %
403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ImageMagick Studio.                                                        %
413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Include declarations.
493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
504c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/studio.h"
514c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/attribute.h"
524c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob.h"
534c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob-private.h"
544c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/cache.h"
554c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color.h"
564c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color-private.h"
574c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/colormap.h"
584c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/colormap-private.h"
594c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception.h"
604c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception-private.h"
614c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image.h"
624c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image-private.h"
634c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/list.h"
644c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/magick.h"
654c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/memory_.h"
664c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/pixel-accessor.h"
674c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/quantum-private.h"
684c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/static.h"
694c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string_.h"
704c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/module.h"
714c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/utility.h"
7218c6c27bc513a8c73a5bc4a2c157afb19c3e24b9cristy#include "MagickCore/utility-private.h"
733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
743ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct
753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned Width;
773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned Height;
783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned Reserved;
793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} CUTHeader;
803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
813ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct
823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char FileId[2];
843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned Version;
853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned Size;
863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char FileType;
873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char SubType;
883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned BoardID;
893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned GraphicsMode;
903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned MaxIndex;
913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned MaxRed;
923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned MaxGreen;
933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned MaxBlue;
943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char PaletteId[20];
953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} CUTPalHeader;
963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristystatic void InsertRow(Image *image,ssize_t depth,unsigned char *p,ssize_t y,
99c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy  ExceptionInfo *exception)
1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
101bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t bit; ssize_t x;
1024c08aed51c5899665ade97263692328eea4af106cristy  register Quantum *q;
1034c08aed51c5899665ade97263692328eea4af106cristy  Quantum index;
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1054c08aed51c5899665ade97263692328eea4af106cristy  index=0;
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (depth)
1074e82e51d7ebce7b4ef0f808d906124dd6f812248cristy  {
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 1:  /* Convert bitmap scanline. */
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
111acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
113bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < ((ssize_t) image->columns-7); x+=8)
1144e82e51d7ebce7b4ef0f808d906124dd6f812248cristy        {
1154e82e51d7ebce7b4ef0f808d906124dd6f812248cristy          for (bit=0; bit < 8; bit++)
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
1174c08aed51c5899665ade97263692328eea4af106cristy            index=(Quantum) ((((*p) & (0x80 >> bit)) != 0) ? 0x01 : 0x00);
1184c08aed51c5899665ade97263692328eea4af106cristy            SetPixelIndex(image,index,q);
119ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy            q+=GetPixelChannels(image);
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
1214e82e51d7ebce7b4ef0f808d906124dd6f812248cristy          p++;
1224e82e51d7ebce7b4ef0f808d906124dd6f812248cristy        }
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image->columns % 8) != 0)
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (bit=0; bit < (image->columns % 8); bit++)
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
1274c08aed51c5899665ade97263692328eea4af106cristy                index=(Quantum) ((((*p) & (0x80 >> bit)) != 0) ? 0x01 : 0x00);
1284c08aed51c5899665ade97263692328eea4af106cristy                SetPixelIndex(image,index,q);
129ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                q+=GetPixelChannels(image);
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p++;
1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
133ccad00b02d1242dc1c039f9979337e00f69212e8dirk        (void) SyncAuthenticPixels(image,exception);
1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 2:  /* Convert PseudoColor scanline. */
1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
139acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
141bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < ((ssize_t) image->columns-1); x+=2)
1424c08aed51c5899665ade97263692328eea4af106cristy        {
143c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,(*p >> 6) & 0x3,exception);
1444c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
145ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
146c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,(*p >> 4) & 0x3,exception);
1474c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
148ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
149c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,(*p >> 2) & 0x3,exception);
1504c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
151ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
152c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,(*p) & 0x3,exception);
1534c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
154ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
1554c08aed51c5899665ade97263692328eea4af106cristy          p++;
1564c08aed51c5899665ade97263692328eea4af106cristy        }
1573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image->columns % 4) != 0)
1583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
159c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy            index=ConstrainColormapIndex(image,(*p >> 6) & 0x3,exception);
1604c08aed51c5899665ade97263692328eea4af106cristy            SetPixelIndex(image,index,q);
161ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy            q+=GetPixelChannels(image);
1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 4) >= 1)
1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
165c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy                index=ConstrainColormapIndex(image,(*p >> 4) & 0x3,exception);
1664c08aed51c5899665ade97263692328eea4af106cristy                SetPixelIndex(image,index,q);
167ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                q+=GetPixelChannels(image);
1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((image->columns % 4) >= 2)
1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
171c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy                    index=ConstrainColormapIndex(image,(*p >> 2) & 0x3,
172c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy                      exception);
1734c08aed51c5899665ade97263692328eea4af106cristy                    SetPixelIndex(image,index,q);
174ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                    q+=GetPixelChannels(image);
1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p++;
1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
179ccad00b02d1242dc1c039f9979337e00f69212e8dirk        (void) SyncAuthenticPixels(image,exception);
1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 4:  /* Convert PseudoColor scanline. */
1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
186acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
188bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < ((ssize_t) image->columns-1); x+=2)
1894c08aed51c5899665ade97263692328eea4af106cristy        {
190c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy            index=ConstrainColormapIndex(image,(*p >> 4) & 0xf,exception);
1914c08aed51c5899665ade97263692328eea4af106cristy            SetPixelIndex(image,index,q);
192ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy            q+=GetPixelChannels(image);
193c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy            index=ConstrainColormapIndex(image,(*p) & 0xf,exception);
1944c08aed51c5899665ade97263692328eea4af106cristy            SetPixelIndex(image,index,q);
195ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy            q+=GetPixelChannels(image);
1963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p++;
1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image->columns % 2) != 0)
1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
200c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy            index=ConstrainColormapIndex(image,(*p >> 4) & 0xf,exception);
2014c08aed51c5899665ade97263692328eea4af106cristy            SetPixelIndex(image,index,q);
202ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy            q+=GetPixelChannels(image);
2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p++;
2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
205ccad00b02d1242dc1c039f9979337e00f69212e8dirk        (void) SyncAuthenticPixels(image,exception);
2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 8: /* Convert PseudoColor scanline. */
2093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
211acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL) break;
212bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
2134e82e51d7ebce7b4ef0f808d906124dd6f812248cristy        {
214c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,*p,exception);
2154c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
2164e82e51d7ebce7b4ef0f808d906124dd6f812248cristy          p++;
217ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
2184e82e51d7ebce7b4ef0f808d906124dd6f812248cristy        }
219ccad00b02d1242dc1c039f9979337e00f69212e8dirk        (void) SyncAuthenticPixels(image,exception);
220ccad00b02d1242dc1c039f9979337e00f69212e8dirk        break;
2213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   Compute the number of colors in Grayed R[i]=G[i]=B[i] image
2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
228c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristystatic int GetCutColors(Image *image,ExceptionInfo *exception)
2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Quantum
2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    intensity,
2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scale_intensity;
2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2344c08aed51c5899665ade97263692328eea4af106cristy  register Quantum
2354e82e51d7ebce7b4ef0f808d906124dd6f812248cristy    *q;
2364e82e51d7ebce7b4ef0f808d906124dd6f812248cristy
2374e82e51d7ebce7b4ef0f808d906124dd6f812248cristy  ssize_t
2384e82e51d7ebce7b4ef0f808d906124dd6f812248cristy    x,
2394e82e51d7ebce7b4ef0f808d906124dd6f812248cristy    y;
2404e82e51d7ebce7b4ef0f808d906124dd6f812248cristy
2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  intensity=0;
2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scale_intensity=ScaleCharToQuantum(16);
243bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
246fa18e626bfb0f8953c8393f3252cbc3f0e07c80ccristy    if (q == (Quantum *) NULL)
247fa18e626bfb0f8953c8393f3252cbc3f0e07c80ccristy      break;
248bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=0; x < (ssize_t) image->columns; x++)
2493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2504c08aed51c5899665ade97263692328eea4af106cristy      if (intensity < GetPixelRed(image,q))
2514c08aed51c5899665ade97263692328eea4af106cristy        intensity=GetPixelRed(image,q);
2523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (intensity >= scale_intensity)
2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(255);
254ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(image);
2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (intensity < ScaleCharToQuantum(2))
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(2);
2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (intensity < ScaleCharToQuantum(16))
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(16);
2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((int) intensity);
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d C U T I m a g e                                                   %
2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadCUTImage() reads an CUT X image file and returns it.  It
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image.
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadCUTImage method is:
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadCUTImage(const ImageInfo *image_info,ExceptionInfo *exception)
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadCUTImage(const ImageInfo *image_info,ExceptionInfo *exception)
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *image,*palette;
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo *clone_info;
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType status;
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
299bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t EncodedByte;
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char RunCount,RunValue,RunCountMasked;
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  CUTHeader  Header;
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  CUTPalHeader PalHeader;
303bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t depth;
304bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t i,j;
305bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t ldblk;
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char *BImgBuff=NULL,*ptrB;
3074c08aed51c5899665ade97263692328eea4af106cristy  register Quantum *q;
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
313e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image_info->signature == MagickCoreSignature);
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
318e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
3199950d57e1124b73f684fb5946e206994cefda628cristy  image=AcquireImage(image_info,exception);
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read CUT image.
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  palette=NULL;
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  clone_info=NULL;
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Header.Width=ReadBlobLSBShort(image);
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Header.Height=ReadBlobLSBShort(image);
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Header.Reserved=ReadBlobLSBShort(image);
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (Header.Width==0 || Header.Height==0 || Header.Reserved!=0)
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    CUT_KO:  ThrowReaderException(CorruptImageError,"ImproperImageHeader");
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*---This code checks first line of image---*/
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  EncodedByte=ReadBlobLSBShort(image);
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RunCount=(unsigned char) ReadBlobByte(image);
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RunCountMasked=RunCount & 0x7F;
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ldblk=0;
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while((int) RunCountMasked!=0)  /*end of line?*/
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      i=1;
346bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      if((int) RunCount<0x80) i=(ssize_t) RunCountMasked;
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      offset=SeekBlob(image,TellBlob(image)+i,SEEK_SET);
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (offset < 0)
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if(EOFBlob(image) != MagickFalse) goto CUT_KO;  /*wrong data*/
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      EncodedByte-=i+1;
352bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      ldblk+=(ssize_t) RunCountMasked;
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      RunCount=(unsigned char) ReadBlobByte(image);
3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if(EOFBlob(image) != MagickFalse)  goto CUT_KO;  /*wrong data: unexpected eof in line*/
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      RunCountMasked=RunCount & 0x7F;
3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if(EncodedByte!=1) goto CUT_KO;  /*wrong data: size incorrect*/
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;        /*guess a number of bit planes*/
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if(ldblk==(int) Header.Width)   i=8;
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if(2*ldblk==(int) Header.Width) i=4;
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if(8*ldblk==(int) Header.Width) i=1;
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if(i==0) goto CUT_KO;    /*wrong data: incorrect bit planes*/
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  depth=i;
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=Header.Width;
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=Header.Height;
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=8;
369bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->colors=(size_t) (GetQuantumRange(1UL*i)+1);
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
371acabb847a592ca5e430c1c0949d03acfc0b78bb9cristy  if (image_info->ping != MagickFalse) goto Finish;
372acabb847a592ca5e430c1c0949d03acfc0b78bb9cristy  status=SetImageExtent(image,image->columns,image->rows,exception);
373acabb847a592ca5e430c1c0949d03acfc0b78bb9cristy  if (status == MagickFalse)
374acabb847a592ca5e430c1c0949d03acfc0b78bb9cristy    return(DestroyImageList(image));
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* ----- Do something with palette ----- */
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((clone_info=CloneImageInfo(image_info)) == NULL) goto NoPalette;
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
380bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  i=(ssize_t) strlen(clone_info->filename);
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  j=i;
3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while(--i>0)
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if(clone_info->filename[i]=='.')
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if(clone_info->filename[i]=='/' || clone_info->filename[i]=='\\' ||
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         clone_info->filename[i]==':' )
3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          i=j;
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(clone_info->filename+i,".PAL",(size_t)
397151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    (MagickPathExtent-i));
39818c6c27bc513a8c73a5bc4a2c157afb19c3e24b9cristy  if((clone_info->file=fopen_utf8(clone_info->filename,"rb"))==NULL)
3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(clone_info->filename+i,".pal",(size_t)
401151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy        (MagickPathExtent-i));
40218c6c27bc513a8c73a5bc4a2c157afb19c3e24b9cristy      if((clone_info->file=fopen_utf8(clone_info->filename,"rb"))==NULL)
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          clone_info->filename[i]='\0';
40518c6c27bc513a8c73a5bc4a2c157afb19c3e24b9cristy          if((clone_info->file=fopen_utf8(clone_info->filename,"rb"))==NULL)
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              clone_info=DestroyImageInfo(clone_info);
4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              clone_info=NULL;
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              goto NoPalette;
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4149950d57e1124b73f684fb5946e206994cefda628cristy  if( (palette=AcquireImage(clone_info,exception))==NULL ) goto NoPalette;
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(clone_info,palette,ReadBinaryBlobMode,exception);
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ErasePalette:
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      palette=DestroyImage(palette);
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      palette=NULL;
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      goto NoPalette;
4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if(palette!=NULL)
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
427da16f16767eb31921af855f17bda465fffc4e000cristy      (void) ReadBlob(palette,2,(unsigned char *) PalHeader.FileId);
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if(strncmp(PalHeader.FileId,"AH",2) != 0) goto ErasePalette;
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PalHeader.Version=ReadBlobLSBShort(palette);
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PalHeader.Size=ReadBlobLSBShort(palette);
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PalHeader.FileType=(char) ReadBlobByte(palette);
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PalHeader.SubType=(char) ReadBlobByte(palette);
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PalHeader.BoardID=ReadBlobLSBShort(palette);
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PalHeader.GraphicsMode=ReadBlobLSBShort(palette);
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PalHeader.MaxIndex=ReadBlobLSBShort(palette);
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PalHeader.MaxRed=ReadBlobLSBShort(palette);
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PalHeader.MaxGreen=ReadBlobLSBShort(palette);
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PalHeader.MaxBlue=ReadBlobLSBShort(palette);
439da16f16767eb31921af855f17bda465fffc4e000cristy      (void) ReadBlob(palette,20,(unsigned char *) PalHeader.PaletteId);
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if(PalHeader.MaxIndex<1) goto ErasePalette;
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=PalHeader.MaxIndex+1;
443018f07f7333b25743d0afff892450cebdb905c1acristy      if (AcquireImageColormap(image,image->colors,exception) == MagickFalse) goto NoMemory;
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if(PalHeader.MaxRed==0) PalHeader.MaxRed=(unsigned int) QuantumRange;  /*avoid division by 0*/
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if(PalHeader.MaxGreen==0) PalHeader.MaxGreen=(unsigned int) QuantumRange;
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if(PalHeader.MaxBlue==0) PalHeader.MaxBlue=(unsigned int) QuantumRange;
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for(i=0;i<=(int) PalHeader.MaxIndex;i++)
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {      /*this may be wrong- I don't know why is palette such strange*/
451bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          j=(ssize_t) TellBlob(palette);
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if((j % 512)>512-6)
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              j=((j / 512)+1)*512;
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              offset=SeekBlob(palette,j,SEEK_SET);
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (offset < 0)
4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(CorruptImageError,"ImproperImageHeader");
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->colormap[i].red=(Quantum) ReadBlobLSBShort(palette);
4604f3c0be11fec6eda4790699de19a9d1fa3272ec1cristy          if (QuantumRange != (Quantum) PalHeader.MaxRed)
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
462ce70c17bb6433add2eb069515a4f3105989e0662cristy              image->colormap[i].red=ClampToQuantum(((double)
4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colormap[i].red*QuantumRange+(PalHeader.MaxRed>>1))/
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PalHeader.MaxRed);
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->colormap[i].green=(Quantum) ReadBlobLSBShort(palette);
4674f3c0be11fec6eda4790699de19a9d1fa3272ec1cristy          if (QuantumRange != (Quantum) PalHeader.MaxGreen)
4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
469ce70c17bb6433add2eb069515a4f3105989e0662cristy              image->colormap[i].green=ClampToQuantum
4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (((double) image->colormap[i].green*QuantumRange+(PalHeader.MaxGreen>>1))/PalHeader.MaxGreen);
4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->colormap[i].blue=(Quantum) ReadBlobLSBShort(palette);
4734f3c0be11fec6eda4790699de19a9d1fa3272ec1cristy          if (QuantumRange != (Quantum) PalHeader.MaxBlue)
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
475ce70c17bb6433add2eb069515a4f3105989e0662cristy              image->colormap[i].blue=ClampToQuantum
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (((double)image->colormap[i].blue*QuantumRange+(PalHeader.MaxBlue>>1))/PalHeader.MaxBlue);
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy NoPalette:
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if(palette==NULL)
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=256;
489018f07f7333b25743d0afff892450cebdb905c1acristy      if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        NoMemory:
4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
495bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (i=0; i < (ssize_t)image->colors; i++)
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->colormap[i].red=ScaleCharToQuantum((unsigned char) i);
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->colormap[i].green=ScaleCharToQuantum((unsigned char) i);
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->colormap[i].blue=ScaleCharToQuantum((unsigned char) i);
5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* ----- Load RLE compressed raster ----- */
5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  BImgBuff=(unsigned char *) AcquireQuantumMemory((size_t) ldblk,
5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*BImgBuff));  /*Ldblk was set in the check phase*/
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if(BImgBuff==NULL) goto NoMemory;
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  offset=SeekBlob(image,6 /*sizeof(Header)*/,SEEK_SET);
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (offset < 0)
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < (int) Header.Height; i++)
5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      EncodedByte=ReadBlobLSBShort(image);
5153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ptrB=BImgBuff;
5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      j=ldblk;
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      RunCount=(unsigned char) ReadBlobByte(image);
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      RunCountMasked=RunCount & 0x7F;
5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5224e82e51d7ebce7b4ef0f808d906124dd6f812248cristy      while ((int) RunCountMasked != 0)
5234e82e51d7ebce7b4ef0f808d906124dd6f812248cristy      {
524bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          if((ssize_t) RunCountMasked>j)
5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {    /*Wrong Data*/
5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              RunCountMasked=(unsigned char) j;
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if(j==0)
5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if((int) RunCount>0x80)
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              RunValue=(unsigned char) ReadBlobByte(image);
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ResetMagickMemory(ptrB,(int) RunValue,(size_t) RunCountMasked);
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else {
539da16f16767eb31921af855f17bda465fffc4e000cristy            (void) ReadBlob(image,(size_t) RunCountMasked,ptrB);
5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ptrB+=(int) RunCountMasked;
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          j-=(int) RunCountMasked;
5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (EOFBlob(image) != MagickFalse) goto Finish;  /* wrong data: unexpected eof in line */
5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          RunCount=(unsigned char) ReadBlobByte(image);
5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          RunCountMasked=RunCount & 0x7F;
5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
550c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy      InsertRow(image,depth,BImgBuff,i,exception);
5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
552ea1a8aa04a9fe1500104284407c1cc06d20da699cristy  (void) SyncImage(image,exception);
5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*detect monochrome image*/
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if(palette==NULL)
5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {    /*attempt to detect binary (black&white) images*/
5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((image->storage_class == PseudoClass) &&
560f1d8548abecaf5ca89d453fd9fc0cde77d20672bdirk          (SetImageGray(image,exception) != MagickFalse))
5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
562c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          if(GetCutColors(image,exception)==2)
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
564bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t)image->colors; i++)
5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  register Quantum
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sample;
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  sample=ScaleCharToQuantum((unsigned char) i);
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if(image->colormap[i].red!=sample) goto Finish;
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if(image->colormap[i].green!=sample) goto Finish;
5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if(image->colormap[i].blue!=sample) goto Finish;
5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5749fff7b4fa7d657da7bfed66239982b85c6337de9cristy              image->colormap[1].red=image->colormap[1].green=
5756e963d8cbd0aebba1073d7f4b61e3d17177d6fedcristy                image->colormap[1].blue=QuantumRange;
576bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t)image->rows; i++)
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=QueueAuthenticPixels(image,0,i,image->columns,1,exception);
579bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (j=0; j < (ssize_t)image->columns; j++)
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
5814c08aed51c5899665ade97263692328eea4af106cristy                      if (GetPixelRed(image,q) == ScaleCharToQuantum(1))
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
5834c08aed51c5899665ade97263692328eea4af106cristy                          SetPixelRed(image,QuantumRange,q);
5844c08aed51c5899665ade97263692328eea4af106cristy                          SetPixelGreen(image,QuantumRange,q);
5854c08aed51c5899665ade97263692328eea4af106cristy                          SetPixelBlue(image,QuantumRange,q);
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
587ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                      q+=GetPixelChannels(image);
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse) goto Finish;
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Finish:
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (BImgBuff != NULL)
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    BImgBuff=(unsigned char *) RelinquishMagickMemory(BImgBuff);
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (palette != NULL)
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    palette=DestroyImage(palette);
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (clone_info != NULL)
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clone_info=DestroyImageInfo(clone_info);
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (EOFBlob(image) != MagickFalse)
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->filename);
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r C U T I m a g e                                           %
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterCUTImage() adds attributes for the CUT image format to
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The attributes include the image format
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterCUTImage method is:
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
629bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterCUTImage(void)
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
632bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterCUTImage(void)
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63706b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("CUT","CUT","DR Halo");
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadCUTImage;
63908e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags|=CoderSeekableStreamFlag;
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r C U T I m a g e                                       %
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterCUTImage() removes format registrations made by the
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  CUT module from the list of supported formats.
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterCUTImage method is:
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterCUTImage(void)
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterCUTImage(void)
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("CUT");
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
667