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