X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=MagickCore%2Fcolor.c;h=432ad6d7a17ff070350e513a1cc13804db10f3af;hb=45ef08fd6a09813e4a8f5ddadf85ba9e0ec2cdc7;hp=81a2ead58ed09089954f51d832e37a7343d060fa;hpb=c7b79fc84ba64846c11bcfffeb38ddf81ec806f9;p=imagemagick diff --git a/MagickCore/color.c b/MagickCore/color.c index 81a2ead58..432ad6d7a 100644 --- a/MagickCore/color.c +++ b/MagickCore/color.c @@ -16,7 +16,7 @@ % July 1992 % % % % % -% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization % +% Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization % % dedicated to making software imaging solutions freely available. % % % % You may not use this file except in compliance with the License. You may % @@ -52,6 +52,7 @@ #include "MagickCore/exception.h" #include "MagickCore/exception-private.h" #include "MagickCore/gem.h" +#include "MagickCore/gem-private.h" #include "MagickCore/geometry.h" #include "MagickCore/image-private.h" #include "MagickCore/memory_.h" @@ -66,6 +67,7 @@ #include "MagickCore/string_.h" #include "MagickCore/token.h" #include "MagickCore/utility.h" +#include "MagickCore/utility-private.h" #include "MagickCore/xml-tree.h" /* @@ -816,7 +818,7 @@ static MagickBooleanType % MagickBooleanType ColorComponentGenesis(void) % */ -MagickExport MagickBooleanType ColorComponentGenesis(void) +MagickPrivate MagickBooleanType ColorComponentGenesis(void) { AcquireSemaphoreInfo(&color_semaphore); return(MagickTrue); @@ -858,7 +860,7 @@ static void *DestroyColorElement(void *color_info) return((void *) NULL); } -MagickExport void ColorComponentTerminus(void) +MagickPrivate void ColorComponentTerminus(void) { if (color_semaphore == (SemaphoreInfo *) NULL) AcquireSemaphoreInfo(&color_semaphore); @@ -886,7 +888,7 @@ MagickExport void ColorComponentTerminus(void) % % The format of the GetColorInfo method is: % -% const PixelPacket *GetColorInfo(const char *name, +% const PixelInfo *GetColorInfo(const char *name, % const ComplianceType compliance,ExceptionInfo *exception) % % A description of each parameter follows: @@ -946,7 +948,7 @@ MagickExport const ColorInfo *GetColorCompliance(const char *name, } if (p == (ColorInfo *) NULL) (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning, - "UnrecognizedColor","`%s'",name); + "UnrecognizedColor","'%s'",name); else (void) InsertValueInLinkedList(color_list,0, RemoveElementByValueFromLinkedList(color_list,p)); @@ -970,7 +972,7 @@ MagickExport const ColorInfo *GetColorCompliance(const char *name, % % The format of the GetColorInfo method is: % -% const PixelPacket *GetColorInfo(const char *name, +% const PixelInfo *GetColorInfo(const char *name, % ExceptionInfo *exception) % % A description of each parameter follows: @@ -1025,7 +1027,7 @@ MagickExport void ConcatenateColorComponent(const PixelInfo *pixel, char text[MaxTextExtent]; - MagickRealType + double color; color=0.0; @@ -1087,8 +1089,10 @@ MagickExport void ConcatenateColorComponent(const PixelInfo *pixel, (void) ConcatenateMagickString(tuple,text,MaxTextExtent); return; } - if ((pixel->colorspace == HSLColorspace) || - (pixel->colorspace == HSBColorspace)) + if ((pixel->colorspace == HCLColorspace) || + (pixel->colorspace == HSBColorspace) || + (pixel->colorspace == HSLColorspace) || + (pixel->colorspace == HWBColorspace)) { (void) FormatLocaleString(text,MaxTextExtent,"%g%%",(double) (100.0*QuantumScale*color)); @@ -1325,38 +1329,38 @@ MagickExport char **GetColorList(const char *pattern, */ static void ConcatentateHexColorComponent(const PixelInfo *pixel, - const ChannelType channel,char *tuple) + const PixelChannel channel,char *tuple) { char component[MaxTextExtent]; - MagickRealType + double color; color=0.0; switch (channel) { - case RedChannel: + case RedPixelChannel: { color=pixel->red; break; } - case GreenChannel: + case GreenPixelChannel: { color=pixel->green; break; } - case BlueChannel: + case BluePixelChannel: { color=pixel->blue; break; } - case AlphaChannel: + case AlphaPixelChannel: { color=pixel->alpha; break; } - case BlackChannel: + case BlackPixelChannel: { color=pixel->black; break; @@ -1408,13 +1412,14 @@ MagickExport void GetColorTuple(const PixelInfo *pixel, Convert pixel to hex color. */ (void) ConcatenateMagickString(tuple,"#",MaxTextExtent); - ConcatentateHexColorComponent(pixel,RedChannel,tuple); - ConcatentateHexColorComponent(pixel,GreenChannel,tuple); - ConcatentateHexColorComponent(pixel,BlueChannel,tuple); + ConcatentateHexColorComponent(pixel,RedPixelChannel,tuple); + ConcatentateHexColorComponent(pixel,GreenPixelChannel,tuple); + ConcatentateHexColorComponent(pixel,BluePixelChannel,tuple); if (pixel->colorspace == CMYKColorspace) - ConcatentateHexColorComponent(pixel,BlackChannel,tuple); - if ((pixel->matte != MagickFalse) && (pixel->alpha != OpaqueAlpha)) - ConcatentateHexColorComponent(pixel,AlphaChannel,tuple); + ConcatentateHexColorComponent(pixel,BlackPixelChannel,tuple); + if ((pixel->alpha_trait == BlendPixelTrait) && + (pixel->alpha != OpaqueAlpha)) + ConcatentateHexColorComponent(pixel,AlphaPixelChannel,tuple); return; } /* @@ -1423,8 +1428,8 @@ MagickExport void GetColorTuple(const PixelInfo *pixel, color=(*pixel); if (color.depth > 8) { -#define SVGCompliant(component) ((MagickRealType) \ - ScaleCharToQuantum(ScaleQuantumToChar(ClampToQuantum(component)))); +#define SVGCompliant(component) ((double) \ + ScaleCharToQuantum(ScaleQuantumToChar(ClampToQuantum(component)))) MagickStatusType status; @@ -1432,32 +1437,42 @@ MagickExport void GetColorTuple(const PixelInfo *pixel, /* SVG requires color depths > 8 expressed as percentages. */ - status=color.red == SVGCompliant(color.red); - status&=color.green == SVGCompliant(color.green); - status&=color.blue == SVGCompliant(color.blue); - if (color.colorspace == CMYKColorspace) - status&=color.black == SVGCompliant(color.black); - if (color.matte != MagickFalse) - status&=color.alpha == SVGCompliant(color.alpha); + status=fabs(color.red-SVGCompliant(color.red)) < MagickEpsilon ? + MagickTrue : MagickFalse; + status&=fabs(color.green-SVGCompliant(color.green)) < MagickEpsilon ? + MagickTrue : MagickFalse; + status&=fabs(color.blue-SVGCompliant(color.blue)) < MagickEpsilon ? + MagickTrue : MagickFalse; + if (color.colorspace-CMYKColorspace) + status&=fabs(color.black-SVGCompliant(color.black)) < MagickEpsilon ? + MagickTrue : MagickFalse; + if (color.alpha_trait == BlendPixelTrait) + status&=fabs(color.alpha-SVGCompliant(color.alpha)) < MagickEpsilon ? + MagickTrue : MagickFalse; if (status != MagickFalse) color.depth=8; } (void) ConcatenateMagickString(tuple,CommandOptionToMnemonic( MagickColorspaceOptions,(ssize_t) color.colorspace),MaxTextExtent); - if (color.matte != MagickFalse) + if (color.alpha_trait == BlendPixelTrait) (void) ConcatenateMagickString(tuple,"a",MaxTextExtent); (void) ConcatenateMagickString(tuple,"(",MaxTextExtent); - ConcatenateColorComponent(&color,RedPixelChannel,SVGCompliance,tuple); - (void) ConcatenateMagickString(tuple,",",MaxTextExtent); - ConcatenateColorComponent(&color,GreenPixelChannel,SVGCompliance,tuple); - (void) ConcatenateMagickString(tuple,",",MaxTextExtent); - ConcatenateColorComponent(&color,BluePixelChannel,SVGCompliance,tuple); + if (color.colorspace == GRAYColorspace) + ConcatenateColorComponent(&color,GrayPixelChannel,SVGCompliance,tuple); + else + { + ConcatenateColorComponent(&color,RedPixelChannel,SVGCompliance,tuple); + (void) ConcatenateMagickString(tuple,",",MaxTextExtent); + ConcatenateColorComponent(&color,GreenPixelChannel,SVGCompliance,tuple); + (void) ConcatenateMagickString(tuple,",",MaxTextExtent); + ConcatenateColorComponent(&color,BluePixelChannel,SVGCompliance,tuple); + } if (color.colorspace == CMYKColorspace) { (void) ConcatenateMagickString(tuple,",",MaxTextExtent); ConcatenateColorComponent(&color,BlackPixelChannel,SVGCompliance,tuple); } - if (color.matte != MagickFalse) + if (color.alpha_trait == BlendPixelTrait) { (void) ConcatenateMagickString(tuple,",",MaxTextExtent); ConcatenateColorComponent(&color,AlphaPixelChannel,SVGCompliance,tuple); @@ -1525,8 +1540,8 @@ static MagickBooleanType InitializeColorList(ExceptionInfo *exception) % % The format of the IsEquivalentAlpha method is: % -% void IsEquivalentAlpha(const Image *image,const PixelPacket *p, -% const PixelPacket *q) +% void IsEquivalentAlpha(const Image *image,const PixelInfo *p, +% const PixelInfo *q) % % A description of each parameter follows: % @@ -1546,21 +1561,21 @@ static inline double MagickMax(const double x,const double y) } MagickExport MagickBooleanType IsEquivalentAlpha(const Image *image, - const PixelPacket *p,const PixelPacket *q) + const PixelInfo *p,const PixelInfo *q) { - MagickRealType + double fuzz, pixel; - register MagickRealType + register double distance; - if (image->matte == MagickFalse) + if (image->alpha_trait != BlendPixelTrait) return(MagickTrue); if (p->alpha == q->alpha) return(MagickTrue); fuzz=MagickMax(image->fuzz,MagickSQ1_2)*MagickMax(image->fuzz,MagickSQ1_2); - pixel=(MagickRealType) p->alpha-(MagickRealType) q->alpha; + pixel=(double) p->alpha-(double) q->alpha; distance=pixel*pixel; if (distance > fuzz) return(MagickFalse); @@ -1644,8 +1659,8 @@ MagickExport MagickBooleanType IsEquivalentImage(const Image *image, status=MagickTrue; GetPixelInfo(image,&pixel); GetPixelInfo(image,&target); - image_view=AcquireCacheView(image); - target_view=AcquireCacheView(target_image); + image_view=AcquireVirtualCacheView(image,exception); + target_view=AcquireVirtualCacheView(target_image,exception); for (y=(*y_offset); y < (ssize_t) image->rows; y++) { for (x=y == 0 ? *x_offset : 0; x < (ssize_t) image->columns; x++) @@ -1655,9 +1670,9 @@ MagickExport MagickBooleanType IsEquivalentImage(const Image *image, for (i=0; i < (ssize_t) target_image->columns; i++) { p=GetCacheViewVirtualPixels(image_view,x+i,y+j,1,1,exception); - SetPixelInfo(image,p,&pixel); + GetPixelInfoPixel(image,p,&pixel); q=GetCacheViewVirtualPixels(target_view,i,j,1,1,exception); - SetPixelInfo(image,q,&target); + GetPixelInfoPixel(image,q,&target); if (IsFuzzyEquivalencePixelInfo(&pixel,&target) == MagickFalse) break; } @@ -1884,7 +1899,7 @@ static MagickBooleanType LoadColorList(const char *xml,const char *filename, { if (depth > 200) (void) ThrowMagickException(exception,GetMagickModule(), - ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token); + ConfigureError,"IncludeElementNestedTooDeeply","'%s'",token); else { char @@ -1931,7 +1946,7 @@ static MagickBooleanType LoadColorList(const char *xml,const char *filename, status=AppendValueToLinkedList(color_list,color_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), - ResourceLimitError,"MemoryAllocationFailed","`%s'", + ResourceLimitError,"MemoryAllocationFailed","'%s'", color_info->name); color_info=(ColorInfo *) NULL; } @@ -1947,7 +1962,8 @@ static MagickBooleanType LoadColorList(const char *xml,const char *filename, { if (LocaleCompare((char *) keyword,"color") == 0) { - (void) QueryMagickColor(token,&color_info->color,exception); + (void) QueryColorCompliance(token,AllCompliance,&color_info->color, + exception); break; } if (LocaleCompare((char *) keyword,"compliance") == 0) @@ -1982,7 +1998,7 @@ static MagickBooleanType LoadColorList(const char *xml,const char *filename, { if (LocaleCompare((char *) keyword,"stealth") == 0) { - color_info->stealth=IsMagickTrue(token); + color_info->stealth=IsStringTrue(token); break; } break; @@ -2063,24 +2079,24 @@ static MagickBooleanType LoadColorLists(const char *filename, if (color_info == (ColorInfo *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), - ResourceLimitError,"MemoryAllocationFailed","`%s'",color_info->name); + ResourceLimitError,"MemoryAllocationFailed","'%s'",color_info->name); continue; } (void) ResetMagickMemory(color_info,0,sizeof(*color_info)); color_info->path=(char *) "[built-in]"; color_info->name=(char *) p->name; GetPixelInfo((Image *) NULL,&color_info->color); - color_info->color.red=(MagickRealType) ScaleCharToQuantum(p->red); - color_info->color.green=(MagickRealType) ScaleCharToQuantum(p->green); - color_info->color.blue=(MagickRealType) ScaleCharToQuantum(p->blue); - color_info->color.alpha=(MagickRealType) (QuantumRange*p->alpha); + color_info->color.red=(double) ScaleCharToQuantum(p->red); + color_info->color.green=(double) ScaleCharToQuantum(p->green); + color_info->color.blue=(double) ScaleCharToQuantum(p->blue); + color_info->color.alpha=(double) (QuantumRange*p->alpha); color_info->compliance=(ComplianceType) p->compliance; color_info->exempt=MagickTrue; color_info->signature=MagickSignature; status=AppendValueToLinkedList(color_list,color_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), - ResourceLimitError,"MemoryAllocationFailed","`%s'",color_info->name); + ResourceLimitError,"MemoryAllocationFailed","'%s'",color_info->name); } /* Load external color map. @@ -2102,19 +2118,19 @@ static MagickBooleanType LoadColorLists(const char *filename, % % % % % % -% Q u e r y C o l o r D a t a b a s e % ++ Q u e r y C o l o r C o m p l i a n c e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% QueryColorDatabase() returns the red, green, blue, and opacity intensities -% for a given color name. +% QueryColorCompliance() returns the red, green, blue, and alpha intensities +% for a given color name and standards compliance. % -% The format of the QueryColorDatabase method is: +% The format of the QueryColorCompliance method is: % -% MagickBooleanType QueryColorDatabase(const char *name, -% const ComplianceType compliance,PixelPacket *color, +% MagickBooleanType QueryColorCompliance(const char *name, +% const ComplianceType compliance,PixelInfo *color, % ExceptionInfo *exception) % % A description of each parameter follows: @@ -2129,167 +2145,16 @@ static MagickBooleanType LoadColorLists(const char *filename, % o exception: return any errors or warnings in this structure. % */ - -static inline double MagickMin(const double x,const double y) -{ - if (x < y) - return(x); - return(y); -} - MagickExport MagickBooleanType QueryColorCompliance(const char *name, - const ComplianceType compliance,PixelPacket *color,ExceptionInfo *exception) -{ - MagickBooleanType - status; - - PixelInfo - pixel; - - status=QueryMagickColorCompliance(name,compliance,&pixel,exception); - color->alpha=ClampToQuantum(pixel.alpha); - if (pixel.colorspace == CMYKColorspace) - { - color->red=ClampToQuantum((MagickRealType) - (QuantumRange-MagickMin(QuantumRange,(MagickRealType) (QuantumScale* - pixel.red*(QuantumRange-pixel.black)+pixel.black)))); - color->green=ClampToQuantum((MagickRealType) - (QuantumRange-MagickMin(QuantumRange,(MagickRealType) (QuantumScale* - pixel.green*(QuantumRange-pixel.black)+pixel.black)))); - color->blue=ClampToQuantum((MagickRealType) - (QuantumRange-MagickMin(QuantumRange,(MagickRealType) (QuantumScale* - pixel.blue*(QuantumRange-pixel.black)+pixel.black)))); - color->black=ClampToQuantum((MagickRealType) - (QuantumRange-MagickMin(QuantumRange,(MagickRealType) (QuantumScale* - pixel.black*(QuantumRange-pixel.black)+pixel.black)))); - return(status); - } - color->red=ClampToQuantum(pixel.red); - color->green=ClampToQuantum(pixel.green); - color->blue=ClampToQuantum(pixel.blue); - return(status); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -% Q u e r y C o l o r D a t a b a s e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% QueryColorDatabase() returns the red, green, blue, and opacity intensities -% for a given color name. -% -% The format of the QueryColorDatabase method is: -% -% MagickBooleanType QueryColorDatabase(const char *name,PixelPacket *color, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o name: the color name (e.g. white, blue, yellow). -% -% o color: the red, green, blue, and opacity intensities values of the -% named color in this structure. -% -% o exception: return any errors or warnings in this structure. -% -*/ -MagickExport MagickBooleanType QueryColorDatabase(const char *name, - PixelPacket *color,ExceptionInfo *exception) + const ComplianceType compliance,PixelInfo *color,ExceptionInfo *exception) { - return(QueryColorCompliance(name,AllCompliance,color,exception)); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -% Q u e r y C o l o r n a m e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% QueryColorname() returns a named color for the given color intensity. If -% an exact match is not found, a rgb() color is returned instead. -% -% The format of the QueryColorname method is: -% -% MagickBooleanType QueryColorname(const Image *image, -% const PixelPacket *color,const ComplianceType compliance,char *name, -% ExceptionInfo *exception) -% -% A description of each parameter follows. -% -% o image: the image. -% -% o color: the color intensities. -% -% o compliance: Adhere to this color standard: SVG, X11, or XPM. -% -% o name: Return the color name or hex value. -% -% o exception: return any errors or warnings in this structure. -% -*/ -MagickExport MagickBooleanType QueryColorname(const Image *image, - const PixelPacket *color,const ComplianceType compliance,char *name, - ExceptionInfo *exception) -{ - PixelInfo - pixel; + extern const char + BackgroundColor[]; - GetPixelInfo(image,&pixel); - SetPixelInfoPacket(image,color,&pixel); - return(QueryMagickColorname(image,&pixel,compliance,name,exception)); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -% Q u e r y M a g i c k C o l o r C o m p l i a n c e % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% QueryMagickColorCompliance() returns the red, green, blue, and alpha -% intensities for a given color name and standards compliance. -% -% The format of the QueryMagickColor method is: -% -% MagickBooleanType QueryMagickColor(const char *name, -% const ComplianceType compliance,PixelInfo *color, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o name: the color name (e.g. white, blue, yellow). -% -% o compliance: Adhere to this color standard: SVG, X11, or XPM. -% -% o color: the red, green, blue, and opacity intensities values of the -% named color in this structure. -% -% o exception: return any errors or warnings in this structure. -% -*/ -MagickExport MagickBooleanType QueryMagickColorCompliance(const char *name, - const ComplianceType compliance,PixelInfo *color, - ExceptionInfo *exception) -{ GeometryInfo geometry_info; - MagickRealType + double scale; MagickStatusType @@ -2320,7 +2185,7 @@ MagickExport MagickBooleanType QueryMagickColorCompliance(const char *name, char c; - LongPixelPacket + PixelPacket pixel; QuantumAny @@ -2366,7 +2231,7 @@ MagickExport MagickBooleanType QueryMagickColorCompliance(const char *name, if ((n % 4) != 0) { (void) ThrowMagickException(exception,GetMagickModule(), - OptionWarning,"UnrecognizedColor","`%s'",name); + OptionWarning,"UnrecognizedColor","'%s'",name); return(MagickFalse); } do @@ -2393,17 +2258,17 @@ MagickExport MagickBooleanType QueryMagickColorCompliance(const char *name, } while (isxdigit((int) ((unsigned char) *name)) != MagickFalse); depth=4*(n/4); } - color->colorspace=RGBColorspace; - color->matte=MagickFalse; + color->colorspace=sRGBColorspace; + color->alpha_trait=UndefinedPixelTrait; range=GetQuantumRange(depth); - color->red=(MagickRealType) ScaleAnyToQuantum(pixel.red,range); - color->green=(MagickRealType) ScaleAnyToQuantum(pixel.green,range); - color->blue=(MagickRealType) ScaleAnyToQuantum(pixel.blue,range); - color->alpha=(MagickRealType) OpaqueAlpha; + color->red=(double) ScaleAnyToQuantum(pixel.red,range); + color->green=(double) ScaleAnyToQuantum(pixel.green,range); + color->blue=(double) ScaleAnyToQuantum(pixel.blue,range); + color->alpha=(double) OpaqueAlpha; if ((n % 3) != 0) { - color->matte=MagickTrue; - color->alpha=(MagickRealType) ScaleAnyToQuantum(pixel.alpha,range); + color->alpha_trait=BlendPixelTrait; + color->alpha=(double) ScaleAnyToQuantum(pixel.alpha,range); } color->black=0.0; return(MagickTrue); @@ -2413,6 +2278,9 @@ MagickExport MagickBooleanType QueryMagickColorCompliance(const char *name, char colorspace[MaxTextExtent]; + MagickBooleanType + icc_color; + /* Parse color of the form rgb(100,255,0). */ @@ -2421,87 +2289,151 @@ MagickExport MagickBooleanType QueryMagickColorCompliance(const char *name, if (colorspace[i] == '(') break; colorspace[i--]='\0'; + scale=(double) ScaleCharToQuantum(1); + icc_color=MagickFalse; + if (LocaleNCompare(colorspace,"device-",7) == 0) + { + (void) CopyMagickString(colorspace,colorspace+7,MaxTextExtent); + scale=(double) QuantumRange; + icc_color=MagickTrue; + } + if (LocaleCompare(colorspace,"icc-color") == 0) + { + register ssize_t + j; + + (void) CopyMagickString(colorspace,name+i+2,MaxTextExtent); + for (j=0; colorspace[j] != '\0'; j++) + if (colorspace[j] == ',') + break; + colorspace[j--]='\0'; + i+=j+3; + scale=(double) QuantumRange; + icc_color=MagickTrue; + } LocaleLower(colorspace); - color->matte=MagickFalse; + color->alpha_trait=UndefinedPixelTrait; if ((i > 0) && (colorspace[i] == 'a')) { colorspace[i]='\0'; - color->matte=MagickTrue; + color->alpha_trait=BlendPixelTrait; } type=ParseCommandOption(MagickColorspaceOptions,MagickFalse,colorspace); if (type < 0) { (void) ThrowMagickException(exception,GetMagickModule(), - OptionWarning,"UnrecognizedColor","`%s'",name); + OptionWarning,"UnrecognizedColor","'%s'",name); return(MagickFalse); } color->colorspace=(ColorspaceType) type; + if ((icc_color == MagickFalse) && (color->colorspace == RGBColorspace)) + color->colorspace=sRGBColorspace; /* as required by SVG standard */ SetGeometryInfo(&geometry_info); flags=ParseGeometry(name+i+1,&geometry_info); - scale=(MagickRealType) ScaleCharToQuantum(1); - if ((flags & PercentValue) != 0) - scale=(MagickRealType) (QuantumRange/100.0); - if ((flags & RhoValue) != 0) - color->red=(MagickRealType) ClampToQuantum(scale*geometry_info.rho); - if ((flags & SigmaValue) != 0) - color->green=(MagickRealType) ClampToQuantum(scale*geometry_info.sigma); - if ((flags & XiValue) != 0) - color->blue=(MagickRealType) ClampToQuantum(scale*geometry_info.xi); - color->alpha=(MagickRealType) OpaqueAlpha; - if ((flags & PsiValue) != 0) + if (flags == 0) { - if (color->colorspace == CMYKColorspace) - color->black=(MagickRealType) ClampToQuantum(scale* - geometry_info.psi); - else - if (color->matte != MagickFalse) - color->alpha=(MagickRealType) ClampToQuantum((MagickRealType) - QuantumRange*geometry_info.psi); + char + *colorname; + + ColorspaceType + colorspace; + + colorspace=color->colorspace; + colorname=AcquireString(name+i+1); + (void) SubstituteString(&colorname,")",""); + (void) QueryColorCompliance(colorname,AllCompliance,color,exception); + colorname=DestroyString(colorname); + color->colorspace=colorspace; } - if (((flags & ChiValue) != 0) && (color->matte != MagickFalse)) - color->alpha=(MagickRealType) ClampToQuantum((MagickRealType) - QuantumRange*geometry_info.chi); - if (LocaleCompare(colorspace,"gray") == 0) - { - color->green=color->red; - color->blue=color->red; - if (((flags & SigmaValue) != 0) && (color->matte != MagickFalse)) - color->alpha=(MagickRealType) ClampToQuantum((MagickRealType) - QuantumRange*geometry_info.sigma); - } - if ((LocaleCompare(colorspace,"HSB") == 0) || - (LocaleCompare(colorspace,"HSL") == 0) || - (LocaleCompare(colorspace,"HWB") == 0)) + else { - PixelPacket - pixel; - - scale=1.0/360.0; if ((flags & PercentValue) != 0) - scale=1.0/100.0; - geometry_info.rho*=360.0*scale; - scale=1.0/255.0; - if ((flags & PercentValue) != 0) - scale=1.0/100.0; - geometry_info.sigma*=scale; - geometry_info.xi*=scale; - if (LocaleCompare(colorspace,"HSB") == 0) - ConvertHSBToRGB(fmod(fmod(geometry_info.rho,360.0)+360.0,360.0)/ - 360.0,geometry_info.sigma,geometry_info.xi,&pixel.red, - &pixel.green,&pixel.blue); - else - if (LocaleCompare(colorspace,"HSL") == 0) - ConvertHSLToRGB(fmod(fmod(geometry_info.rho,360.0)+360.0,360.0)/ - 360.0,geometry_info.sigma,geometry_info.xi,&pixel.red, - &pixel.green,&pixel.blue); - else - ConvertHWBToRGB(fmod(fmod(geometry_info.rho,360.0)+360.0,360.0)/ - 360.0,geometry_info.sigma,geometry_info.xi,&pixel.red, - &pixel.green,&pixel.blue); - color->colorspace=RGBColorspace; - color->red=(MagickRealType) pixel.red; - color->green=(MagickRealType) pixel.green; - color->blue=(MagickRealType) pixel.blue; + scale=(double) (QuantumRange/100.0); + if ((flags & RhoValue) != 0) + color->red=(double) ClampToQuantum(scale*geometry_info.rho); + if ((flags & SigmaValue) != 0) + color->green=(double) ClampToQuantum(scale* + geometry_info.sigma); + if ((flags & XiValue) != 0) + color->blue=(double) ClampToQuantum(scale*geometry_info.xi); + color->alpha=(double) OpaqueAlpha; + if ((flags & PsiValue) != 0) + { + if (color->colorspace == CMYKColorspace) + color->black=(double) ClampToQuantum(scale* + geometry_info.psi); + else + if (color->alpha_trait == BlendPixelTrait) + color->alpha=(double) ClampToQuantum(QuantumRange* + geometry_info.psi); + } + if (((flags & ChiValue) != 0) && + (color->alpha_trait == BlendPixelTrait)) + color->alpha=(double) ClampToQuantum(QuantumRange* + geometry_info.chi); + if (LocaleCompare(colorspace,"gray") == 0) + { + color->colorspace=GRAYColorspace; + color->green=color->red; + color->blue=color->red; + if (((flags & SigmaValue) != 0) && + (color->alpha_trait == BlendPixelTrait)) + color->alpha=(double) ClampToQuantum(QuantumRange* + geometry_info.sigma); + } + if ((LocaleCompare(colorspace,"HCL") == 0) || + (LocaleCompare(colorspace,"HSB") == 0) || + (LocaleCompare(colorspace,"HSL") == 0) || + (LocaleCompare(colorspace,"HWB") == 0)) + { + double + blue, + green, + red; + + if (LocaleCompare(colorspace,"HCL") == 0) + color->colorspace=HCLColorspace; + else + if (LocaleCompare(colorspace,"HSB") == 0) + color->colorspace=HSBColorspace; + else + if (LocaleCompare(colorspace,"HSL") == 0) + color->colorspace=HSLColorspace; + else + if (LocaleCompare(colorspace,"HWB") == 0) + color->colorspace=HWBColorspace; + scale=1.0/360.0; + if ((flags & PercentValue) != 0) + scale=1.0/100.0; + geometry_info.rho*=360.0*scale; + scale=1.0/255.0; + if ((flags & PercentValue) != 0) + scale=1.0/100.0; + geometry_info.sigma*=scale; + geometry_info.xi*=scale; + if (LocaleCompare(colorspace,"HCL") == 0) + ConvertHCLToRGB(fmod(fmod(geometry_info.rho,360.0)+360.0, + 360.0)/360.0,geometry_info.sigma,geometry_info.xi,&red, + &green,&blue); + else + if (LocaleCompare(colorspace,"HSB") == 0) + ConvertHSBToRGB(fmod(fmod(geometry_info.rho,360.0)+360.0, + 360.0)/360.0,geometry_info.sigma,geometry_info.xi,&red, + &green,&blue); + else + if (LocaleCompare(colorspace,"HSL") == 0) + ConvertHSLToRGB(fmod(fmod(geometry_info.rho,360.0)+360.0, + 360.0)/360.0,geometry_info.sigma,geometry_info.xi,&red, + &green,&blue); + else + ConvertHWBToRGB(fmod(fmod(geometry_info.rho,360.0)+360.0, + 360.0)/360.0,geometry_info.sigma,geometry_info.xi,&red, + &green,&blue); + color->colorspace=sRGBColorspace; + color->red=(MagickRealType) red; + color->green=(MagickRealType) green; + color->blue=(MagickRealType) blue; + } } return(MagickTrue); } @@ -2511,12 +2443,13 @@ MagickExport MagickBooleanType QueryMagickColorCompliance(const char *name, p=GetColorCompliance(name,compliance,exception); if (p == (const ColorInfo *) NULL) return(MagickFalse); - color->colorspace=RGBColorspace; - color->matte=p->color.alpha != OpaqueAlpha ? MagickTrue : MagickFalse; - color->red=(MagickRealType) p->color.red; - color->green=(MagickRealType) p->color.green; - color->blue=(MagickRealType) p->color.blue; - color->alpha=(MagickRealType) p->color.alpha; + color->colorspace=sRGBColorspace; + color->alpha_trait=p->color.alpha != OpaqueAlpha ? BlendPixelTrait : + UndefinedPixelTrait; + color->red=(double) p->color.red; + color->green=(double) p->color.green; + color->blue=(double) p->color.blue; + color->alpha=(double) p->color.alpha; color->black=0.0; return(MagickTrue); } @@ -2526,56 +2459,21 @@ MagickExport MagickBooleanType QueryMagickColorCompliance(const char *name, % % % % % % -% Q u e r y M a g i c k C o l o r % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% QueryMagickColor() returns the red, green, blue, and opacity intensities -% for a given color name. -% -% The format of the QueryMagickColor method is: -% -% MagickBooleanType QueryMagickColor(const char *name, -% PixelInfo *color,ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o name: the color name (e.g. white, blue, yellow). -% -% o color: the red, green, blue, and opacity intensities values of the -% named color in this structure. -% -% o exception: return any errors or warnings in this structure. -% -*/ -MagickExport MagickBooleanType QueryMagickColor(const char *name, - PixelInfo *color,ExceptionInfo *exception) -{ - return(QueryMagickColorCompliance(name,AllCompliance,color,exception)); -} - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -% Q u e r y M a g i c k C o l o r n a m e % +% Q u e r y C o l o r n a m e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% QueryMagickColorname() returns a named color for the given color intensity. +% QueryColorname() returns a named color for the given color intensity. % If an exact match is not found, a hex value is returned instead. For % example an intensity of rgb:(0,0,0) returns black whereas rgb:(223,223,223) % returns #dfdfdf. % -% The format of the QueryMagickColorname method is: +% The format of the QueryColorname method is: % -% MagickBooleanType QueryMagickColorname(const Image *image, -% const PixelPacket *color,const ComplianceType compliance,char *name, +% MagickBooleanType QueryColorname(const Image *image, +% const PixelInfo *color,const ComplianceType compliance,char *name, % ExceptionInfo *exception) % % A description of each parameter follows. @@ -2591,14 +2489,22 @@ MagickExport MagickBooleanType QueryMagickColor(const char *name, % o exception: return any errors or warnings in this structure. % */ -MagickExport MagickBooleanType QueryMagickColorname(const Image *image, + +static inline double MagickMin(const double x,const double y) +{ + if (x < y) + return(x); + return(y); +} + +MagickExport MagickBooleanType QueryColorname(const Image *image, const PixelInfo *color,const ComplianceType compliance,char *name, ExceptionInfo *exception) { PixelInfo pixel; - MagickRealType + double opacity; register const ColorInfo @@ -2608,22 +2514,24 @@ MagickExport MagickBooleanType QueryMagickColorname(const Image *image, pixel=(*color); if (compliance == XPMCompliance) { - pixel.matte=MagickFalse; + pixel.alpha_trait=UndefinedPixelTrait; pixel.depth=(size_t) MagickMin(1.0*image->depth,16.0); } GetColorTuple(&pixel,compliance != SVGCompliance ? MagickTrue : MagickFalse, name); - if (IsRGBColorspace(pixel.colorspace) == MagickFalse) + if (IssRGBColorspace(pixel.colorspace) == MagickFalse) return(MagickFalse); (void) GetColorInfo("*",exception); ResetLinkedListIterator(color_list); - opacity=image->matte != MagickFalse ? color->alpha : OpaqueAlpha; + opacity=image->alpha_trait == BlendPixelTrait ? color->alpha : OpaqueAlpha; p=(const ColorInfo *) GetNextValueInLinkedList(color_list); while (p != (const ColorInfo *) NULL) { - if (((p->compliance & compliance) != 0) && ((p->color.red == color->red)) && - (p->color.green == color->green) && (p->color.blue == color->blue) && - (p->color.alpha == opacity)) + if (((p->compliance & compliance) != 0) && + ((fabs(p->color.red-color->red) < MagickEpsilon)) && + (fabs(p->color.green-color->green) < MagickEpsilon) && + (fabs(p->color.blue-color->blue) < MagickEpsilon) && + (fabs(p->color.alpha-opacity) < MagickEpsilon)) { (void) CopyMagickString(name,p->name,MaxTextExtent); break;