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