cut.c revision fa18e626bfb0f8953c8393f3252cbc3f0e07c80c
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) goto Finish;
377
378  /* ----- Do something with palette ----- */
379  if ((clone_info=CloneImageInfo(image_info)) == NULL) goto NoPalette;
380
381
382  i=(ssize_t) strlen(clone_info->filename);
383  j=i;
384  while(--i>0)
385    {
386      if(clone_info->filename[i]=='.')
387        {
388          break;
389        }
390      if(clone_info->filename[i]=='/' || clone_info->filename[i]=='\\' ||
391         clone_info->filename[i]==':' )
392        {
393          i=j;
394          break;
395        }
396    }
397
398  (void) CopyMagickString(clone_info->filename+i,".PAL",(size_t)
399    (MaxTextExtent-i));
400  if((clone_info->file=fopen_utf8(clone_info->filename,"rb"))==NULL)
401    {
402      (void) CopyMagickString(clone_info->filename+i,".pal",(size_t)
403        (MaxTextExtent-i));
404      if((clone_info->file=fopen_utf8(clone_info->filename,"rb"))==NULL)
405        {
406          clone_info->filename[i]='\0';
407          if((clone_info->file=fopen_utf8(clone_info->filename,"rb"))==NULL)
408            {
409              clone_info=DestroyImageInfo(clone_info);
410              clone_info=NULL;
411              goto NoPalette;
412            }
413        }
414    }
415
416  if( (palette=AcquireImage(clone_info,exception))==NULL ) goto NoPalette;
417  status=OpenBlob(clone_info,palette,ReadBinaryBlobMode,exception);
418  if (status == MagickFalse)
419    {
420    ErasePalette:
421      palette=DestroyImage(palette);
422      palette=NULL;
423      goto NoPalette;
424    }
425
426
427  if(palette!=NULL)
428    {
429      (void) ReadBlob(palette,2,(unsigned char *) PalHeader.FileId);
430      if(strncmp(PalHeader.FileId,"AH",2) != 0) goto ErasePalette;
431      PalHeader.Version=ReadBlobLSBShort(palette);
432      PalHeader.Size=ReadBlobLSBShort(palette);
433      PalHeader.FileType=(char) ReadBlobByte(palette);
434      PalHeader.SubType=(char) ReadBlobByte(palette);
435      PalHeader.BoardID=ReadBlobLSBShort(palette);
436      PalHeader.GraphicsMode=ReadBlobLSBShort(palette);
437      PalHeader.MaxIndex=ReadBlobLSBShort(palette);
438      PalHeader.MaxRed=ReadBlobLSBShort(palette);
439      PalHeader.MaxGreen=ReadBlobLSBShort(palette);
440      PalHeader.MaxBlue=ReadBlobLSBShort(palette);
441      (void) ReadBlob(palette,20,(unsigned char *) PalHeader.PaletteId);
442
443      if(PalHeader.MaxIndex<1) goto ErasePalette;
444      image->colors=PalHeader.MaxIndex+1;
445      if (AcquireImageColormap(image,image->colors,exception) == MagickFalse) goto NoMemory;
446
447      if(PalHeader.MaxRed==0) PalHeader.MaxRed=(unsigned int) QuantumRange;  /*avoid division by 0*/
448      if(PalHeader.MaxGreen==0) PalHeader.MaxGreen=(unsigned int) QuantumRange;
449      if(PalHeader.MaxBlue==0) PalHeader.MaxBlue=(unsigned int) QuantumRange;
450
451      for(i=0;i<=(int) PalHeader.MaxIndex;i++)
452        {      /*this may be wrong- I don't know why is palette such strange*/
453          j=(ssize_t) TellBlob(palette);
454          if((j % 512)>512-6)
455            {
456              j=((j / 512)+1)*512;
457              offset=SeekBlob(palette,j,SEEK_SET);
458              if (offset < 0)
459                ThrowReaderException(CorruptImageError,"ImproperImageHeader");
460            }
461          image->colormap[i].red=(Quantum) ReadBlobLSBShort(palette);
462          if (QuantumRange != (Quantum) PalHeader.MaxRed)
463            {
464              image->colormap[i].red=ClampToQuantum(((double)
465                image->colormap[i].red*QuantumRange+(PalHeader.MaxRed>>1))/
466                PalHeader.MaxRed);
467            }
468          image->colormap[i].green=(Quantum) ReadBlobLSBShort(palette);
469          if (QuantumRange != (Quantum) PalHeader.MaxGreen)
470            {
471              image->colormap[i].green=ClampToQuantum
472                (((double) image->colormap[i].green*QuantumRange+(PalHeader.MaxGreen>>1))/PalHeader.MaxGreen);
473            }
474          image->colormap[i].blue=(Quantum) ReadBlobLSBShort(palette);
475          if (QuantumRange != (Quantum) PalHeader.MaxBlue)
476            {
477              image->colormap[i].blue=ClampToQuantum
478                (((double)image->colormap[i].blue*QuantumRange+(PalHeader.MaxBlue>>1))/PalHeader.MaxBlue);
479            }
480
481        }
482    }
483
484
485
486 NoPalette:
487  if(palette==NULL)
488    {
489
490      image->colors=256;
491      if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
492        {
493        NoMemory:
494          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
495            }
496
497      for (i=0; i < (ssize_t)image->colors; i++)
498        {
499          image->colormap[i].red=ScaleCharToQuantum((unsigned char) i);
500          image->colormap[i].green=ScaleCharToQuantum((unsigned char) i);
501          image->colormap[i].blue=ScaleCharToQuantum((unsigned char) i);
502        }
503    }
504
505
506  /* ----- Load RLE compressed raster ----- */
507  BImgBuff=(unsigned char *) AcquireQuantumMemory((size_t) ldblk,
508    sizeof(*BImgBuff));  /*Ldblk was set in the check phase*/
509  if(BImgBuff==NULL) goto NoMemory;
510
511  offset=SeekBlob(image,6 /*sizeof(Header)*/,SEEK_SET);
512  if (offset < 0)
513    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
514  for (i=0; i < (int) Header.Height; i++)
515  {
516      EncodedByte=ReadBlobLSBShort(image);
517
518      ptrB=BImgBuff;
519      j=ldblk;
520
521      RunCount=(unsigned char) ReadBlobByte(image);
522      RunCountMasked=RunCount & 0x7F;
523
524      while ((int) RunCountMasked != 0)
525      {
526          if((ssize_t) RunCountMasked>j)
527            {    /*Wrong Data*/
528              RunCountMasked=(unsigned char) j;
529              if(j==0)
530                {
531                  break;
532                }
533            }
534
535          if((int) RunCount>0x80)
536            {
537              RunValue=(unsigned char) ReadBlobByte(image);
538              (void) ResetMagickMemory(ptrB,(int) RunValue,(size_t) RunCountMasked);
539            }
540          else {
541            (void) ReadBlob(image,(size_t) RunCountMasked,ptrB);
542          }
543
544          ptrB+=(int) RunCountMasked;
545          j-=(int) RunCountMasked;
546
547          if (EOFBlob(image) != MagickFalse) goto Finish;  /* wrong data: unexpected eof in line */
548          RunCount=(unsigned char) ReadBlobByte(image);
549          RunCountMasked=RunCount & 0x7F;
550        }
551
552      InsertRow(image,depth,BImgBuff,i,exception);
553    }
554  (void) SyncImage(image,exception);
555
556
557  /*detect monochrome image*/
558
559  if(palette==NULL)
560    {    /*attempt to detect binary (black&white) images*/
561      if ((image->storage_class == PseudoClass) &&
562          (IsImageGray(image,exception) != MagickFalse))
563        {
564          if(GetCutColors(image,exception)==2)
565            {
566              for (i=0; i < (ssize_t)image->colors; i++)
567                {
568                  register Quantum
569                    sample;
570                  sample=ScaleCharToQuantum((unsigned char) i);
571                  if(image->colormap[i].red!=sample) goto Finish;
572                  if(image->colormap[i].green!=sample) goto Finish;
573                  if(image->colormap[i].blue!=sample) goto Finish;
574                }
575
576              image->colormap[1].red=image->colormap[1].green=
577                image->colormap[1].blue=QuantumRange;
578              for (i=0; i < (ssize_t)image->rows; i++)
579                {
580                  q=QueueAuthenticPixels(image,0,i,image->columns,1,exception);
581                  for (j=0; j < (ssize_t)image->columns; j++)
582                    {
583                      if (GetPixelRed(image,q) == ScaleCharToQuantum(1))
584                        {
585                          SetPixelRed(image,QuantumRange,q);
586                          SetPixelGreen(image,QuantumRange,q);
587                          SetPixelBlue(image,QuantumRange,q);
588                        }
589                      q+=GetPixelChannels(image);
590                    }
591                  if (SyncAuthenticPixels(image,exception) == MagickFalse) goto Finish;
592                }
593            }
594        }
595    }
596
597 Finish:
598  if (BImgBuff != NULL)
599    BImgBuff=(unsigned char *) RelinquishMagickMemory(BImgBuff);
600  if (palette != NULL)
601    palette=DestroyImage(palette);
602  if (clone_info != NULL)
603    clone_info=DestroyImageInfo(clone_info);
604  if (EOFBlob(image) != MagickFalse)
605    ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
606      image->filename);
607  (void) CloseBlob(image);
608  return(GetFirstImageInList(image));
609}
610
611/*
612%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
613%                                                                             %
614%                                                                             %
615%                                                                             %
616%   R e g i s t e r C U T I m a g e                                           %
617%                                                                             %
618%                                                                             %
619%                                                                             %
620%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
621%
622%  RegisterCUTImage() adds attributes for the CUT image format to
623%  the list of supported formats.  The attributes include the image format
624%  tag, a method to read and/or write the format, whether the format
625%  supports the saving of more than one frame to the same file or blob,
626%  whether the format supports native in-memory I/O, and a brief
627%  description of the format.
628%
629%  The format of the RegisterCUTImage method is:
630%
631%      size_t RegisterCUTImage(void)
632%
633*/
634ModuleExport size_t RegisterCUTImage(void)
635{
636  MagickInfo
637    *entry;
638
639  entry=SetMagickInfo("CUT");
640  entry->decoder=(DecodeImageHandler *) ReadCUTImage;
641  entry->seekable_stream=MagickTrue;
642  entry->description=ConstantString("DR Halo");
643  entry->module=ConstantString("CUT");
644  (void) RegisterMagickInfo(entry);
645  return(MagickImageCoderSignature);
646}
647
648/*
649%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
650%                                                                             %
651%                                                                             %
652%                                                                             %
653%   U n r e g i s t e r C U T I m a g e                                       %
654%                                                                             %
655%                                                                             %
656%                                                                             %
657%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
658%
659%  UnregisterCUTImage() removes format registrations made by the
660%  CUT module from the list of supported formats.
661%
662%  The format of the UnregisterCUTImage method is:
663%
664%      UnregisterCUTImage(void)
665%
666*/
667ModuleExport void UnregisterCUTImage(void)
668{
669  (void) UnregisterMagickInfo("CUT");
670}
671