]> 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 "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 \f
73 typedef struct
74 {
75   unsigned Width;
76   unsigned Height;
77   unsigned Reserved;
78 } CUTHeader;
79
80 typedef struct
81 {
82   char FileId[2];
83   unsigned Version;
84   unsigned Size;
85   char FileType;
86   char SubType;
87   unsigned BoardID;
88   unsigned GraphicsMode;
89   unsigned MaxIndex;
90   unsigned MaxRed;
91   unsigned MaxGreen;
92   unsigned MaxBlue;
93   char PaletteId[20];
94 } CUTPalHeader;
95
96 \f
97 static void InsertRow(ssize_t depth,unsigned char *p,ssize_t y,Image *image)
98 {
99   ExceptionInfo
100     *exception;
101
102   size_t bit; ssize_t x;
103   register Quantum *q;
104   Quantum index;
105
106   index=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 == (const Quantum *) NULL)
114           break;
115         for (x=0; x < ((ssize_t) image->columns-7); x+=8)
116         {
117           for (bit=0; bit < 8; bit++)
118           {
119             index=(Quantum) ((((*p) & (0x80 >> bit)) != 0) ? 0x01 : 0x00);
120             SetPixelIndex(image,index,q);
121             q+=GetPixelChannels(image);
122           }
123           p++;
124         }
125         if ((image->columns % 8) != 0)
126           {
127             for (bit=0; bit < (image->columns % 8); bit++)
128               {
129                 index=(Quantum) ((((*p) & (0x80 >> bit)) != 0) ? 0x01 : 0x00);
130                 SetPixelIndex(image,index,q);
131                 q+=GetPixelChannels(image);
132               }
133             p++;
134           }
135         if (SyncAuthenticPixels(image,exception) == MagickFalse)
136           break;
137         break;
138       }
139     case 2:  /* Convert PseudoColor scanline. */
140       {
141         q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
142         if (q == (const Quantum *) NULL)
143           break;
144         for (x=0; x < ((ssize_t) image->columns-1); x+=2)
145         {
146           index=ConstrainColormapIndex(image,(*p >> 6) & 0x3);
147           SetPixelIndex(image,index,q);
148           q+=GetPixelChannels(image);
149           index=ConstrainColormapIndex(image,(*p >> 4) & 0x3);
150           SetPixelIndex(image,index,q);
151           q+=GetPixelChannels(image);
152           index=ConstrainColormapIndex(image,(*p >> 2) & 0x3);
153           SetPixelIndex(image,index,q);
154           q+=GetPixelChannels(image);
155           index=ConstrainColormapIndex(image,(*p) & 0x3);
156           SetPixelIndex(image,index,q);
157           q+=GetPixelChannels(image);
158           p++;
159         }
160         if ((image->columns % 4) != 0)
161           {
162             index=ConstrainColormapIndex(image,(*p >> 6) & 0x3);
163             SetPixelIndex(image,index,q);
164             q+=GetPixelChannels(image);
165             if ((image->columns % 4) >= 1)
166
167               {
168                 index=ConstrainColormapIndex(image,(*p >> 4) & 0x3);
169                 SetPixelIndex(image,index,q);
170                 q+=GetPixelChannels(image);
171                 if ((image->columns % 4) >= 2)
172
173                   {
174                     index=ConstrainColormapIndex(image,(*p >> 2) & 0x3);
175                     SetPixelIndex(image,index,q);
176                     q+=GetPixelChannels(image);
177                   }
178               }
179             p++;
180           }
181         if (SyncAuthenticPixels(image,exception) == MagickFalse)
182           break;
183         break;
184       }
185
186     case 4:  /* Convert PseudoColor scanline. */
187       {
188         q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
189         if (q == (const Quantum *) NULL)
190           break;
191         for (x=0; x < ((ssize_t) image->columns-1); x+=2)
192         {
193             index=ConstrainColormapIndex(image,(*p >> 4) & 0xf);
194             SetPixelIndex(image,index,q);
195             q+=GetPixelChannels(image);
196             index=ConstrainColormapIndex(image,(*p) & 0xf);
197             SetPixelIndex(image,index,q);
198             q+=GetPixelChannels(image);
199             p++;
200           }
201         if ((image->columns % 2) != 0)
202           {
203             index=ConstrainColormapIndex(image,(*p >> 4) & 0xf);
204             SetPixelIndex(image,index,q);
205             q+=GetPixelChannels(image);
206             p++;
207           }
208         if (SyncAuthenticPixels(image,exception) == MagickFalse)
209           break;
210         break;
211       }
212     case 8: /* Convert PseudoColor scanline. */
213       {
214         q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
215         if (q == (const Quantum *) NULL) break;
216         for (x=0; x < (ssize_t) image->columns; x++)
217         {
218           index=ConstrainColormapIndex(image,*p);
219           SetPixelIndex(image,index,q);
220           p++;
221           q+=GetPixelChannels(image);
222         }
223         if (SyncAuthenticPixels(image,exception) == MagickFalse)
224           break;
225       }
226       break;
227
228     }
229 }
230
231 /*
232    Compute the number of colors in Grayed R[i]=G[i]=B[i] image
233 */
234 static int GetCutColors(Image *image)
235 {
236   ExceptionInfo
237     *exception;
238
239   Quantum
240     intensity,
241     scale_intensity;
242
243   register Quantum
244     *q;
245
246   ssize_t
247     x,
248     y;
249
250   exception=(&image->exception);
251   intensity=0;
252   scale_intensity=ScaleCharToQuantum(16);
253   for (y=0; y < (ssize_t) image->rows; y++)
254   {
255     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
256     for (x=0; x < (ssize_t) image->columns; x++)
257     {
258       if (intensity < GetPixelRed(image,q))
259         intensity=GetPixelRed(image,q);
260       if (intensity >= scale_intensity)
261         return(255);
262       q+=GetPixelChannels(image);
263     }
264   }
265   if (intensity < ScaleCharToQuantum(2))
266     return(2);
267   if (intensity < ScaleCharToQuantum(16))
268     return(16);
269   return((int) intensity);
270 }
271 \f
272 /*
273 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
274 %                                                                             %
275 %                                                                             %
276 %                                                                             %
277 %   R e a d C U T I m a g e                                                   %
278 %                                                                             %
279 %                                                                             %
280 %                                                                             %
281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
282 %
283 %  ReadCUTImage() reads an CUT X image file and returns it.  It
284 %  allocates the memory necessary for the new Image structure and returns a
285 %  pointer to the new image.
286 %
287 %  The format of the ReadCUTImage method is:
288 %
289 %      Image *ReadCUTImage(const ImageInfo *image_info,ExceptionInfo *exception)
290 %
291 %  A description of each parameter follows:
292 %
293 %    o image_info: the image info.
294 %
295 %    o exception: return any errors or warnings in this structure.
296 %
297 */
298 static Image *ReadCUTImage(const ImageInfo *image_info,ExceptionInfo *exception)
299 {
300   Image *image,*palette;
301   ImageInfo *clone_info;
302   MagickBooleanType status;
303
304   MagickOffsetType
305     offset;
306
307   size_t EncodedByte;
308   unsigned char RunCount,RunValue,RunCountMasked;
309   CUTHeader  Header;
310   CUTPalHeader PalHeader;
311   ssize_t depth;
312   ssize_t i,j;
313   ssize_t ldblk;
314   unsigned char *BImgBuff=NULL,*ptrB;
315   register Quantum *q;
316
317   /*
318     Open image file.
319   */
320   assert(image_info != (const ImageInfo *) NULL);
321   assert(image_info->signature == MagickSignature);
322   if (image_info->debug != MagickFalse)
323     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
324       image_info->filename);
325   assert(exception != (ExceptionInfo *) NULL);
326   assert(exception->signature == MagickSignature);
327   image=AcquireImage(image_info);
328   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
329   if (status == MagickFalse)
330     {
331       image=DestroyImageList(image);
332       return((Image *) NULL);
333     }
334   /*
335     Read CUT image.
336   */
337   palette=NULL;
338   clone_info=NULL;
339   Header.Width=ReadBlobLSBShort(image);
340   Header.Height=ReadBlobLSBShort(image);
341   Header.Reserved=ReadBlobLSBShort(image);
342
343   if (Header.Width==0 || Header.Height==0 || Header.Reserved!=0)
344     CUT_KO:  ThrowReaderException(CorruptImageError,"ImproperImageHeader");
345
346   /*---This code checks first line of image---*/
347   EncodedByte=ReadBlobLSBShort(image);
348   RunCount=(unsigned char) ReadBlobByte(image);
349   RunCountMasked=RunCount & 0x7F;
350   ldblk=0;
351   while((int) RunCountMasked!=0)  /*end of line?*/
352     {
353       i=1;
354       if((int) RunCount<0x80) i=(ssize_t) RunCountMasked;
355       offset=SeekBlob(image,TellBlob(image)+i,SEEK_SET);
356       if (offset < 0)
357         ThrowReaderException(CorruptImageError,"ImproperImageHeader");
358       if(EOFBlob(image) != MagickFalse) goto CUT_KO;  /*wrong data*/
359       EncodedByte-=i+1;
360       ldblk+=(ssize_t) RunCountMasked;
361
362       RunCount=(unsigned char) ReadBlobByte(image);
363       if(EOFBlob(image) != MagickFalse)  goto CUT_KO;  /*wrong data: unexpected eof in line*/
364       RunCountMasked=RunCount & 0x7F;
365     }
366   if(EncodedByte!=1) goto CUT_KO;  /*wrong data: size incorrect*/
367   i=0;        /*guess a number of bit planes*/
368   if(ldblk==(int) Header.Width)   i=8;
369   if(2*ldblk==(int) Header.Width) i=4;
370   if(8*ldblk==(int) Header.Width) i=1;
371   if(i==0) goto CUT_KO;    /*wrong data: incorrect bit planes*/
372   depth=i;
373
374   image->columns=Header.Width;
375   image->rows=Header.Height;
376   image->depth=8;
377   image->colors=(size_t) (GetQuantumRange(1UL*i)+1);
378
379   if (image_info->ping) goto Finish;
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=OpenMagickStream(clone_info->filename,"rb"))==NULL)
404     {
405       (void) CopyMagickString(clone_info->filename+i,".pal",(size_t)
406         (MaxTextExtent-i));
407       if((clone_info->file=OpenMagickStream(clone_info->filename,"rb"))==NULL)
408         {
409           clone_info->filename[i]='\0';
410           if((clone_info->file=OpenMagickStream(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))==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) == 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) == 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(depth,BImgBuff,i,image);
556     }
557   (void) SyncImage(image);
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           (IsImageGray(image,&image->exception) != MagickFalse))
566         {
567           if(GetCutColors(image)==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=(Quantum) 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 \f
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 */
637 ModuleExport size_t RegisterCUTImage(void)
638 {
639   MagickInfo
640     *entry;
641
642   entry=SetMagickInfo("CUT");
643   entry->decoder=(DecodeImageHandler *) ReadCUTImage;
644   entry->seekable_stream=MagickTrue;
645   entry->description=ConstantString("DR Halo");
646   entry->module=ConstantString("CUT");
647   (void) RegisterMagickInfo(entry);
648   return(MagickImageCoderSignature);
649 }
650 \f
651 /*
652 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
653 %                                                                             %
654 %                                                                             %
655 %                                                                             %
656 %   U n r e g i s t e r C U T I m a g e                                       %
657 %                                                                             %
658 %                                                                             %
659 %                                                                             %
660 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
661 %
662 %  UnregisterCUTImage() removes format registrations made by the
663 %  CUT module from the list of supported formats.
664 %
665 %  The format of the UnregisterCUTImage method is:
666 %
667 %      UnregisterCUTImage(void)
668 %
669 */
670 ModuleExport void UnregisterCUTImage(void)
671 {
672   (void) UnregisterMagickInfo("CUT");
673 }