/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d G R A D I E N T I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadGRADIENTImage creates a gradient image and initializes it to % the color range as specified by the filename. It allocates the memory % necessary for the new Image structure and returns a pointer to the new % image. % % The format of the ReadGRADIENTImage method is: % % Image *ReadGRADIENTImage(const ImageInfo *image_info, % ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % */ static Image *ReadGRADIENTImage(const ImageInfo *image_info, ExceptionInfo *exception) { char colorname[MaxTextExtent]; MagickBooleanType icc_color, status; MagickPixelPacket start_pixel, stop_pixel; PixelPacket start_color, stop_color; Image *image; /* Initialize Image structure. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info); if ((image->columns == 0) || (image->rows == 0)) ThrowReaderException(OptionError,"MustSpecifyImageSize"); (void) SetImageOpacity(image,(Quantum) TransparentOpacity); (void) CopyMagickString(image->filename,image_info->filename,MaxTextExtent); (void) CopyMagickString(colorname,image_info->filename,MaxTextExtent); (void) sscanf(image_info->filename,"%[^-]",colorname); icc_color=MagickFalse; if (LocaleCompare(colorname,"icc") == 0) { (void) ConcatenateMagickString(colorname,"-",MaxTextExtent); (void) sscanf(image_info->filename,"%*[^-]-%[^-]",colorname+4); icc_color=MagickTrue; } if (QueryColorDatabase(colorname,&start_color,exception) == MagickFalse) { image=DestroyImage(image); return((Image *) NULL); } (void) QueryMagickColor(colorname,&start_pixel,exception); (void) CopyMagickString(colorname,"white",MaxTextExtent); if (GetPixelLuma(image,&start_color) > (QuantumRange/2)) (void) CopyMagickString(colorname,"black",MaxTextExtent); if (icc_color == MagickFalse) (void) sscanf(image_info->filename,"%*[^-]-%s",colorname); else (void) sscanf(image_info->filename,"%*[^-]-%*[^-]-%s",colorname); if (QueryColorDatabase(colorname,&stop_color,exception) == MagickFalse) { image=DestroyImage(image); return((Image *) NULL); } (void) QueryMagickColor(colorname,&stop_pixel,exception); (void) SetImageColorspace(image,start_pixel.colorspace); status=GradientImage(image,LocaleCompare(image_info->magick,"GRADIENT") == 0 ? LinearGradient : RadialGradient,PadSpread,&start_color,&stop_color); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } if ((start_pixel.matte == MagickFalse) && (stop_pixel.matte == MagickFalse)) (void) SetImageAlphaChannel(image,DeactivateAlphaChannel); return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d X C I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadXCImage creates a constant image and initializes it to the % X server color as specified by the filename. It allocates the memory % necessary for the new Image structure and returns a pointer to the new % image. % % The format of the ReadXCImage method is: % % Image *ReadXCImage(const ImageInfo *image_info,ExceptionInfo *exception) % % A description of each parameter follows: % % o image: The image. % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % */ static Image *ReadXCImage(const ImageInfo *image_info,ExceptionInfo *exception) { Image *image; IndexPacket *indexes; MagickBooleanType status; MagickPixelPacket color; long y; register long x; register PixelPacket *q; /* Initialize Image structure. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AllocateImage(image_info); if (image->columns == 0) image->columns=1; if (image->rows == 0) image->rows=1; (void) CopyMagickString(image->filename,image_info->filename,MaxTextExtent); status=QueryMagickColor((char *) image_info->filename,&color,exception); if (status == MagickFalse) { image=DestroyImage(image); return((Image *) NULL); } image->colorspace=color.colorspace; image->matte=color.matte; if ((image->colorspace == RGBColorspace) && (image->matte == MagickFalse)) { if (AllocateImageColormap(image,1) == MagickFalse) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); (void) QueryColorDatabase((char *) image_info->filename, &image->background_color,exception); image->colormap[0]=image->background_color; color.index=0.0; } if (SetImageExtent(image,0,0) == MagickFalse) { InheritException(exception,&image->exception); return(DestroyImageList(image)); } for (y=0; y < (long) image->rows; y++) { q=GetImagePixels(image,0,y,image->columns,1); if (q == (PixelPacket *) NULL) break; indexes=GetIndexes(image); for (x=0; x < (long) image->columns; x++) { q->red=RoundToQuantum(color.red); q->green=RoundToQuantum(color.green); q->blue=RoundToQuantum(color.blue); if (image->matte) q->opacity=RoundToQuantum(color.opacity); if ((image->storage_class == PseudoClass) || (image->colorspace == CMYKColorspace)) indexes[x]=(IndexPacket) RoundToQuantum(color.index); q++; } if (SyncImagePixels(image) == MagickFalse) break; } return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d X C I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadXCImage creates a constant image and initializes it to the % X server color as specified by the filename. It allocates the memory % necessary for the new Image structure and returns a pointer to the new % image. % % The format of the ReadXCImage method is: % % Image *ReadXCImage(const ImageInfo *image_info,ExceptionInfo *exception) % % A description of each parameter follows: % % o image: The image. % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % */ static Image *ReadXCImage(const ImageInfo *image_info,ExceptionInfo *exception) { Image *image; IndexPacket index, *indexes; MagickBooleanType status; MagickPixelPacket color; ssize_t y; PixelPacket pixel; register ssize_t x; register PixelPacket *q; /* Initialize Image structure. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info); if (image->columns == 0) image->columns=1; if (image->rows == 0) image->rows=1; (void) CopyMagickString(image->filename,image_info->filename,MaxTextExtent); status=QueryMagickColor((char *) image_info->filename,&color,exception); if (status == MagickFalse) { image=DestroyImage(image); return((Image *) NULL); } image->colorspace=color.colorspace; image->matte=color.matte; index=0; SetPixelPacket(image,&color,&pixel,&index); for (y=0; y < (ssize_t) image->rows; y++) { q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) *q++=pixel; if (image->colorspace == CMYKColorspace) { indexes=GetAuthenticIndexQueue(image); for (x=0; x < (ssize_t) image->columns; x++) indexes[x]=index; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } return(GetFirstImageInList(image)); }
MagickExport Image *CompareImageChannels(Image *image, const Image *reconstruct_image,const ChannelType channel, const MetricType metric,double *distortion,ExceptionInfo *exception) { Image *difference_image; long y; MagickPixelPacket composite, red, source, white; MagickStatusType difference; register const IndexPacket *indexes, *reconstruct_indexes; register const PixelPacket *p, *q; register IndexPacket *difference_indexes; register long x; register PixelPacket *r; ViewInfo *difference_view, *image_view, *reconstruct_view; assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(reconstruct_image != (const Image *) NULL); assert(reconstruct_image->signature == MagickSignature); assert(distortion != (double *) NULL); *distortion=0.0; if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); if ((reconstruct_image->columns != image->columns) || (reconstruct_image->rows != image->rows)) ThrowImageException(ImageError,"ImageSizeDiffers"); difference_image=CloneImage(image,image->columns,image->rows,MagickTrue, exception); if (difference_image == (Image *) NULL) return((Image *) NULL); if (SetImageStorageClass(difference_image,DirectClass) == MagickFalse) { InheritException(exception,&difference_image->exception); difference_image=DestroyImage(difference_image); return((Image *) NULL); } (void) QueryMagickColor("#f1001e",&red,exception); (void) QueryMagickColor("#ffffff",&white,exception); if (difference_image->colorspace == CMYKColorspace) { ConvertRGBToCMYK(&red); ConvertRGBToCMYK(&white); } /* Generate difference image. */ GetMagickPixelPacket(reconstruct_image,&source); GetMagickPixelPacket(difference_image,&composite); image_view=OpenCacheView(image); reconstruct_view=OpenCacheView(reconstruct_image); difference_view=OpenCacheView(difference_image); for (y=0; y < (long) image->rows; y++) { p=AcquireCacheViewPixels(image_view,0,y,image->columns,1,exception); q=AcquireCacheViewPixels(reconstruct_view,0,y,reconstruct_image->columns,1, exception); r=SetCacheView(difference_view,0,y,difference_image->columns,1); if ((p == (const PixelPacket *) NULL) || (q == (const PixelPacket *) NULL) || (r == (PixelPacket *) NULL)) break; indexes=AcquireCacheViewIndexes(image_view); reconstruct_indexes=AcquireCacheViewIndexes(reconstruct_view); difference_indexes=GetCacheViewIndexes(difference_view); for (x=0; x < (long) image->columns; x++) { difference=MagickFalse; if ((channel & RedChannel) != 0) if (p->red != q->red) difference=MagickTrue; if ((channel & GreenChannel) != 0) if (p->green != q->green) difference=MagickTrue; if ((channel & BlueChannel) != 0) if (p->blue != q->blue) difference=MagickTrue; if ((channel & OpacityChannel) != 0) if (p->opacity != q->opacity) difference=MagickTrue; if (((channel & IndexChannel) != 0) && (image->colorspace == CMYKColorspace) && (reconstruct_image->colorspace == CMYKColorspace)) if (indexes[x] != reconstruct_indexes[x]) difference=MagickTrue; SetMagickPixelPacket(reconstruct_image,q,reconstruct_indexes+x,&source); if (difference != MagickFalse) MagickPixelCompositeOver(&source,7.5*QuantumRange/10.0,&red, (MagickRealType) red.opacity,&composite); else MagickPixelCompositeOver(&source,7.5*QuantumRange/10.0,&white, (MagickRealType) white.opacity,&composite); SetPixelPacket(difference_image,&composite,r,difference_indexes+x); p++; q++; r++; } if (SyncCacheView(difference_view) == MagickFalse) break; } difference_view=CloseCacheView(difference_view); reconstruct_view=CloseCacheView(reconstruct_view); image_view=CloseCacheView(image_view); (void) GetImageChannelDistortion(image,reconstruct_image,channel,metric, distortion,exception); return(difference_image); }