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