cut.c revision 9950d57e1124b73f684fb5946e206994cefda628
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
98bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic void InsertRow(ssize_t depth,unsigned char *p,ssize_t y,Image *image)
993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ExceptionInfo
1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *exception;
1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t bit; ssize_t x;
1044c08aed51c5899665ade97263692328eea4af106cristy  register Quantum *q;
1054c08aed51c5899665ade97263692328eea4af106cristy  Quantum index;
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1074c08aed51c5899665ade97263692328eea4af106cristy  index=0;
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  exception=(&image->exception);
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (depth)
1104e82e51d7ebce7b4ef0f808d906124dd6f812248cristy  {
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 1:  /* Convert bitmap scanline. */
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
114acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
116bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < ((ssize_t) image->columns-7); x+=8)
1174e82e51d7ebce7b4ef0f808d906124dd6f812248cristy        {
1184e82e51d7ebce7b4ef0f808d906124dd6f812248cristy          for (bit=0; bit < 8; bit++)
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
1204c08aed51c5899665ade97263692328eea4af106cristy            index=(Quantum) ((((*p) & (0x80 >> bit)) != 0) ? 0x01 : 0x00);
1214c08aed51c5899665ade97263692328eea4af106cristy            SetPixelIndex(image,index,q);
122ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy            q+=GetPixelChannels(image);
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
1244e82e51d7ebce7b4ef0f808d906124dd6f812248cristy          p++;
1254e82e51d7ebce7b4ef0f808d906124dd6f812248cristy        }
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image->columns % 8) != 0)
1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (bit=0; bit < (image->columns % 8); bit++)
1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
1304c08aed51c5899665ade97263692328eea4af106cristy                index=(Quantum) ((((*p) & (0x80 >> bit)) != 0) ? 0x01 : 0x00);
1314c08aed51c5899665ade97263692328eea4af106cristy                SetPixelIndex(image,index,q);
132ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                q+=GetPixelChannels(image);
1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p++;
1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 2:  /* Convert PseudoColor scanline. */
1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
143acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
145bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < ((ssize_t) image->columns-1); x+=2)
1464c08aed51c5899665ade97263692328eea4af106cristy        {
1474c08aed51c5899665ade97263692328eea4af106cristy          index=ConstrainColormapIndex(image,(*p >> 6) & 0x3);
1484c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
149ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
1504c08aed51c5899665ade97263692328eea4af106cristy          index=ConstrainColormapIndex(image,(*p >> 4) & 0x3);
1514c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
152ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
1534c08aed51c5899665ade97263692328eea4af106cristy          index=ConstrainColormapIndex(image,(*p >> 2) & 0x3);
1544c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
155ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
1564c08aed51c5899665ade97263692328eea4af106cristy          index=ConstrainColormapIndex(image,(*p) & 0x3);
1574c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
158ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
1594c08aed51c5899665ade97263692328eea4af106cristy          p++;
1604c08aed51c5899665ade97263692328eea4af106cristy        }
1613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image->columns % 4) != 0)
1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            index=ConstrainColormapIndex(image,(*p >> 6) & 0x3);
1644c08aed51c5899665ade97263692328eea4af106cristy            SetPixelIndex(image,index,q);
165ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy            q+=GetPixelChannels(image);
1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 4) >= 1)
1673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                index=ConstrainColormapIndex(image,(*p >> 4) & 0x3);
1704c08aed51c5899665ade97263692328eea4af106cristy                SetPixelIndex(image,index,q);
171ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                q+=GetPixelChannels(image);
1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((image->columns % 4) >= 2)
1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    index=ConstrainColormapIndex(image,(*p >> 2) & 0x3);
1764c08aed51c5899665ade97263692328eea4af106cristy                    SetPixelIndex(image,index,q);
177ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                    q+=GetPixelChannels(image);
1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p++;
1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 4:  /* Convert PseudoColor scanline. */
1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
190acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
192bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < ((ssize_t) image->columns-1); x+=2)
1934c08aed51c5899665ade97263692328eea4af106cristy        {
1943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            index=ConstrainColormapIndex(image,(*p >> 4) & 0xf);
1954c08aed51c5899665ade97263692328eea4af106cristy            SetPixelIndex(image,index,q);
196ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy            q+=GetPixelChannels(image);
1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            index=ConstrainColormapIndex(image,(*p) & 0xf);
1984c08aed51c5899665ade97263692328eea4af106cristy            SetPixelIndex(image,index,q);
199ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy            q+=GetPixelChannels(image);
2003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p++;
2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image->columns % 2) != 0)
2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            index=ConstrainColormapIndex(image,(*p >> 4) & 0xf);
2054c08aed51c5899665ade97263692328eea4af106cristy            SetPixelIndex(image,index,q);
206ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy            q+=GetPixelChannels(image);
2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p++;
2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
2093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 8: /* Convert PseudoColor scanline. */
2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
216acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL) break;
217bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
2184e82e51d7ebce7b4ef0f808d906124dd6f812248cristy        {
2194e82e51d7ebce7b4ef0f808d906124dd6f812248cristy          index=ConstrainColormapIndex(image,*p);
2204c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
2214e82e51d7ebce7b4ef0f808d906124dd6f812248cristy          p++;
222ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
2234e82e51d7ebce7b4ef0f808d906124dd6f812248cristy        }
2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   Compute the number of colors in Grayed R[i]=G[i]=B[i] image
2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int GetCutColors(Image *image)
2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ExceptionInfo
2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *exception;
2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Quantum
2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    intensity,
2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scale_intensity;
2433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2444c08aed51c5899665ade97263692328eea4af106cristy  register Quantum
2454e82e51d7ebce7b4ef0f808d906124dd6f812248cristy    *q;
2464e82e51d7ebce7b4ef0f808d906124dd6f812248cristy
2474e82e51d7ebce7b4ef0f808d906124dd6f812248cristy  ssize_t
2484e82e51d7ebce7b4ef0f808d906124dd6f812248cristy    x,
2494e82e51d7ebce7b4ef0f808d906124dd6f812248cristy    y;
2504e82e51d7ebce7b4ef0f808d906124dd6f812248cristy
2513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  exception=(&image->exception);
2523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  intensity=0;
2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scale_intensity=ScaleCharToQuantum(16);
254bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
257bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=0; x < (ssize_t) image->columns; x++)
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2594c08aed51c5899665ade97263692328eea4af106cristy      if (intensity < GetPixelRed(image,q))
2604c08aed51c5899665ade97263692328eea4af106cristy        intensity=GetPixelRed(image,q);
2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (intensity >= scale_intensity)
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(255);
263ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(image);
2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (intensity < ScaleCharToQuantum(2))
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(2);
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (intensity < ScaleCharToQuantum(16))
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(16);
2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((int) intensity);
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d C U T I m a g e                                                   %
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadCUTImage() reads an CUT X image file and returns it.  It
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image.
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadCUTImage method is:
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadCUTImage(const ImageInfo *image_info,ExceptionInfo *exception)
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadCUTImage(const ImageInfo *image_info,ExceptionInfo *exception)
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *image,*palette;
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo *clone_info;
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType status;
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
308bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t EncodedByte;
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char RunCount,RunValue,RunCountMasked;
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  CUTHeader  Header;
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  CUTPalHeader PalHeader;
312bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t depth;
313bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t i,j;
314bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t ldblk;
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char *BImgBuff=NULL,*ptrB;
3164c08aed51c5899665ade97263692328eea4af106cristy  register Quantum *q;
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
3289950d57e1124b73f684fb5946e206994cefda628cristy  image=AcquireImage(image_info,exception);
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read CUT image.
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  palette=NULL;
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  clone_info=NULL;
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Header.Width=ReadBlobLSBShort(image);
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Header.Height=ReadBlobLSBShort(image);
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Header.Reserved=ReadBlobLSBShort(image);
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (Header.Width==0 || Header.Height==0 || Header.Reserved!=0)
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    CUT_KO:  ThrowReaderException(CorruptImageError,"ImproperImageHeader");
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*---This code checks first line of image---*/
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  EncodedByte=ReadBlobLSBShort(image);
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RunCount=(unsigned char) ReadBlobByte(image);
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RunCountMasked=RunCount & 0x7F;
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ldblk=0;
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while((int) RunCountMasked!=0)  /*end of line?*/
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      i=1;
355bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      if((int) RunCount<0x80) i=(ssize_t) RunCountMasked;
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      offset=SeekBlob(image,TellBlob(image)+i,SEEK_SET);
3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (offset < 0)
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if(EOFBlob(image) != MagickFalse) goto CUT_KO;  /*wrong data*/
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      EncodedByte-=i+1;
361bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      ldblk+=(ssize_t) RunCountMasked;
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      RunCount=(unsigned char) ReadBlobByte(image);
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if(EOFBlob(image) != MagickFalse)  goto CUT_KO;  /*wrong data: unexpected eof in line*/
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      RunCountMasked=RunCount & 0x7F;
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if(EncodedByte!=1) goto CUT_KO;  /*wrong data: size incorrect*/
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;        /*guess a number of bit planes*/
3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if(ldblk==(int) Header.Width)   i=8;
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if(2*ldblk==(int) Header.Width) i=4;
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if(8*ldblk==(int) Header.Width) i=1;
3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if(i==0) goto CUT_KO;    /*wrong data: incorrect bit planes*/
3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  depth=i;
3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=Header.Width;
3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=Header.Height;
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=8;
378bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->colors=(size_t) (GetQuantumRange(1UL*i)+1);
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping) goto Finish;
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* ----- Do something with palette ----- */
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((clone_info=CloneImageInfo(image_info)) == NULL) goto NoPalette;
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
386bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  i=(ssize_t) strlen(clone_info->filename);
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  j=i;
3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while(--i>0)
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if(clone_info->filename[i]=='.')
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if(clone_info->filename[i]=='/' || clone_info->filename[i]=='\\' ||
3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         clone_info->filename[i]==':' )
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          i=j;
3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(clone_info->filename+i,".PAL",(size_t)
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (MaxTextExtent-i));
40418c6c27bc513a8c73a5bc4a2c157afb19c3e24b9cristy  if((clone_info->file=fopen_utf8(clone_info->filename,"rb"))==NULL)
4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(clone_info->filename+i,".pal",(size_t)
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (MaxTextExtent-i));
40818c6c27bc513a8c73a5bc4a2c157afb19c3e24b9cristy      if((clone_info->file=fopen_utf8(clone_info->filename,"rb"))==NULL)
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          clone_info->filename[i]='\0';
41118c6c27bc513a8c73a5bc4a2c157afb19c3e24b9cristy          if((clone_info->file=fopen_utf8(clone_info->filename,"rb"))==NULL)
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              clone_info=DestroyImageInfo(clone_info);
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              clone_info=NULL;
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              goto NoPalette;
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4209950d57e1124b73f684fb5946e206994cefda628cristy  if( (palette=AcquireImage(clone_info,exception))==NULL ) goto NoPalette;
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(clone_info,palette,ReadBinaryBlobMode,exception);
4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ErasePalette:
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      palette=DestroyImage(palette);
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      palette=NULL;
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      goto NoPalette;
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if(palette!=NULL)
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
433da16f16767eb31921af855f17bda465fffc4e000cristy      (void) ReadBlob(palette,2,(unsigned char *) PalHeader.FileId);
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if(strncmp(PalHeader.FileId,"AH",2) != 0) goto ErasePalette;
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PalHeader.Version=ReadBlobLSBShort(palette);
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PalHeader.Size=ReadBlobLSBShort(palette);
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PalHeader.FileType=(char) ReadBlobByte(palette);
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PalHeader.SubType=(char) ReadBlobByte(palette);
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PalHeader.BoardID=ReadBlobLSBShort(palette);
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PalHeader.GraphicsMode=ReadBlobLSBShort(palette);
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PalHeader.MaxIndex=ReadBlobLSBShort(palette);
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PalHeader.MaxRed=ReadBlobLSBShort(palette);
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PalHeader.MaxGreen=ReadBlobLSBShort(palette);
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PalHeader.MaxBlue=ReadBlobLSBShort(palette);
445da16f16767eb31921af855f17bda465fffc4e000cristy      (void) ReadBlob(palette,20,(unsigned char *) PalHeader.PaletteId);
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if(PalHeader.MaxIndex<1) goto ErasePalette;
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=PalHeader.MaxIndex+1;
449018f07f7333b25743d0afff892450cebdb905c1acristy      if (AcquireImageColormap(image,image->colors,exception) == MagickFalse) goto NoMemory;
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if(PalHeader.MaxRed==0) PalHeader.MaxRed=(unsigned int) QuantumRange;  /*avoid division by 0*/
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if(PalHeader.MaxGreen==0) PalHeader.MaxGreen=(unsigned int) QuantumRange;
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if(PalHeader.MaxBlue==0) PalHeader.MaxBlue=(unsigned int) QuantumRange;
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for(i=0;i<=(int) PalHeader.MaxIndex;i++)
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {      /*this may be wrong- I don't know why is palette such strange*/
457bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          j=(ssize_t) TellBlob(palette);
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if((j % 512)>512-6)
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              j=((j / 512)+1)*512;
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              offset=SeekBlob(palette,j,SEEK_SET);
4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (offset < 0)
4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(CorruptImageError,"ImproperImageHeader");
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->colormap[i].red=(Quantum) ReadBlobLSBShort(palette);
4664f3c0be11fec6eda4790699de19a9d1fa3272ec1cristy          if (QuantumRange != (Quantum) PalHeader.MaxRed)
4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
468ce70c17bb6433add2eb069515a4f3105989e0662cristy              image->colormap[i].red=ClampToQuantum(((double)
4693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colormap[i].red*QuantumRange+(PalHeader.MaxRed>>1))/
4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PalHeader.MaxRed);
4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->colormap[i].green=(Quantum) ReadBlobLSBShort(palette);
4734f3c0be11fec6eda4790699de19a9d1fa3272ec1cristy          if (QuantumRange != (Quantum) PalHeader.MaxGreen)
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
475ce70c17bb6433add2eb069515a4f3105989e0662cristy              image->colormap[i].green=ClampToQuantum
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (((double) image->colormap[i].green*QuantumRange+(PalHeader.MaxGreen>>1))/PalHeader.MaxGreen);
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->colormap[i].blue=(Quantum) ReadBlobLSBShort(palette);
4794f3c0be11fec6eda4790699de19a9d1fa3272ec1cristy          if (QuantumRange != (Quantum) PalHeader.MaxBlue)
4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
481ce70c17bb6433add2eb069515a4f3105989e0662cristy              image->colormap[i].blue=ClampToQuantum
4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (((double)image->colormap[i].blue*QuantumRange+(PalHeader.MaxBlue>>1))/PalHeader.MaxBlue);
4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy NoPalette:
4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if(palette==NULL)
4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=256;
495018f07f7333b25743d0afff892450cebdb905c1acristy      if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        NoMemory:
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
501bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (i=0; i < (ssize_t)image->colors; i++)
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->colormap[i].red=ScaleCharToQuantum((unsigned char) i);
5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->colormap[i].green=ScaleCharToQuantum((unsigned char) i);
5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->colormap[i].blue=ScaleCharToQuantum((unsigned char) i);
5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* ----- Load RLE compressed raster ----- */
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  BImgBuff=(unsigned char *) AcquireQuantumMemory((size_t) ldblk,
5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*BImgBuff));  /*Ldblk was set in the check phase*/
5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if(BImgBuff==NULL) goto NoMemory;
5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  offset=SeekBlob(image,6 /*sizeof(Header)*/,SEEK_SET);
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (offset < 0)
5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < (int) Header.Height; i++)
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      EncodedByte=ReadBlobLSBShort(image);
5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ptrB=BImgBuff;
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      j=ldblk;
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      RunCount=(unsigned char) ReadBlobByte(image);
5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      RunCountMasked=RunCount & 0x7F;
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5284e82e51d7ebce7b4ef0f808d906124dd6f812248cristy      while ((int) RunCountMasked != 0)
5294e82e51d7ebce7b4ef0f808d906124dd6f812248cristy      {
530bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          if((ssize_t) RunCountMasked>j)
5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {    /*Wrong Data*/
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              RunCountMasked=(unsigned char) j;
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if(j==0)
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if((int) RunCount>0x80)
5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              RunValue=(unsigned char) ReadBlobByte(image);
5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ResetMagickMemory(ptrB,(int) RunValue,(size_t) RunCountMasked);
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else {
545da16f16767eb31921af855f17bda465fffc4e000cristy            (void) ReadBlob(image,(size_t) RunCountMasked,ptrB);
5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ptrB+=(int) RunCountMasked;
5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          j-=(int) RunCountMasked;
5503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (EOFBlob(image) != MagickFalse) goto Finish;  /* wrong data: unexpected eof in line */
5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          RunCount=(unsigned char) ReadBlobByte(image);
5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          RunCountMasked=RunCount & 0x7F;
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      InsertRow(depth,BImgBuff,i,image);
5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5584e82e51d7ebce7b4ef0f808d906124dd6f812248cristy  (void) SyncImage(image);
5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*detect monochrome image*/
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if(palette==NULL)
5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {    /*attempt to detect binary (black&white) images*/
5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((image->storage_class == PseudoClass) &&
5664c08aed51c5899665ade97263692328eea4af106cristy          (IsImageGray(image,&image->exception) != MagickFalse))
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if(GetCutColors(image)==2)
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
570bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t)image->colors; i++)
5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  register Quantum
5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sample;
5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  sample=ScaleCharToQuantum((unsigned char) i);
5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if(image->colormap[i].red!=sample) goto Finish;
5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if(image->colormap[i].green!=sample) goto Finish;
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if(image->colormap[i].blue!=sample) goto Finish;
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5809fff7b4fa7d657da7bfed66239982b85c6337de9cristy              image->colormap[1].red=image->colormap[1].green=
5819fff7b4fa7d657da7bfed66239982b85c6337de9cristy                image->colormap[1].blue=(Quantum) QuantumRange;
582bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t)image->rows; i++)
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=QueueAuthenticPixels(image,0,i,image->columns,1,exception);
585bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (j=0; j < (ssize_t)image->columns; j++)
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
5874c08aed51c5899665ade97263692328eea4af106cristy                      if (GetPixelRed(image,q) == ScaleCharToQuantum(1))
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
5894c08aed51c5899665ade97263692328eea4af106cristy                          SetPixelRed(image,QuantumRange,q);
5904c08aed51c5899665ade97263692328eea4af106cristy                          SetPixelGreen(image,QuantumRange,q);
5914c08aed51c5899665ade97263692328eea4af106cristy                          SetPixelBlue(image,QuantumRange,q);
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
593ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                      q+=GetPixelChannels(image);
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse) goto Finish;
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Finish:
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (BImgBuff != NULL)
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    BImgBuff=(unsigned char *) RelinquishMagickMemory(BImgBuff);
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (palette != NULL)
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    palette=DestroyImage(palette);
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (clone_info != NULL)
6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clone_info=DestroyImageInfo(clone_info);
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (EOFBlob(image) != MagickFalse)
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->filename);
6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r C U T I m a g e                                           %
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterCUTImage() adds attributes for the CUT image format to
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The attributes include the image format
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterCUTImage method is:
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
635bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterCUTImage(void)
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
638bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterCUTImage(void)
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("CUT");
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadCUTImage;
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("DR Halo");
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("CUT");
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r C U T I m a g e                                       %
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterCUTImage() removes format registrations made by the
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  CUT module from the list of supported formats.
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterCUTImage method is:
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterCUTImage(void)
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterCUTImage(void)
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("CUT");
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
675