cut.c revision 06b627a07ff44e1ff93ef1288c9f428066ded10d
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3%                                                                             %
4%                                                                             %
5%                              CCC  U   U  TTTTT                              %
6%                             C     U   U    T                                %
7%                             C     U   U    T                                %
8%                             C     U   U    T                                %
9%                              CCC   UUU     T                                %
10%                                                                             %
11%                                                                             %
12%                         Read DR Halo Image Format                           %
13%                                                                             %
14%                              Software Design                                %
15%                              Jaroslav Fojtik                                %
16%                                 June 2000                                   %
17%                                                                             %
18%                                                                             %
19%  Permission is hereby granted, free of charge, to any person obtaining a    %
20%  copy of this software and associated documentation files ("ImageMagick"),  %
21%  to deal in ImageMagick without restriction, including without limitation   %
22%  the rights to use, copy, modify, merge, publish, distribute, sublicense,   %
23%  and/or sell copies of ImageMagick, and to permit persons to whom the       %
24%  ImageMagick is furnished to do so, subject to the following conditions:    %
25%                                                                             %
26%  The above copyright notice and this permission notice shall be included in %
27%  all copies or substantial portions of ImageMagick.                         %
28%                                                                             %
29%  The software is provided "as is", without warranty of any kind, express or %
30%  implied, including but not limited to the warranties of merchantability,   %
31%  fitness for a particular purpose and noninfringement.  In no event shall   %
32%  ImageMagick Studio be liable for any claim, damages or other liability,    %
33%  whether in an action of contract, tort or otherwise, arising from, out of  %
34%  or in connection with ImageMagick or the use or other dealings in          %
35%  ImageMagick.                                                               %
36%                                                                             %
37%  Except as contained in this notice, the name of the ImageMagick Studio     %
38%  shall not be used in advertising or otherwise to promote the sale, use or  %
39%  other dealings in ImageMagick without prior written authorization from the %
40%  ImageMagick Studio.                                                        %
41%                                                                             %
42%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43%
44%
45*/
46
47/*
48  Include declarations.
49*/
50#include "MagickCore/studio.h"
51#include "MagickCore/attribute.h"
52#include "MagickCore/blob.h"
53#include "MagickCore/blob-private.h"
54#include "MagickCore/cache.h"
55#include "MagickCore/color.h"
56#include "MagickCore/color-private.h"
57#include "MagickCore/colormap.h"
58#include "MagickCore/colormap-private.h"
59#include "MagickCore/exception.h"
60#include "MagickCore/exception-private.h"
61#include "MagickCore/image.h"
62#include "MagickCore/image-private.h"
63#include "MagickCore/list.h"
64#include "MagickCore/magick.h"
65#include "MagickCore/memory_.h"
66#include "MagickCore/pixel-accessor.h"
67#include "MagickCore/quantum-private.h"
68#include "MagickCore/static.h"
69#include "MagickCore/string_.h"
70#include "MagickCore/module.h"
71#include "MagickCore/utility.h"
72#include "MagickCore/utility-private.h"
73
74typedef struct
75{
76  unsigned Width;
77  unsigned Height;
78  unsigned Reserved;
79} CUTHeader;
80
81typedef struct
82{
83  char FileId[2];
84  unsigned Version;
85  unsigned Size;
86  char FileType;
87  char SubType;
88  unsigned BoardID;
89  unsigned GraphicsMode;
90  unsigned MaxIndex;
91  unsigned MaxRed;
92  unsigned MaxGreen;
93  unsigned MaxBlue;
94  char PaletteId[20];
95} CUTPalHeader;
96
97
98static void InsertRow(Image *image,ssize_t depth,unsigned char *p,ssize_t y,
99  ExceptionInfo *exception)
100{
101  size_t bit; ssize_t x;
102  register Quantum *q;
103  Quantum index;
104
105  index=0;
106  switch (depth)
107  {
108    case 1:  /* Convert bitmap scanline. */
109      {
110        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
111        if (q == (Quantum *) NULL)
112          break;
113        for (x=0; x < ((ssize_t) image->columns-7); x+=8)
114        {
115          for (bit=0; bit < 8; bit++)
116          {
117            index=(Quantum) ((((*p) & (0x80 >> bit)) != 0) ? 0x01 : 0x00);
118            SetPixelIndex(image,index,q);
119            q+=GetPixelChannels(image);
120          }
121          p++;
122        }
123        if ((image->columns % 8) != 0)
124          {
125            for (bit=0; bit < (image->columns % 8); bit++)
126              {
127                index=(Quantum) ((((*p) & (0x80 >> bit)) != 0) ? 0x01 : 0x00);
128                SetPixelIndex(image,index,q);
129                q+=GetPixelChannels(image);
130              }
131            p++;
132          }
133        if (SyncAuthenticPixels(image,exception) == MagickFalse)
134          break;
135        break;
136      }
137    case 2:  /* Convert PseudoColor scanline. */
138      {
139        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
140        if (q == (Quantum *) NULL)
141          break;
142        for (x=0; x < ((ssize_t) image->columns-1); x+=2)
143        {
144          index=ConstrainColormapIndex(image,(*p >> 6) & 0x3,exception);
145          SetPixelIndex(image,index,q);
146          q+=GetPixelChannels(image);
147          index=ConstrainColormapIndex(image,(*p >> 4) & 0x3,exception);
148          SetPixelIndex(image,index,q);
149          q+=GetPixelChannels(image);
150          index=ConstrainColormapIndex(image,(*p >> 2) & 0x3,exception);
151          SetPixelIndex(image,index,q);
152          q+=GetPixelChannels(image);
153          index=ConstrainColormapIndex(image,(*p) & 0x3,exception);
154          SetPixelIndex(image,index,q);
155          q+=GetPixelChannels(image);
156          p++;
157        }
158        if ((image->columns % 4) != 0)
159          {
160            index=ConstrainColormapIndex(image,(*p >> 6) & 0x3,exception);
161            SetPixelIndex(image,index,q);
162            q+=GetPixelChannels(image);
163            if ((image->columns % 4) >= 1)
164
165              {
166                index=ConstrainColormapIndex(image,(*p >> 4) & 0x3,exception);
167                SetPixelIndex(image,index,q);
168                q+=GetPixelChannels(image);
169                if ((image->columns % 4) >= 2)
170
171                  {
172                    index=ConstrainColormapIndex(image,(*p >> 2) & 0x3,
173                      exception);
174                    SetPixelIndex(image,index,q);
175                    q+=GetPixelChannels(image);
176                  }
177              }
178            p++;
179          }
180        if (SyncAuthenticPixels(image,exception) == MagickFalse)
181          break;
182        break;
183      }
184
185    case 4:  /* Convert PseudoColor scanline. */
186      {
187        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
188        if (q == (Quantum *) NULL)
189          break;
190        for (x=0; x < ((ssize_t) image->columns-1); x+=2)
191        {
192            index=ConstrainColormapIndex(image,(*p >> 4) & 0xf,exception);
193            SetPixelIndex(image,index,q);
194            q+=GetPixelChannels(image);
195            index=ConstrainColormapIndex(image,(*p) & 0xf,exception);
196            SetPixelIndex(image,index,q);
197            q+=GetPixelChannels(image);
198            p++;
199          }
200        if ((image->columns % 2) != 0)
201          {
202            index=ConstrainColormapIndex(image,(*p >> 4) & 0xf,exception);
203            SetPixelIndex(image,index,q);
204            q+=GetPixelChannels(image);
205            p++;
206          }
207        if (SyncAuthenticPixels(image,exception) == MagickFalse)
208          break;
209        break;
210      }
211    case 8: /* Convert PseudoColor scanline. */
212      {
213        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
214        if (q == (Quantum *) NULL) break;
215        for (x=0; x < (ssize_t) image->columns; x++)
216        {
217          index=ConstrainColormapIndex(image,*p,exception);
218          SetPixelIndex(image,index,q);
219          p++;
220          q+=GetPixelChannels(image);
221        }
222        if (SyncAuthenticPixels(image,exception) == MagickFalse)
223          break;
224      }
225      break;
226
227    }
228}
229
230/*
231   Compute the number of colors in Grayed R[i]=G[i]=B[i] image
232*/
233static int GetCutColors(Image *image,ExceptionInfo *exception)
234{
235  Quantum
236    intensity,
237    scale_intensity;
238
239  register Quantum
240    *q;
241
242  ssize_t
243    x,
244    y;
245
246  intensity=0;
247  scale_intensity=ScaleCharToQuantum(16);
248  for (y=0; y < (ssize_t) image->rows; y++)
249  {
250    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
251    if (q == (Quantum *) NULL)
252      break;
253    for (x=0; x < (ssize_t) image->columns; x++)
254    {
255      if (intensity < GetPixelRed(image,q))
256        intensity=GetPixelRed(image,q);
257      if (intensity >= scale_intensity)
258        return(255);
259      q+=GetPixelChannels(image);
260    }
261  }
262  if (intensity < ScaleCharToQuantum(2))
263    return(2);
264  if (intensity < ScaleCharToQuantum(16))
265    return(16);
266  return((int) intensity);
267}
268
269/*
270%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
271%                                                                             %
272%                                                                             %
273%                                                                             %
274%   R e a d C U T I m a g e                                                   %
275%                                                                             %
276%                                                                             %
277%                                                                             %
278%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
279%
280%  ReadCUTImage() reads an CUT X image file and returns it.  It
281%  allocates the memory necessary for the new Image structure and returns a
282%  pointer to the new image.
283%
284%  The format of the ReadCUTImage method is:
285%
286%      Image *ReadCUTImage(const ImageInfo *image_info,ExceptionInfo *exception)
287%
288%  A description of each parameter follows:
289%
290%    o image_info: the image info.
291%
292%    o exception: return any errors or warnings in this structure.
293%
294*/
295static Image *ReadCUTImage(const ImageInfo *image_info,ExceptionInfo *exception)
296{
297  Image *image,*palette;
298  ImageInfo *clone_info;
299  MagickBooleanType status;
300
301  MagickOffsetType
302    offset;
303
304  size_t EncodedByte;
305  unsigned char RunCount,RunValue,RunCountMasked;
306  CUTHeader  Header;
307  CUTPalHeader PalHeader;
308  ssize_t depth;
309  ssize_t i,j;
310  ssize_t ldblk;
311  unsigned char *BImgBuff=NULL,*ptrB;
312  register Quantum *q;
313
314  /*
315    Open image file.
316  */
317  assert(image_info != (const ImageInfo *) NULL);
318  assert(image_info->signature == MagickSignature);
319  if (image_info->debug != MagickFalse)
320    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
321      image_info->filename);
322  assert(exception != (ExceptionInfo *) NULL);
323  assert(exception->signature == MagickSignature);
324  image=AcquireImage(image_info,exception);
325  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
326  if (status == MagickFalse)
327    {
328      image=DestroyImageList(image);
329      return((Image *) NULL);
330    }
331  /*
332    Read CUT image.
333  */
334  palette=NULL;
335  clone_info=NULL;
336  Header.Width=ReadBlobLSBShort(image);
337  Header.Height=ReadBlobLSBShort(image);
338  Header.Reserved=ReadBlobLSBShort(image);
339
340  if (Header.Width==0 || Header.Height==0 || Header.Reserved!=0)
341    CUT_KO:  ThrowReaderException(CorruptImageError,"ImproperImageHeader");
342
343  /*---This code checks first line of image---*/
344  EncodedByte=ReadBlobLSBShort(image);
345  RunCount=(unsigned char) ReadBlobByte(image);
346  RunCountMasked=RunCount & 0x7F;
347  ldblk=0;
348  while((int) RunCountMasked!=0)  /*end of line?*/
349    {
350      i=1;
351      if((int) RunCount<0x80) i=(ssize_t) RunCountMasked;
352      offset=SeekBlob(image,TellBlob(image)+i,SEEK_SET);
353      if (offset < 0)
354        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
355      if(EOFBlob(image) != MagickFalse) goto CUT_KO;  /*wrong data*/
356      EncodedByte-=i+1;
357      ldblk+=(ssize_t) RunCountMasked;
358
359      RunCount=(unsigned char) ReadBlobByte(image);
360      if(EOFBlob(image) != MagickFalse)  goto CUT_KO;  /*wrong data: unexpected eof in line*/
361      RunCountMasked=RunCount & 0x7F;
362    }
363  if(EncodedByte!=1) goto CUT_KO;  /*wrong data: size incorrect*/
364  i=0;        /*guess a number of bit planes*/
365  if(ldblk==(int) Header.Width)   i=8;
366  if(2*ldblk==(int) Header.Width) i=4;
367  if(8*ldblk==(int) Header.Width) i=1;
368  if(i==0) goto CUT_KO;    /*wrong data: incorrect bit planes*/
369  depth=i;
370
371  image->columns=Header.Width;
372  image->rows=Header.Height;
373  image->depth=8;
374  image->colors=(size_t) (GetQuantumRange(1UL*i)+1);
375
376  if (image_info->ping != MagickFalse) goto Finish;
377  status=SetImageExtent(image,image->columns,image->rows,exception);
378  if (status == MagickFalse)
379    return(DestroyImageList(image));
380
381  /* ----- Do something with palette ----- */
382  if ((clone_info=CloneImageInfo(image_info)) == NULL) goto NoPalette;
383
384
385  i=(ssize_t) strlen(clone_info->filename);
386  j=i;
387  while(--i>0)
388    {
389      if(clone_info->filename[i]=='.')
390        {
391          break;
392        }
393      if(clone_info->filename[i]=='/' || clone_info->filename[i]=='\\' ||
394         clone_info->filename[i]==':' )
395        {
396          i=j;
397          break;
398        }
399    }
400
401  (void) CopyMagickString(clone_info->filename+i,".PAL",(size_t)
402    (MaxTextExtent-i));
403  if((clone_info->file=fopen_utf8(clone_info->filename,"rb"))==NULL)
404    {
405      (void) CopyMagickString(clone_info->filename+i,".pal",(size_t)
406        (MaxTextExtent-i));
407      if((clone_info->file=fopen_utf8(clone_info->filename,"rb"))==NULL)
408        {
409          clone_info->filename[i]='\0';
410          if((clone_info->file=fopen_utf8(clone_info->filename,"rb"))==NULL)
411            {
412              clone_info=DestroyImageInfo(clone_info);
413              clone_info=NULL;
414              goto NoPalette;
415            }
416        }
417    }
418
419  if( (palette=AcquireImage(clone_info,exception))==NULL ) goto NoPalette;
420  status=OpenBlob(clone_info,palette,ReadBinaryBlobMode,exception);
421  if (status == MagickFalse)
422    {
423    ErasePalette:
424      palette=DestroyImage(palette);
425      palette=NULL;
426      goto NoPalette;
427    }
428
429
430  if(palette!=NULL)
431    {
432      (void) ReadBlob(palette,2,(unsigned char *) PalHeader.FileId);
433      if(strncmp(PalHeader.FileId,"AH",2) != 0) goto ErasePalette;
434      PalHeader.Version=ReadBlobLSBShort(palette);
435      PalHeader.Size=ReadBlobLSBShort(palette);
436      PalHeader.FileType=(char) ReadBlobByte(palette);
437      PalHeader.SubType=(char) ReadBlobByte(palette);
438      PalHeader.BoardID=ReadBlobLSBShort(palette);
439      PalHeader.GraphicsMode=ReadBlobLSBShort(palette);
440      PalHeader.MaxIndex=ReadBlobLSBShort(palette);
441      PalHeader.MaxRed=ReadBlobLSBShort(palette);
442      PalHeader.MaxGreen=ReadBlobLSBShort(palette);
443      PalHeader.MaxBlue=ReadBlobLSBShort(palette);
444      (void) ReadBlob(palette,20,(unsigned char *) PalHeader.PaletteId);
445
446      if(PalHeader.MaxIndex<1) goto ErasePalette;
447      image->colors=PalHeader.MaxIndex+1;
448      if (AcquireImageColormap(image,image->colors,exception) == MagickFalse) goto NoMemory;
449
450      if(PalHeader.MaxRed==0) PalHeader.MaxRed=(unsigned int) QuantumRange;  /*avoid division by 0*/
451      if(PalHeader.MaxGreen==0) PalHeader.MaxGreen=(unsigned int) QuantumRange;
452      if(PalHeader.MaxBlue==0) PalHeader.MaxBlue=(unsigned int) QuantumRange;
453
454      for(i=0;i<=(int) PalHeader.MaxIndex;i++)
455        {      /*this may be wrong- I don't know why is palette such strange*/
456          j=(ssize_t) TellBlob(palette);
457          if((j % 512)>512-6)
458            {
459              j=((j / 512)+1)*512;
460              offset=SeekBlob(palette,j,SEEK_SET);
461              if (offset < 0)
462                ThrowReaderException(CorruptImageError,"ImproperImageHeader");
463            }
464          image->colormap[i].red=(Quantum) ReadBlobLSBShort(palette);
465          if (QuantumRange != (Quantum) PalHeader.MaxRed)
466            {
467              image->colormap[i].red=ClampToQuantum(((double)
468                image->colormap[i].red*QuantumRange+(PalHeader.MaxRed>>1))/
469                PalHeader.MaxRed);
470            }
471          image->colormap[i].green=(Quantum) ReadBlobLSBShort(palette);
472          if (QuantumRange != (Quantum) PalHeader.MaxGreen)
473            {
474              image->colormap[i].green=ClampToQuantum
475                (((double) image->colormap[i].green*QuantumRange+(PalHeader.MaxGreen>>1))/PalHeader.MaxGreen);
476            }
477          image->colormap[i].blue=(Quantum) ReadBlobLSBShort(palette);
478          if (QuantumRange != (Quantum) PalHeader.MaxBlue)
479            {
480              image->colormap[i].blue=ClampToQuantum
481                (((double)image->colormap[i].blue*QuantumRange+(PalHeader.MaxBlue>>1))/PalHeader.MaxBlue);
482            }
483
484        }
485    }
486
487
488
489 NoPalette:
490  if(palette==NULL)
491    {
492
493      image->colors=256;
494      if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
495        {
496        NoMemory:
497          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
498            }
499
500      for (i=0; i < (ssize_t)image->colors; i++)
501        {
502          image->colormap[i].red=ScaleCharToQuantum((unsigned char) i);
503          image->colormap[i].green=ScaleCharToQuantum((unsigned char) i);
504          image->colormap[i].blue=ScaleCharToQuantum((unsigned char) i);
505        }
506    }
507
508
509  /* ----- Load RLE compressed raster ----- */
510  BImgBuff=(unsigned char *) AcquireQuantumMemory((size_t) ldblk,
511    sizeof(*BImgBuff));  /*Ldblk was set in the check phase*/
512  if(BImgBuff==NULL) goto NoMemory;
513
514  offset=SeekBlob(image,6 /*sizeof(Header)*/,SEEK_SET);
515  if (offset < 0)
516    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
517  for (i=0; i < (int) Header.Height; i++)
518  {
519      EncodedByte=ReadBlobLSBShort(image);
520
521      ptrB=BImgBuff;
522      j=ldblk;
523
524      RunCount=(unsigned char) ReadBlobByte(image);
525      RunCountMasked=RunCount & 0x7F;
526
527      while ((int) RunCountMasked != 0)
528      {
529          if((ssize_t) RunCountMasked>j)
530            {    /*Wrong Data*/
531              RunCountMasked=(unsigned char) j;
532              if(j==0)
533                {
534                  break;
535                }
536            }
537
538          if((int) RunCount>0x80)
539            {
540              RunValue=(unsigned char) ReadBlobByte(image);
541              (void) ResetMagickMemory(ptrB,(int) RunValue,(size_t) RunCountMasked);
542            }
543          else {
544            (void) ReadBlob(image,(size_t) RunCountMasked,ptrB);
545          }
546
547          ptrB+=(int) RunCountMasked;
548          j-=(int) RunCountMasked;
549
550          if (EOFBlob(image) != MagickFalse) goto Finish;  /* wrong data: unexpected eof in line */
551          RunCount=(unsigned char) ReadBlobByte(image);
552          RunCountMasked=RunCount & 0x7F;
553        }
554
555      InsertRow(image,depth,BImgBuff,i,exception);
556    }
557  (void) SyncImage(image,exception);
558
559
560  /*detect monochrome image*/
561
562  if(palette==NULL)
563    {    /*attempt to detect binary (black&white) images*/
564      if ((image->storage_class == PseudoClass) &&
565          (SetImageGray(image,exception) != MagickFalse))
566        {
567          if(GetCutColors(image,exception)==2)
568            {
569              for (i=0; i < (ssize_t)image->colors; i++)
570                {
571                  register Quantum
572                    sample;
573                  sample=ScaleCharToQuantum((unsigned char) i);
574                  if(image->colormap[i].red!=sample) goto Finish;
575                  if(image->colormap[i].green!=sample) goto Finish;
576                  if(image->colormap[i].blue!=sample) goto Finish;
577                }
578
579              image->colormap[1].red=image->colormap[1].green=
580                image->colormap[1].blue=QuantumRange;
581              for (i=0; i < (ssize_t)image->rows; i++)
582                {
583                  q=QueueAuthenticPixels(image,0,i,image->columns,1,exception);
584                  for (j=0; j < (ssize_t)image->columns; j++)
585                    {
586                      if (GetPixelRed(image,q) == ScaleCharToQuantum(1))
587                        {
588                          SetPixelRed(image,QuantumRange,q);
589                          SetPixelGreen(image,QuantumRange,q);
590                          SetPixelBlue(image,QuantumRange,q);
591                        }
592                      q+=GetPixelChannels(image);
593                    }
594                  if (SyncAuthenticPixels(image,exception) == MagickFalse) goto Finish;
595                }
596            }
597        }
598    }
599
600 Finish:
601  if (BImgBuff != NULL)
602    BImgBuff=(unsigned char *) RelinquishMagickMemory(BImgBuff);
603  if (palette != NULL)
604    palette=DestroyImage(palette);
605  if (clone_info != NULL)
606    clone_info=DestroyImageInfo(clone_info);
607  if (EOFBlob(image) != MagickFalse)
608    ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
609      image->filename);
610  (void) CloseBlob(image);
611  return(GetFirstImageInList(image));
612}
613
614/*
615%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
616%                                                                             %
617%                                                                             %
618%                                                                             %
619%   R e g i s t e r C U T I m a g e                                           %
620%                                                                             %
621%                                                                             %
622%                                                                             %
623%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
624%
625%  RegisterCUTImage() adds attributes for the CUT image format to
626%  the list of supported formats.  The attributes include the image format
627%  tag, a method to read and/or write the format, whether the format
628%  supports the saving of more than one frame to the same file or blob,
629%  whether the format supports native in-memory I/O, and a brief
630%  description of the format.
631%
632%  The format of the RegisterCUTImage method is:
633%
634%      size_t RegisterCUTImage(void)
635%
636*/
637ModuleExport size_t RegisterCUTImage(void)
638{
639  MagickInfo
640    *entry;
641
642  entry=AcquireMagickInfo("CUT","CUT","DR Halo");
643  entry->decoder=(DecodeImageHandler *) ReadCUTImage;
644  entry->flags|=CoderSeekableStreamFlag;
645  (void) RegisterMagickInfo(entry);
646  return(MagickImageCoderSignature);
647}
648
649/*
650%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
651%                                                                             %
652%                                                                             %
653%                                                                             %
654%   U n r e g i s t e r C U T I m a g e                                       %
655%                                                                             %
656%                                                                             %
657%                                                                             %
658%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
659%
660%  UnregisterCUTImage() removes format registrations made by the
661%  CUT module from the list of supported formats.
662%
663%  The format of the UnregisterCUTImage method is:
664%
665%      UnregisterCUTImage(void)
666%
667*/
668ModuleExport void UnregisterCUTImage(void)
669{
670  (void) UnregisterMagickInfo("CUT");
671}
672