blob: f63c7ecb586334d466693ad5c595181fc73ca26d [file] [log] [blame]
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% PPPP EEEEE RRRR L %
% P P E R R L %
% PPPP EEE RRRR L %
% P E R R L %
% P EEEEE R R LLLLL %
% %
% M M AAA GGGG IIIII CCCC K K %
% MM MM A A G I C K K %
% M M M AAAAA G GGG I C KKK %
% M M A A G G I C K K %
% M M A A GGGG IIIII CCCC K K %
% %
% %
% Object-oriented Perl interface to ImageMagick %
% %
% Software Design %
% Kyle Shorter %
% Cristy %
% February 1997 %
% %
% %
% Copyright 1999-2019 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 %
% obtain a copy of the License at %
% %
% https://imagemagick.org/script/license.php %
% %
% Unless required by applicable law or agreed to in writing, software %
% distributed under the License is distributed on an "AS IS" BASIS, %
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
% See the License for the specific language governing permissions and %
% limitations under the License. %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% PerlMagick is an objected-oriented Perl interface to ImageMagick. Use
% the module to read, manipulate, or write an image or image sequence from
% within a Perl script. This makes PerlMagick suitable for Web CGI scripts.
%
*/
/*
Include declarations.
*/
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
#define PERL_NO_GET_CONTEXT
#include <MagickCore/MagickCore.h>
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include <math.h>
#undef tainted
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
/*
Define declarations.
*/
#ifndef aTHX_
#define aTHX_
#define pTHX_
#define dTHX
#endif
#define DegreesToRadians(x) (MagickPI*(x)/180.0)
#define EndOf(array) (&array[NumberOf(array)])
#define MagickPI 3.14159265358979323846264338327950288419716939937510
#define MaxArguments 34
#ifndef na
#define na PL_na
#endif
#define NumberOf(array) (sizeof(array)/sizeof(*array))
#define PackageName "Image::Magick"
#if PERL_VERSION <= 6
#define PerlIO FILE
#define PerlIO_importFILE(f, fl) (f)
#define PerlIO_findFILE(f) NULL
#endif
#ifndef sv_undef
#define sv_undef PL_sv_undef
#endif
#define AddImageToRegistry(sv,image) \
{ \
if (magick_registry != (SplayTreeInfo *) NULL) \
{ \
(void) AddValueToSplayTree(magick_registry,image,image); \
(sv)=newSViv(PTR2IV(image)); \
} \
}
#define DeleteImageFromRegistry(reference,image) \
{ \
if (magick_registry != (SplayTreeInfo *) NULL) \
{ \
if (GetImageReferenceCount(image) == 1) \
(void) DeleteNodeByValueFromSplayTree(magick_registry,image); \
image=DestroyImage(image); \
sv_setiv(reference,0); \
} \
}
#define InheritPerlException(exception,perl_exception) \
{ \
char \
message[MagickPathExtent]; \
\
if ((exception)->severity != UndefinedException) \
{ \
(void) FormatLocaleString(message,MagickPathExtent,"Exception %d: %s%s%s%s",\
(exception)->severity, (exception)->reason ? \
GetLocaleExceptionMessage((exception)->severity,(exception)->reason) : \
"Unknown", (exception)->description ? " (" : "", \
(exception)->description ? GetLocaleExceptionMessage( \
(exception)->severity,(exception)->description) : "", \
(exception)->description ? ")" : ""); \
if ((perl_exception) != (SV *) NULL) \
{ \
if (SvCUR(perl_exception)) \
sv_catpv(perl_exception,"\n"); \
sv_catpv(perl_exception,message); \
} \
} \
}
#define ThrowPerlException(exception,severity,tag,reason) \
(void) ThrowMagickException(exception,GetMagickModule(),severity, \
tag,"`%s'",reason); \
/*
Typedef and structure declarations.
*/
typedef enum
{
NullReference = 0,
ArrayReference = (~0),
RealReference = (~0)-1,
FileReference = (~0)-2,
ImageReference = (~0)-3,
IntegerReference = (~0)-4,
StringReference = (~0)-5
} MagickReference;
typedef struct _Arguments
{
const char
*method;
ssize_t
type;
} Arguments;
struct ArgumentList
{
ssize_t
integer_reference;
double
real_reference;
const char
*string_reference;
Image
*image_reference;
SV
*array_reference;
FILE
*file_reference;
size_t
length;
};
struct PackageInfo
{
ImageInfo
*image_info;
};
typedef void
*Image__Magick; /* data type for the Image::Magick package */
/*
Static declarations.
*/
static struct
Methods
{
const char
*name;
Arguments
arguments[MaxArguments];
} Methods[] =
{
{ "Comment", { {"comment", StringReference} } },
{ "Label", { {"label", StringReference} } },
{ "AddNoise", { {"noise", MagickNoiseOptions}, {"attenuate", RealReference},
{"channel", MagickChannelOptions} } },
{ "Colorize", { {"fill", StringReference}, {"blend", StringReference} } },
{ "Border", { {"geometry", StringReference}, {"width", IntegerReference},
{"height", IntegerReference}, {"fill", StringReference},
{"bordercolor", StringReference}, {"color", StringReference},
{"compose", MagickComposeOptions} } },
{ "Blur", { {"geometry", StringReference}, {"radius", RealReference},
{"sigma", RealReference}, {"channel", MagickChannelOptions} } },
{ "Chop", { {"geometry", StringReference}, {"width", IntegerReference},
{"height", IntegerReference}, {"x", IntegerReference},
{"y", IntegerReference}, {"gravity", MagickGravityOptions} } },
{ "Crop", { {"geometry", StringReference}, {"width", IntegerReference},
{"height", IntegerReference}, {"x", IntegerReference},
{"y", IntegerReference}, {"fuzz", StringReference},
{"gravity", MagickGravityOptions} } },
{ "Despeckle", { { (const char *) NULL, NullReference } } },
{ "Edge", { {"radius", RealReference} } },
{ "Emboss", { {"geometry", StringReference}, {"radius", RealReference},
{"sigma", RealReference} } },
{ "Enhance", { { (const char *) NULL, NullReference } } },
{ "Flip", { { (const char *) NULL, NullReference } } },
{ "Flop", { { (const char *) NULL, NullReference } } },
{ "Frame", { {"geometry", StringReference}, {"width", IntegerReference},
{"height", IntegerReference}, {"inner", IntegerReference},
{"outer", IntegerReference}, {"fill", StringReference},
{"color", StringReference}, {"compose", MagickComposeOptions} } },
{ "Implode", { {"amount", RealReference},
{"interpolate", MagickInterpolateOptions} } },
{ "Magnify", { { (const char *) NULL, NullReference } } },
{ "MedianFilter", { {"geometry", StringReference},
{"width", IntegerReference}, {"height", IntegerReference},
{"channel", MagickChannelOptions} } },
{ "Minify", { { (const char *) NULL, NullReference } } },
{ "OilPaint", { {"radius", RealReference}, {"sigma", RealReference} } },
{ "ReduceNoise", { {"geometry", StringReference},
{"width", IntegerReference},{"height", IntegerReference},
{"channel", MagickChannelOptions} } },
{ "Roll", { {"geometry", StringReference}, {"x", IntegerReference},
{"y", IntegerReference} } },
{ "Rotate", { {"degrees", RealReference},
{"background", StringReference} } },
{ "Sample", { {"geometry", StringReference}, {"width", IntegerReference},
{"height", IntegerReference} } },
{ "Scale", { {"geometry", StringReference}, {"width", IntegerReference},
{"height", IntegerReference} } },
{ "Shade", { {"geometry", StringReference}, {"azimuth", RealReference},
{"elevation", RealReference}, {"gray", MagickBooleanOptions} } },
{ "Sharpen", { {"geometry", StringReference}, {"radius", RealReference},
{"sigma", RealReference}, {"channel", MagickChannelOptions} } },
{ "Shear", { {"geometry", StringReference}, {"x", RealReference},
{"y", RealReference}, { "fill", StringReference},
{"color", StringReference} } },
{ "Spread", { {"radius", RealReference},
{"interpolate", MagickInterpolateOptions} } },
{ "Swirl", { {"degrees", RealReference},
{"interpolate", MagickInterpolateOptions} } },
{ "Resize", { {"geometry", StringReference}, {"width", IntegerReference},
{"height", IntegerReference}, {"filter", MagickFilterOptions},
{"support", StringReference } } },
{ "Zoom", { {"geometry", StringReference}, {"width", IntegerReference},
{"height", IntegerReference}, {"filter", MagickFilterOptions},
{"support", RealReference } } },
{ "Annotate", { {"text", StringReference}, {"font", StringReference},
{"pointsize", RealReference}, {"density", StringReference},
{"undercolor", StringReference}, {"stroke", StringReference},
{"fill", StringReference}, {"geometry", StringReference},
{"sans", StringReference}, {"x", RealReference},
{"y", RealReference}, {"gravity", MagickGravityOptions},
{"translate", StringReference}, {"scale", StringReference},
{"rotate", RealReference}, {"skewX", RealReference},
{"skewY", RealReference}, {"strokewidth", RealReference},
{"antialias", MagickBooleanOptions}, {"family", StringReference},
{"style", MagickStyleOptions}, {"stretch", MagickStretchOptions},
{"weight", IntegerReference}, {"align", MagickAlignOptions},
{"encoding", StringReference}, {"affine", ArrayReference},
{"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
{"tile", ImageReference}, {"kerning", RealReference},
{"interline-spacing", RealReference},
{"interword-spacing", RealReference},
{"direction", MagickDirectionOptions},
{"decorate", MagickDecorateOptions} } },
{ "ColorFloodfill", { {"geometry", StringReference},
{"x", IntegerReference}, {"y", IntegerReference},
{"fill", StringReference}, {"bordercolor", StringReference},
{"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
{ "Composite", { {"image", ImageReference},
{"compose", MagickComposeOptions}, {"geometry", StringReference},
{"x", IntegerReference}, {"y", IntegerReference},
{"gravity", MagickGravityOptions}, {"opacity", StringReference},
{"tile", MagickBooleanOptions}, {"rotate", RealReference},
{"color", StringReference}, {"mask", ImageReference},
{"channel", MagickChannelOptions},
{"interpolate", MagickInterpolateOptions}, {"args", StringReference},
{"blend", StringReference}, {"clip-to-self", MagickBooleanOptions} } },
{ "Contrast", { {"sharpen", MagickBooleanOptions} } },
{ "CycleColormap", { {"display", IntegerReference} } },
{ "Draw", { {"primitive", MagickPrimitiveOptions},
{"points", StringReference}, {"method", MagickMethodOptions},
{"stroke", StringReference}, {"fill", StringReference},
{"strokewidth", RealReference}, {"font", StringReference},
{"bordercolor", StringReference}, {"x", RealReference},
{"y", RealReference}, {"translate", StringReference},
{"scale", StringReference}, {"rotate", RealReference},
{"skewX", RealReference}, {"skewY", RealReference},
{"tile", ImageReference}, {"pointsize", RealReference},
{"antialias", MagickBooleanOptions}, {"density", StringReference},
{"linewidth", RealReference}, {"affine", ArrayReference},
{"stroke-dashoffset", RealReference},
{"stroke-dasharray", ArrayReference},
{"interpolate", MagickInterpolateOptions},
{"origin", StringReference}, {"text", StringReference},
{"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
{"vector-graphics", StringReference}, {"kerning", RealReference},
{"interline-spacing", RealReference},
{"interword-spacing", RealReference},
{"direction", MagickDirectionOptions} } },
{ "Equalize", { {"channel", MagickChannelOptions} } },
{ "Gamma", { {"gamma", StringReference}, {"channel", MagickChannelOptions},
{"red", RealReference}, {"green", RealReference},
{"blue", RealReference} } },
{ "Map", { {"image", ImageReference},
{"dither-method", MagickDitherOptions} } },
{ "MatteFloodfill", { {"geometry", StringReference},
{"x", IntegerReference}, {"y", IntegerReference},
{"opacity", StringReference}, {"bordercolor", StringReference},
{"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
{ "Modulate", { {"factor", StringReference}, {"hue", RealReference},
{"saturation", RealReference}, {"whiteness", RealReference},
{"brightness", RealReference}, {"lightness", RealReference},
{"blackness", RealReference} } },
{ "Negate", { {"gray", MagickBooleanOptions},
{"channel", MagickChannelOptions} } },
{ "Normalize", { {"channel", MagickChannelOptions} } },
{ "NumberColors", { { (const char *) NULL, NullReference } } },
{ "Opaque", { {"color", StringReference}, {"fill", StringReference},
{"fuzz", StringReference}, {"channel", MagickChannelOptions},
{"invert", MagickBooleanOptions} } },
{ "Quantize", { {"colors", IntegerReference},
{"treedepth", IntegerReference}, {"colorspace", MagickColorspaceOptions},
{"dither", MagickDitherOptions}, {"measure", MagickBooleanOptions},
{"global", MagickBooleanOptions}, {"transparent-color", StringReference},
{"dither-method", MagickDitherOptions} } },
{ "Raise", { {"geometry", StringReference}, {"width", IntegerReference},
{"height", IntegerReference}, {"raise", MagickBooleanOptions} } },
{ "Segment", { {"geometry", StringReference},
{"cluster-threshold", RealReference},
{"smoothing-threshold", RealReference},
{"colorspace", MagickColorspaceOptions},
{"verbose", MagickBooleanOptions} } },
{ "Signature", { { (const char *) NULL, NullReference } } },
{ "Solarize", { {"geometry", StringReference},
{"threshold", StringReference} } },
{ "Sync", { { (const char *) NULL, NullReference } } },
{ "Texture", { {"texture", ImageReference} } },
{ "Evaluate", { {"value", RealReference},
{"operator", MagickEvaluateOptions},
{"channel", MagickChannelOptions} } },
{ "Transparent", { {"color", StringReference}, {"opacity", StringReference},
{"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
{ "Threshold", { {"threshold", StringReference},
{"channel", MagickChannelOptions} } },
{ "Charcoal", { {"geometry", StringReference}, {"radius", RealReference},
{"sigma", RealReference} } },
{ "Trim", { {"fuzz", StringReference} } },
{ "Wave", { {"geometry", StringReference}, {"amplitude", RealReference},
{"wavelength", RealReference},
{"interpolate", MagickInterpolateOptions} } },
{ "Separate", { {"channel", MagickChannelOptions} } },
{ "Condense", { { (const char *) NULL, NullReference } } },
{ "Stereo", { {"image", ImageReference}, {"x", IntegerReference},
{"y", IntegerReference} } },
{ "Stegano", { {"image", ImageReference}, {"offset", IntegerReference} } },
{ "Deconstruct", { { (const char *) NULL, NullReference } } },
{ "GaussianBlur", { {"geometry", StringReference},
{"radius", RealReference}, {"sigma", RealReference},
{"channel", MagickChannelOptions} } },
{ "Convolve", { {"coefficients", ArrayReference},
{"channel", MagickChannelOptions}, {"bias", StringReference},
{"kernel", StringReference} } },
{ "Profile", { {"name", StringReference}, {"profile", StringReference},
{ "rendering-intent", MagickIntentOptions},
{ "black-point-compensation", MagickBooleanOptions} } },
{ "UnsharpMask", { {"geometry", StringReference},
{"radius", RealReference}, {"sigma", RealReference},
{"gain", RealReference}, {"threshold", RealReference},
{"channel", MagickChannelOptions} } },
{ "MotionBlur", { {"geometry", StringReference},
{"radius", RealReference}, {"sigma", RealReference},
{"angle", RealReference}, {"channel", MagickChannelOptions} } },
{ "OrderedDither", { {"threshold", StringReference},
{"channel", MagickChannelOptions} } },
{ "Shave", { {"geometry", StringReference}, {"width", IntegerReference},
{"height", IntegerReference} } },
{ "Level", { {"levels", StringReference}, {"black-point", RealReference},
{"white-point", RealReference}, {"gamma", RealReference},
{"channel", MagickChannelOptions}, {"level", StringReference} } },
{ "Clip", { {"id", StringReference}, {"inside", MagickBooleanOptions} } },
{ "AffineTransform", { {"affine", ArrayReference},
{"translate", StringReference}, {"scale", StringReference},
{"rotate", RealReference}, {"skewX", RealReference},
{"skewY", RealReference}, {"interpolate", MagickInterpolateOptions},
{"background", StringReference} } },
{ "Difference", { {"image", ImageReference}, {"fuzz", StringReference} } },
{ "AdaptiveThreshold", { {"geometry", StringReference},
{"width", IntegerReference}, {"height", IntegerReference},
{"bias", RealReference} } },
{ "Resample", { {"density", StringReference}, {"x", RealReference},
{"y", RealReference}, {"filter", MagickFilterOptions},
{"support", RealReference } } },
{ "Describe", { {"file", FileReference} } },
{ "BlackThreshold", { {"threshold", StringReference},
{"channel", MagickChannelOptions} } },
{ "WhiteThreshold", { {"threshold", StringReference},
{"channel", MagickChannelOptions} } },
{ "RotationalBlur", { {"geometry", StringReference},
{"angle", RealReference}, {"channel", MagickChannelOptions} } },
{ "Thumbnail", { {"geometry", StringReference}, {"width", IntegerReference},
{"height", IntegerReference} } },
{ "Strip", { { (const char *) NULL, NullReference } } },
{ "Tint", { {"fill", StringReference}, {"blend", StringReference} } },
{ "Channel", { {"channel", MagickChannelOptions} } },
{ "Splice", { {"geometry", StringReference}, {"width", IntegerReference},
{"height", IntegerReference}, {"x", IntegerReference},
{"y", IntegerReference}, {"fuzz", StringReference},
{"background", StringReference}, {"gravity", MagickGravityOptions} } },
{ "Posterize", { {"levels", IntegerReference},
{"dither", MagickBooleanOptions} } },
{ "Shadow", { {"geometry", StringReference}, {"alpha", RealReference},
{"sigma", RealReference}, {"x", IntegerReference},
{"y", IntegerReference} } },
{ "Identify", { {"file", FileReference}, {"features", StringReference},
{"unique", MagickBooleanOptions} } },
{ "SepiaTone", { {"threshold", RealReference} } },
{ "SigmoidalContrast", { {"geometry", StringReference},
{"contrast", RealReference}, {"mid-point", RealReference},
{"channel", MagickChannelOptions}, {"sharpen", MagickBooleanOptions} } },
{ "Extent", { {"geometry", StringReference}, {"width", IntegerReference},
{"height", IntegerReference}, {"x", IntegerReference},
{"y", IntegerReference}, {"fuzz", StringReference},
{"background", StringReference}, {"gravity", MagickGravityOptions} } },
{ "Vignette", { {"geometry", StringReference}, {"radius", RealReference},
{"sigma", RealReference}, {"x", IntegerReference},
{"y", IntegerReference}, {"background", StringReference} } },
{ "ContrastStretch", { {"levels", StringReference},
{"black-point", RealReference},{"white-point", RealReference},
{"channel", MagickChannelOptions} } },
{ "Sans0", { { (const char *) NULL, NullReference } } },
{ "Sans1", { { (const char *) NULL, NullReference } } },
{ "AdaptiveSharpen", { {"geometry", StringReference},
{"radius", RealReference}, {"sigma", RealReference},
{"bias", RealReference}, {"channel", MagickChannelOptions} } },
{ "Transpose", { { (const char *) NULL, NullReference } } },
{ "Transverse", { { (const char *) NULL, NullReference } } },
{ "AutoOrient", { { (const char *) NULL, NullReference } } },
{ "AdaptiveBlur", { {"geometry", StringReference},
{"radius", RealReference}, {"sigma", RealReference},
{"channel", MagickChannelOptions} } },
{ "Sketch", { {"geometry", StringReference},
{"radius", RealReference}, {"sigma", RealReference},
{"angle", RealReference} } },
{ "UniqueColors", { { (const char *) NULL, NullReference } } },
{ "AdaptiveResize", { {"geometry", StringReference},
{"width", IntegerReference}, {"height", IntegerReference},
{"filter", MagickFilterOptions}, {"support", StringReference },
{"blur", RealReference } } },
{ "ClipMask", { {"mask", ImageReference} } },
{ "LinearStretch", { {"levels", StringReference},
{"black-point", RealReference},{"white-point", RealReference} } },
{ "ColorMatrix", { {"matrix", ArrayReference} } },
{ "Mask", { {"mask", ImageReference} } },
{ "Polaroid", { {"caption", StringReference}, {"angle", RealReference},
{"font", StringReference}, {"stroke", StringReference},
{"fill", StringReference}, {"strokewidth", RealReference},
{"pointsize", RealReference}, {"gravity", MagickGravityOptions},
{"background", StringReference},
{"interpolate", MagickInterpolateOptions} } },
{ "FloodfillPaint", { {"geometry", StringReference},
{"x", IntegerReference}, {"y", IntegerReference},
{"fill", StringReference}, {"bordercolor", StringReference},
{"fuzz", StringReference}, {"channel", MagickChannelOptions},
{"invert", MagickBooleanOptions} } },
{ "Distort", { {"points", ArrayReference}, {"method", MagickDistortOptions},
{"virtual-pixel", MagickVirtualPixelOptions},
{"best-fit", MagickBooleanOptions} } },
{ "Clut", { {"image", ImageReference},
{"interpolate", MagickInterpolateOptions},
{"channel", MagickChannelOptions} } },
{ "LiquidRescale", { {"geometry", StringReference},
{"width", IntegerReference}, {"height", IntegerReference},
{"delta-x", RealReference}, {"rigidity", RealReference } } },
{ "Encipher", { {"passphrase", StringReference} } },
{ "Decipher", { {"passphrase", StringReference} } },
{ "Deskew", { {"geometry", StringReference},
{"threshold", StringReference} } },
{ "Remap", { {"image", ImageReference},
{"dither-method", MagickDitherOptions} } },
{ "SparseColor", { {"points", ArrayReference},
{"method", MagickSparseColorOptions},
{"virtual-pixel", MagickVirtualPixelOptions},
{"channel", MagickChannelOptions} } },
{ "Function", { {"parameters", ArrayReference},
{"function", MagickFunctionOptions},
{"virtual-pixel", MagickVirtualPixelOptions} } },
{ "SelectiveBlur", { {"geometry", StringReference},
{"radius", RealReference}, {"sigma", RealReference},
{"threshold", RealReference}, {"channel", MagickChannelOptions} } },
{ "HaldClut", { {"image", ImageReference},
{"channel", MagickChannelOptions} } },
{ "BlueShift", { {"factor", StringReference} } },
{ "ForwardFourierTransform", { {"magnitude", MagickBooleanOptions} } },
{ "InverseFourierTransform", { {"magnitude", MagickBooleanOptions} } },
{ "ColorDecisionList", {
{"color-correction-collection", StringReference} } },
{ "AutoGamma", { {"channel", MagickChannelOptions} } },
{ "AutoLevel", { {"channel", MagickChannelOptions} } },
{ "LevelColors", { {"invert", MagickBooleanOptions},
{"black-point", StringReference}, {"white-point", StringReference},
{"channel", MagickChannelOptions}, {"invert", MagickBooleanOptions} } },
{ "Clamp", { {"channel", MagickChannelOptions} } },
{ "BrightnessContrast", { {"levels", StringReference},
{"brightness", RealReference},{"contrast", RealReference},
{"channel", MagickChannelOptions} } },
{ "Morphology", { {"kernel", StringReference},
{"channel", MagickChannelOptions}, {"method", MagickMorphologyOptions},
{"iterations", IntegerReference} } },
{ "Mode", { {"geometry", StringReference},
{"width", IntegerReference},{"height", IntegerReference},
{"channel", MagickChannelOptions} } },
{ "Statistic", { {"geometry", StringReference},
{"width", IntegerReference},{"height", IntegerReference},
{"channel", MagickChannelOptions}, {"type", MagickStatisticOptions} } },
{ "Perceptible", { {"epsilon", RealReference},
{"channel", MagickChannelOptions} } },
{ "Poly", { {"terms", ArrayReference},
{"channel", MagickChannelOptions} } },
{ "Grayscale", { {"method", MagickNoiseOptions} } },
{ "CannyEdge", { {"geometry", StringReference},
{"radius", RealReference}, {"sigma", RealReference},
{"lower-percent", RealReference}, {"upper-percent", RealReference} } },
{ "HoughLine", { {"geometry", StringReference},
{"width", IntegerReference}, {"height", IntegerReference},
{"threshold", IntegerReference} } },
{ "MeanShift", { {"geometry", StringReference},
{"width", IntegerReference}, {"height", IntegerReference},
{"distance", RealReference} } },
{ "Kuwahara", { {"geometry", StringReference}, {"radius", RealReference},
{"sigma", RealReference}, {"channel", MagickChannelOptions} } },
{ "ConnectedComponents", { {"connectivity", IntegerReference} } },
{ "CopyPixels", { {"image", ImageReference}, {"geometry", StringReference},
{"width", IntegerReference}, {"height", IntegerReference},
{"x", IntegerReference}, {"y", IntegerReference},
{"gravity", MagickGravityOptions}, {"offset", StringReference},
{"dx", IntegerReference}, {"dy", IntegerReference} } },
{ "Color", { {"color", StringReference} } },
{ "WaveletDenoise", { {"geometry", StringReference},
{"threshold", RealReference}, {"softness", RealReference},
{"channel", MagickChannelOptions} } },
{ "Colorspace", { {"colorspace", MagickColorspaceOptions} } },
{ "AutoThreshold", { {"method", MagickAutoThresholdOptions} } },
{ "RangeThreshold", { {"geometry", StringReference},
{"low-black", RealReference}, {"low-white", RealReference},
{"high-white", RealReference}, {"high-black", RealReference},
{"channel", MagickChannelOptions} } },
{ "CLAHE", { {"geometry", StringReference}, {"width", IntegerReference},
{"height", IntegerReference}, {"number-bins", IntegerReference},
{"clip-limit", RealReference} } },
};
static SplayTreeInfo
*magick_registry = (SplayTreeInfo *) NULL;
/*
Forward declarations.
*/
static Image
*SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
static ssize_t
strEQcase(const char *,const char *);
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% C l o n e P a c k a g e I n f o %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
% a new one.
%
% The format of the ClonePackageInfo routine is:
%
% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
% exception)
%
% A description of each parameter follows:
%
% o info: a structure of type info.
%
% o exception: Return any errors or warnings in this structure.
%
*/
static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
ExceptionInfo *exception)
{
struct PackageInfo
*clone_info;
clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
if (clone_info == (struct PackageInfo *) NULL)
{
ThrowPerlException(exception,ResourceLimitError,
"UnableToClonePackageInfo",PackageName);
return((struct PackageInfo *) NULL);
}
if (info == (struct PackageInfo *) NULL)
{
clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
return(clone_info);
}
*clone_info=(*info);
clone_info->image_info=CloneImageInfo(info->image_info);
return(clone_info);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% c o n s t a n t %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% constant() returns a double value for the specified name.
%
% The format of the constant routine is:
%
% double constant(char *name,ssize_t sans)
%
% A description of each parameter follows:
%
% o value: Method constant returns a double value for the specified name.
%
% o name: The name of the constant.
%
% o sans: This integer value is not used.
%
*/
static double constant(char *name,ssize_t sans)
{
(void) sans;
errno=0;
switch (*name)
{
case 'B':
{
if (strEQ(name,"BlobError"))
return(BlobError);
if (strEQ(name,"BlobWarning"))
return(BlobWarning);
break;
}
case 'C':
{
if (strEQ(name,"CacheError"))
return(CacheError);
if (strEQ(name,"CacheWarning"))
return(CacheWarning);
if (strEQ(name,"CoderError"))
return(CoderError);
if (strEQ(name,"CoderWarning"))
return(CoderWarning);
if (strEQ(name,"ConfigureError"))
return(ConfigureError);
if (strEQ(name,"ConfigureWarning"))
return(ConfigureWarning);
if (strEQ(name,"CorruptImageError"))
return(CorruptImageError);
if (strEQ(name,"CorruptImageWarning"))
return(CorruptImageWarning);
break;
}
case 'D':
{
if (strEQ(name,"DelegateError"))
return(DelegateError);
if (strEQ(name,"DelegateWarning"))
return(DelegateWarning);
if (strEQ(name,"DrawError"))
return(DrawError);
if (strEQ(name,"DrawWarning"))
return(DrawWarning);
break;
}
case 'E':
{
if (strEQ(name,"ErrorException"))
return(ErrorException);
if (strEQ(name,"ExceptionError"))
return(CoderError);
if (strEQ(name,"ExceptionWarning"))
return(CoderWarning);
break;
}
case 'F':
{
if (strEQ(name,"FatalErrorException"))
return(FatalErrorException);
if (strEQ(name,"FileOpenError"))
return(FileOpenError);
if (strEQ(name,"FileOpenWarning"))
return(FileOpenWarning);
break;
}
case 'I':
{
if (strEQ(name,"ImageError"))
return(ImageError);
if (strEQ(name,"ImageWarning"))
return(ImageWarning);
break;
}
case 'M':
{
if (strEQ(name,"MaxRGB"))
return(QuantumRange);
if (strEQ(name,"MissingDelegateError"))
return(MissingDelegateError);
if (strEQ(name,"MissingDelegateWarning"))
return(MissingDelegateWarning);
if (strEQ(name,"ModuleError"))
return(ModuleError);
if (strEQ(name,"ModuleWarning"))
return(ModuleWarning);
break;
}
case 'O':
{
if (strEQ(name,"Opaque"))
return(OpaqueAlpha);
if (strEQ(name,"OptionError"))
return(OptionError);
if (strEQ(name,"OptionWarning"))
return(OptionWarning);
break;
}
case 'Q':
{
if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
return(MAGICKCORE_QUANTUM_DEPTH);
if (strEQ(name,"QuantumDepth"))
return(MAGICKCORE_QUANTUM_DEPTH);
if (strEQ(name,"QuantumRange"))
return(QuantumRange);
break;
}
case 'R':
{
if (strEQ(name,"ResourceLimitError"))
return(ResourceLimitError);
if (strEQ(name,"ResourceLimitWarning"))
return(ResourceLimitWarning);
if (strEQ(name,"RegistryError"))
return(RegistryError);
if (strEQ(name,"RegistryWarning"))
return(RegistryWarning);
break;
}
case 'S':
{
if (strEQ(name,"StreamError"))
return(StreamError);
if (strEQ(name,"StreamWarning"))
return(StreamWarning);
if (strEQ(name,"Success"))
return(0);
break;
}
case 'T':
{
if (strEQ(name,"Transparent"))
return(TransparentAlpha);
if (strEQ(name,"TypeError"))
return(TypeError);
if (strEQ(name,"TypeWarning"))
return(TypeWarning);
break;
}
case 'W':
{
if (strEQ(name,"WarningException"))
return(WarningException);
break;
}
case 'X':
{
if (strEQ(name,"XServerError"))
return(XServerError);
if (strEQ(name,"XServerWarning"))
return(XServerWarning);
break;
}
}
errno=EINVAL;
return(0);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% D e s t r o y P a c k a g e I n f o %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Method DestroyPackageInfo frees a previously created info structure.
%
% The format of the DestroyPackageInfo routine is:
%
% DestroyPackageInfo(struct PackageInfo *info)
%
% A description of each parameter follows:
%
% o info: a structure of type info.
%
*/
static void DestroyPackageInfo(struct PackageInfo *info)
{
info->image_info=DestroyImageInfo(info->image_info);
info=(struct PackageInfo *) RelinquishMagickMemory(info);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% G e t L i s t %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Method GetList is recursively called by SetupList to traverse the
% Image__Magick reference. If building an reference_vector (see SetupList),
% *current is the current position in *reference_vector and *last is the final
% entry in *reference_vector.
%
% The format of the GetList routine is:
%
% GetList(info)
%
% A description of each parameter follows:
%
% o info: a structure of type info.
%
*/
static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
ssize_t *current,ssize_t *last,ExceptionInfo *exception)
{
Image
*image;
if (reference == (SV *) NULL)
return(NULL);
switch (SvTYPE(reference))
{
case SVt_PVAV:
{
AV
*av;
Image
*head,
*previous;
register ssize_t
i;
ssize_t
n;
/*
Array of images.
*/
previous=(Image *) NULL;
head=(Image *) NULL;
av=(AV *) reference;
n=av_len(av);
for (i=0; i <= n; i++)
{
SV
**rv;
rv=av_fetch(av,i,0);
if (rv && *rv && sv_isobject(*rv))
{
image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
exception);
if (image == (Image *) NULL)
continue;
if (image == previous)
{
image=CloneImage(image,0,0,MagickTrue,exception);
if (image == (Image *) NULL)
return(NULL);
}
image->previous=previous;
*(previous ? &previous->next : &head)=image;
for (previous=image; previous->next; previous=previous->next) ;
}
}
return(head);
}
case SVt_PVMG:
{
/*
Blessed scalar, one image.
*/
image=INT2PTR(Image *,SvIV(reference));
if (image == (Image *) NULL)
return(NULL);
image->previous=(Image *) NULL;
image->next=(Image *) NULL;
if (reference_vector)
{
if (*current == *last)
{
*last+=256;
if (*reference_vector == (SV **) NULL)
*reference_vector=(SV **) AcquireQuantumMemory(*last,
sizeof(*reference_vector));
else
*reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
*last,sizeof(*reference_vector));
}
if (*reference_vector == (SV **) NULL)
{
ThrowPerlException(exception,ResourceLimitError,
"MemoryAllocationFailed",PackageName);
return((Image *) NULL);
}
(*reference_vector)[*current]=reference;
(*reference_vector)[++(*current)]=NULL;
}
return(image);
}
default:
break;
}
(void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
(double) SvTYPE(reference));
return((Image *) NULL);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% G e t P a c k a g e I n f o %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Method GetPackageInfo looks up or creates an info structure for the given
% Image__Magick reference. If it does create a new one, the information in
% package_info is used to initialize it.
%
% The format of the GetPackageInfo routine is:
%
% struct PackageInfo *GetPackageInfo(void *reference,
% struct PackageInfo *package_info,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o info: a structure of type info.
%
% o exception: Return any errors or warnings in this structure.
%
*/
static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
struct PackageInfo *package_info,ExceptionInfo *exception)
{
char
message[MagickPathExtent];
struct PackageInfo
*clone_info;
SV
*sv;
(void) FormatLocaleString(message,MagickPathExtent,"%s::package%s%p",
PackageName,XS_VERSION,reference);
sv=perl_get_sv(message,(TRUE | 0x02));
if (sv == (SV *) NULL)
{
ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
message);
return(package_info);
}
if (SvREFCNT(sv) == 0)
(void) SvREFCNT_inc(sv);
if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
return(clone_info);
clone_info=ClonePackageInfo(package_info,exception);
sv_setiv(sv,PTR2IV(clone_info));
return(clone_info);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% S e t A t t r i b u t e %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% SetAttribute() sets the attribute to the value in sval. This can change
% either or both of image or info.
%
% The format of the SetAttribute routine is:
%
% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
% SV *sval,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o list: a list of strings.
%
% o string: a character string.
%
*/
static double SiPrefixToDoubleInterval(const char *string,const double interval)
{
char
*q;
double
value;
value=InterpretSiPrefixValue(string,&q);
if (*q == '%')
value*=interval/100.0;
return(value);
}
static inline double StringToDouble(const char *string,char **sentinal)
{
return(InterpretLocaleValue(string,sentinal));
}
static double StringToDoubleInterval(const char *string,const double interval)
{
char
*q;
double
value;
value=InterpretLocaleValue(string,&q);
if (*q == '%')
value*=interval/100.0;
return(value);
}
static inline ssize_t StringToLong(const char *value)
{
return(strtol(value,(char **) NULL,10));
}
static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
const char *attribute,SV *sval,ExceptionInfo *exception)
{
GeometryInfo
geometry_info;
long
x,
y;
PixelInfo
pixel;
MagickStatusType
flags;
PixelInfo
*color,
target_color;
ssize_t
sp;
switch (*attribute)
{
case 'A':
case 'a':
{
if (LocaleCompare(attribute,"adjoin") == 0)
{
sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
SvPV(sval,na)) : SvIV(sval);
if (sp < 0)
{
ThrowPerlException(exception,OptionError,"UnrecognizedType",
SvPV(sval,na));
break;
}
if (info)
info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
break;
}
if (LocaleCompare(attribute,"alpha") == 0)
{
sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
MagickFalse,SvPV(sval,na)) : SvIV(sval);
if (sp < 0)
{
ThrowPerlException(exception,OptionError,"UnrecognizedType",
SvPV(sval,na));
break;
}
for ( ; image; image=image->next)
(void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
exception);
break;
}
if (LocaleCompare(attribute,"antialias") == 0)
{
sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
SvPV(sval,na)) : SvIV(sval);
if (sp < 0)
{
ThrowPerlException(exception,OptionError,"UnrecognizedType",
SvPV(sval,na));
break;
}
if (info)
info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
break;
}
if (LocaleCompare(attribute,"area-limit") == 0)
{
MagickSizeType
limit;
limit=MagickResourceInfinity;
if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
100.0);
(void) SetMagickResourceLimit(AreaResource,limit);
break;
}
if (LocaleCompare(attribute,"attenuate") == 0)
{
if (info)
(void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
break;
}
if (LocaleCompare(attribute,"authenticate") == 0)
{
if (info)
SetImageOption(info->image_info,attribute,SvPV(sval,na));
break;
}
if (info)
SetImageOption(info->image_info,attribute,SvPV(sval,na));
for ( ; image; image=image->next)
{
(void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
(void) SetImageArtifact(image,attribute,SvPV(sval,na));
}
break;
}
case 'B':
case 'b':
{
if (LocaleCompare(attribute,"background") == 0)
{
(void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
exception);
if (info)
info->image_info->background_color=target_color;
for ( ; image; image=image->next)
image->background_color=target_color;
break;
}
if (LocaleCompare(attribute,"blue-primary") == 0)
{
for ( ; image; image=image->next)
{
flags=ParseGeometry(SvPV(sval,na),&geometry_info);
image->chromaticity.blue_primary.x=geometry_info.rho;
image->chromaticity.blue_primary.y=geometry_info.sigma;
if ((flags & SigmaValue) == 0)
image->chromaticity.blue_primary.y=
image->chromaticity.blue_primary.x;
}
break;
}
if (LocaleCompare(attribute,"bordercolor") == 0)
{
(void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
exception);
if (info)
info->image_info->border_color=target_color;
for ( ; image; image=image->next)
image->border_color=target_color;
break;
}
if (info)
SetImageOption(info->image_info,attribute,SvPV(sval,na));
for ( ; image; image=image->next)
{
(void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
(void) SetImageArtifact(image,attribute,SvPV(sval,na));
}
break;
}
case 'C':
case 'c':
{
if (LocaleCompare(attribute,"cache-threshold") == 0)
{
(void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
(void) SetMagickResourceLimit(MapResource,(MagickSizeType)
(2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
break;
}
if (LocaleCompare(attribute,"clip-mask") == 0)
{
Image
*clip_mask;
clip_mask=(Image *) NULL;
if (SvPOK(sval))
clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
for ( ; image; image=image->next)
SetImageMask(image,ReadPixelMask,clip_mask,exception);
break;
}
if (LocaleNCompare(attribute,"colormap",8) == 0)
{
for ( ; image; image=image->next)
{
int
items;
long
i;
if (image->storage_class == DirectClass)
continue;
i=0;
items=sscanf(attribute,"%*[^[][%ld",&i);
(void) items;
if (i > (ssize_t) image->colors)
i%=image->colors;
if ((strchr(SvPV(sval,na),',') == 0) ||
(strchr(SvPV(sval,na),')') != 0))
QueryColorCompliance(SvPV(sval,na),AllCompliance,
image->colormap+i,exception);
else
{
color=image->colormap+i;
pixel.red=color->red;
pixel.green=color->green;
pixel.blue=color->blue;
flags=ParseGeometry(SvPV(sval,na),&geometry_info);
pixel.red=geometry_info.rho;
pixel.green=geometry_info.sigma;
pixel.blue=geometry_info.xi;
color->red=ClampToQuantum(pixel.red);
color->green=ClampToQuantum(pixel.green);
color->blue=ClampToQuantum(pixel.blue);
}
}
break;
}
if (LocaleCompare(attribute,"colorspace") == 0)
{
sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
MagickFalse,SvPV(sval,na)) : SvIV(sval);
if (sp < 0)
{
ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
SvPV(sval,na));
break;
}
for ( ; image; image=image->next)
(void) SetImageColorspace(image,(ColorspaceType) sp,exception);
break;
}
if (LocaleCompare(attribute,"comment") == 0)
{
for ( ; image; image=image->next)
(void) SetImageProperty(image,"Comment",InterpretImageProperties(
info ? info->image_info : (ImageInfo *) NULL,image,
SvPV(sval,na),exception),exception);
break;
}
if (LocaleCompare(attribute,"compression") == 0)
{
sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
MagickFalse,SvPV(sval,na)) : SvIV(sval);
if (sp < 0)
{
ThrowPerlException(exception,OptionError,
"UnrecognizedImageCompression",SvPV(sval,na));
break;
}
if (info)
info->image_info->compression=(CompressionType) sp;
for ( ; image; image=image->next)
image->compression=(CompressionType) sp;
break;
}
if (info)
SetImageOption(info->image_info,attribute,SvPV(sval,na));
for ( ; image; image=image->next)
{
(void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
(void) SetImageArtifact(image,attribute,SvPV(sval,na));
}
break;
}
case 'D':
case 'd':
{
if (LocaleCompare(attribute,"debug") == 0)
{
SetLogEventMask(SvPV(sval,na));
break;
}
if (LocaleCompare(attribute,"delay") == 0)
{
flags=ParseGeometry(SvPV(sval,na),&geometry_info);
for ( ; image; image=image->next)
{
image->delay=(size_t) floor(geometry_info.rho+0.5);
if ((flags & SigmaValue) != 0)
image->ticks_per_second=(ssize_t)
floor(geometry_info.sigma+0.5);
}
break;
}
if (LocaleCompare(attribute,"disk-limit") == 0)
{
MagickSizeType
limit;
limit=MagickResourceInfinity;
if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
100.0);
(void) SetMagickResourceLimit(DiskResource,limit);
break;
}
if (LocaleCompare(attribute,"density") == 0)
{
if (IsGeometry(SvPV(sval,na)) == MagickFalse)
{
ThrowPerlException(exception,OptionError,"MissingGeometry",
SvPV(sval,na));
break;
}
if (info)
(void) CloneString(&info->image_info->density,SvPV(sval,na));
for ( ; image; image=image->next)
{
flags=ParseGeometry(SvPV(sval,na),&geometry_info);
image->resolution.x=geometry_info.rho;
image->resolution.y=geometry_info.sigma;
if ((flags & SigmaValue) == 0)
image->resolution.y=image->resolution.x;
}
break;
}
if (LocaleCompare(attribute,"depth") == 0)
{
if (info)
info->image_info->depth=SvIV(sval);
for ( ; image; image=image->next)
(void) SetImageDepth(image,SvIV(sval),exception);
break;
}
if (LocaleCompare(attribute,"dispose") == 0)
{
sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
SvPV(sval,na)) : SvIV(sval);
if (sp < 0)
{
ThrowPerlException(exception,OptionError,
"UnrecognizedDisposeMethod",SvPV(sval,na));
break;
}
for ( ; image; image=image->next)
image->dispose=(DisposeType) sp;
break;
}
if (LocaleCompare(attribute,"dither") == 0)
{
if (info)
{
sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
MagickFalse,SvPV(sval,na)) : SvIV(sval);
if (sp < 0)
{
ThrowPerlException(exception,OptionError,"UnrecognizedType",
SvPV(sval,na));
break;
}
info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
}
break;
}
if (LocaleCompare(attribute,"display") == 0)
{
display:
if (info)
(void) CloneString(&info->image_info->server_name,SvPV(sval,na));
break;
}
if (info)
SetImageOption(info->image_info,attribute,SvPV(sval,na));
for ( ; image; image=image->next)
{
(void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
(void) SetImageArtifact(image,attribute,SvPV(sval,na));
}
break;
}
case 'E':
case 'e':
{
if (LocaleCompare(attribute,"endian") == 0)
{
sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
SvPV(sval,na)) : SvIV(sval);
if (sp < 0)
{
ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
SvPV(sval,na));
break;
}
if (info)
info->image_info->endian=(EndianType) sp;
for ( ; image; image=image->next)
image->endian=(EndianType) sp;
break;
}
if (LocaleCompare(attribute,"extract") == 0)
{
/*
Set image extract geometry.
*/
(void) CloneString(&info->image_info->extract,SvPV(sval,na));
break;
}
if (info)
SetImageOption(info->image_info,attribute,SvPV(sval,na));
for ( ; image; image=image->next)
{
(void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
(void) SetImageArtifact(image,attribute,SvPV(sval,na));
}
break;
}
case 'F':
case 'f':
{
if (LocaleCompare(attribute,"filename") == 0)
{
if (info)
(void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
MagickPathExtent);
for ( ; image; image=image->next)
(void) CopyMagickString(image->filename,SvPV(sval,na),
MagickPathExtent);
break;
}
if (LocaleCompare(attribute,"file") == 0)
{
FILE
*file;
PerlIO
*io_info;
if (info == (struct PackageInfo *) NULL)
break;
io_info=IoIFP(sv_2io(sval));
if (io_info == (PerlIO *) NULL)
{
ThrowPerlException(exception,BlobError,"UnableToOpenFile",
PackageName);
break;
}
file=PerlIO_findFILE(io_info);
if (file == (FILE *) NULL)
{
ThrowPerlException(exception,BlobError,"UnableToOpenFile",
PackageName);
break;
}
SetImageInfoFile(info->image_info,file);
break;
}
if (LocaleCompare(attribute,"fill") == 0)
{
if (info)
(void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
break;
}
if (LocaleCompare(attribute,"font") == 0)
{
if (info)
(void) CloneString(&info->image_info->font,SvPV(sval,na));
break;
}
if (LocaleCompare(attribute,"foreground") == 0)
break;
if (LocaleCompare(attribute,"fuzz") == 0)
{
if (info)
info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
QuantumRange+1.0);
for ( ; image; image=image->next)
image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
QuantumRange+1.0);
break;
}
if (info)
SetImageOption(info->image_info,attribute,SvPV(sval,na));
for ( ; image; image=image->next)
{
(void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
(void) SetImageArtifact(image,attribute,SvPV(sval,na));
}
break;
}
case 'G':
case 'g':
{
if (LocaleCompare(attribute,"gamma") == 0)
{
for ( ; image; image=image->next)
image->gamma=SvNV(sval);
break;
}
if (LocaleCompare(attribute,"gravity") == 0)
{
sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
SvPV(sval,na)) : SvIV(sval);
if (sp < 0)
{
ThrowPerlException(exception,OptionError,
"UnrecognizedGravityType",SvPV(sval,na));
break;
}
if (info)
SetImageOption(info->image_info,attribute,SvPV(sval,na));
for ( ; image; image=image->next)
image->gravity=(GravityType) sp;
break;
}
if (LocaleCompare(attribute,"green-primary") == 0)
{
for ( ; image; image=image->next)
{
flags=ParseGeometry(SvPV(sval,na),&geometry_info);
image->chromaticity.green_primary.x=geometry_info.rho;
image->chromaticity.green_primary.y=geometry_info.sigma;
if ((flags & SigmaValue) == 0)
image->chromaticity.green_primary.y=
image->chromaticity.green_primary.x;
}
break;
}
if (info)
SetImageOption(info->image_info,attribute,SvPV(sval,na));
for ( ; image; image=image->next)
{
(void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
(void) SetImageArtifact(image,attribute,SvPV(sval,na));
}
break;
}
case 'I':
case 'i':
{
if (LocaleNCompare(attribute,"index",5) == 0)
{
int
items;
long
index;
register Quantum
*q;
CacheView
*image_view;
for ( ; image; image=image->next)
{
if (image->storage_class != PseudoClass)
continue;
x=0;
y=0;
items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
(void) items;
image_view=AcquireAuthenticCacheView(image,exception);
q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
if (q != (Quantum *) NULL)
{
items=sscanf(SvPV(sval,na),"%ld",&index);
if ((index >= 0) && (index < (ssize_t) image->colors))
SetPixelIndex(image,index,q);
(void) SyncCacheViewAuthenticPixels(image_view,exception);
}
image_view=DestroyCacheView(image_view);
}
break;
}
if (LocaleCompare(attribute,"iterations") == 0)
{
iterations:
for ( ; image; image=image->next)
image->iterations=SvIV(sval);
break;
}
if (LocaleCompare(attribute,"interlace") == 0)
{
sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
MagickFalse,SvPV(sval,na)) : SvIV(sval);
if (sp < 0)
{
ThrowPerlException(exception,OptionError,
"UnrecognizedInterlaceType",SvPV(sval,na));
break;
}
if (info)
info->image_info->interlace=(InterlaceType) sp;
for ( ; image; image=image->next)
image->interlace=(InterlaceType) sp;
break;
}
if (info)
SetImageOption(info->image_info,attribute,SvPV(sval,na));
for ( ; image; image=image->next)
{
(void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
(void) SetImageArtifact(image,attribute,SvPV(sval,na));
}
break;
}
case 'L':
case 'l':
{
if (LocaleCompare(attribute,"label") == 0)
{
for ( ; image; image=image->next)
(void) SetImageProperty(image,"label",InterpretImageProperties(
info ? info->image_info : (ImageInfo *) NULL,image,
SvPV(sval,na),exception),exception);
break;
}
if (LocaleCompare(attribute,"loop") == 0)
goto iterations;
if (info)
SetImageOption(info->image_info,attribute,SvPV(sval,na));
for ( ; image; image=image->next)
{
(void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
(void) SetImageArtifact(image,attribute,SvPV(sval,na));
}
break;
}
case 'M':
case 'm':
{
if (LocaleCompare(attribute,"magick") == 0)
{
if (info)
(void) FormatLocaleString(info->image_info->filename,
MagickPathExtent,"%s:",SvPV(sval,na));
for ( ; image; image=image->next)
(void) CopyMagickString(image->magick,SvPV(sval,na),
MagickPathExtent);
break;
}
if (LocaleCompare(attribute,"map-limit") == 0)
{
MagickSizeType
limit;
limit=MagickResourceInfinity;
if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
100.0);
(void) SetMagickResourceLimit(MapResource,limit);
break;
}
if (LocaleCompare(attribute,"mask") == 0)
{
Image
*mask;
mask=(Image *) NULL;
if (SvPOK(sval))
mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
for ( ; image; image=image->next)
SetImageMask(image,ReadPixelMask,mask,exception);
break;
}
if (LocaleCompare(attribute,"mattecolor") == 0)
{
(void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
exception);
if (info)
info->image_info->alpha_color=target_color;
for ( ; image; image=image->next)
image->alpha_color=target_color;
break;
}
if (LocaleCompare(attribute,"matte") == 0)
{
sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
SvPV(sval,na)) : SvIV(sval);
if (sp < 0)
{
ThrowPerlException(exception,OptionError,"UnrecognizedType",
SvPV(sval,na));
break;
}
for ( ; image; image=image->next)
image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
break;
}
if (LocaleCompare(attribute,"memory-limit") == 0)
{
MagickSizeType
limit;
limit=MagickResourceInfinity;
if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
100.0);
(void) SetMagickResourceLimit(MemoryResource,limit);
break;
}
if (LocaleCompare(attribute,"monochrome") == 0)
{
sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
SvPV(sval,na)) : SvIV(sval);
if (sp < 0)
{
ThrowPerlException(exception,OptionError,"UnrecognizedType",
SvPV(sval,na));
break;
}
if (info)
info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
for ( ; image; image=image->next)
(void) SetImageType(image,BilevelType,exception);
break;
}
if (info)
SetImageOption(info->image_info,attribute,SvPV(sval,na));
for ( ; image; image=image->next)
{
(void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
(void) SetImageArtifact(image,attribute,SvPV(sval,na));
}
break;
}
case 'O':
case 'o':
{
if (LocaleCompare(attribute,"option") == 0)
{
if (info)
DefineImageOption(info->image_info,SvPV(sval,na));
break;
}
if (LocaleCompare(attribute,"orientation") == 0)
{
sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
MagickFalse,SvPV(sval,na)) : SvIV(sval);
if (sp < 0)
{
ThrowPerlException(exception,OptionError,
"UnrecognizedOrientationType",SvPV(sval,na));
break;
}
if (info)
info->image_info->orientation=(OrientationType) sp;
for ( ; image; image=image->next)
image->orientation=(OrientationType) sp;
break;
}
if (info)
SetImageOption(info->image_info,attribute,SvPV(sval,na));
for ( ; image; image=image->next)
{
(void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
(void) SetImageArtifact(image,attribute,SvPV(sval,na));
}
break;
}
case 'P':
case 'p':
{
if (LocaleCompare(attribute,"page") == 0)
{
char
*geometry;
geometry=GetPageGeometry(SvPV(sval,na));
if (info)
(void) CloneString(&info->image_info->page,geometry);
for ( ; image; image=image->next)
(void) ParsePageGeometry(image,geometry,&image->page,exception);
geometry=(char *) RelinquishMagickMemory(geometry);
break;
}
if (LocaleNCompare(attribute,"pixel",5) == 0)
{
int
items;
PixelInfo
pixel;
register Quantum
*q;
CacheView
*image_view;
for ( ; image; image=image->next)
{
if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
break;
x=0;
y=0;
items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
(void) items;
image_view=AcquireVirtualCacheView(image,exception);
q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
if (q != (Quantum *) NULL)
{
if ((strchr(SvPV(sval,na),',') == 0) ||
(strchr(SvPV(sval,na),')') != 0))
QueryColorCompliance(SvPV(sval,na),AllCompliance,
&pixel,exception);
else
{
GetPixelInfo(image,&pixel);
flags=ParseGeometry(SvPV(sval,na),&geometry_info);
pixel.red=geometry_info.rho;
if ((flags & SigmaValue) != 0)
pixel.green=geometry_info.sigma;
if ((flags & XiValue) != 0)
pixel.blue=geometry_info.xi;
if ((flags & PsiValue) != 0)
pixel.alpha=geometry_info.psi;
if ((flags & ChiValue) != 0)
pixel.black=geometry_info.chi;
}
SetPixelRed(image,ClampToQuantum(pixel.red),q);
SetPixelGreen(image,ClampToQuantum(pixel.green),q);
SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
if (image->colorspace == CMYKColorspace)
SetPixelBlack(image,ClampToQuantum(pixel.black),q);
SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
(void) SyncCacheViewAuthenticPixels(image_view,exception);
}
image_view=DestroyCacheView(image_view);
}
break;
}
if (LocaleCompare(attribute,"pointsize") == 0)
{
if (info)
{
(void) ParseGeometry(SvPV(sval,na),&geometry_info);
info->image_info->pointsize=geometry_info.rho;
}
break;
}
if (info)
SetImageOption(info->image_info,attribute,SvPV(sval,na));
for ( ; image; image=image->next)
{
(void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
(void) SetImageArtifact(image,attribute,SvPV(sval,na));
}
break;
}
case 'Q':
case 'q':
{
if (LocaleCompare(attribute,"quality") == 0)
{
if (info)
info->image_info->quality=SvIV(sval);
for ( ; image; image=image->next)
image->quality=SvIV(sval);
break;
}
if (info)
SetImageOption(info->image_info,attribute,SvPV(sval,na));
for ( ; image; image=image->next)
{
(void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
(void) SetImageArtifact(image,attribute,SvPV(sval,na));
}
break;
}
case 'R':
case 'r':
{
if (LocaleCompare(attribute,"read-mask") == 0)
{
Image
*mask;
mask=(Image *) NULL;
if (SvPOK(sval))
mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
for ( ; image; image=image->next)
SetImageMask(image,ReadPixelMask,mask,exception);
break;
}
if (LocaleCompare(attribute,"red-primary") == 0)
{
for ( ; image; image=image->next)
{
flags=ParseGeometry(SvPV(sval,na),&geometry_info);
image->chromaticity.red_primary.x=geometry_info.rho;
image->chromaticity.red_primary.y=geometry_info.sigma;
if ((flags & SigmaValue) == 0)
image->chromaticity.red_primary.y=
image->chromaticity.red_primary.x;
}
break;
}
if (LocaleCompare(attribute,"render") == 0)
{
sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
SvPV(sval,na)) : SvIV(sval);
if (sp < 0)
{
ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
SvPV(sval,na));
break;
}
for ( ; image; image=image->next)
image->rendering_intent=(RenderingIntent) sp;
break;
}
if (LocaleCompare(attribute,"repage") == 0)
{
RectangleInfo
geometry;
for ( ; image; image=image->next)
{
flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
if ((flags & WidthValue) != 0)
{
if ((flags & HeightValue) == 0)
geometry.height=geometry.width;
image->page.width=geometry.width;
image->page.height=geometry.height;
}
if ((flags & AspectValue) != 0)
{
if ((flags & XValue) != 0)
image->page.x+=geometry.x;
if ((flags & YValue) != 0)
image->page.y+=geometry.y;
}
else
{
if ((flags & XValue) != 0)
{
image->page.x=geometry.x;
if (((flags & WidthValue) != 0) && (geometry.x > 0))
image->page.width=image->columns+geometry.x;
}
if ((flags & YValue) != 0)
{
image->page.y=geometry.y;
if (((flags & HeightValue) != 0) && (geometry.y > 0))
image->page.height=image->rows+geometry.y;
}
}
}
break;
}
if (info)
SetImageOption(info->image_info,attribute,SvPV(sval,na));
for ( ; image; image=image->next)
{
(void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
(void) SetImageArtifact(image,attribute,SvPV(sval,na));
}
break;
}
case 'S':
case 's':
{
if (LocaleCompare(attribute,"sampling-factor") == 0)
{
if (IsGeometry(SvPV(sval,na)) == MagickFalse)
{
ThrowPerlException(exception,OptionError,"MissingGeometry",
SvPV(sval,na));
break;
}
if (info)
(void) CloneString(&info->image_info->sampling_factor,
SvPV(sval,na));
break;
}
if (LocaleCompare(attribute,"scene") == 0)
{
for ( ; image; image=image->next)
image->scene=SvIV(sval);
break;
}
if (LocaleCompare(attribute,"server") == 0)
goto display;
if (LocaleCompare(attribute,"size") == 0)
{
if (info)
{
if (IsGeometry(SvPV(sval,na)) == MagickFalse)
{
ThrowPerlException(exception,OptionError,"MissingGeometry",
SvPV(sval,na));
break;
}
(void) CloneString(&info->image_info->size,SvPV(sval,na));
}
break;
}
if (LocaleCompare(attribute,"stroke") == 0)
{
if (info)
(void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
break;
}
if (info)
SetImageOption(info->image_info,attribute,SvPV(sval,na));
for ( ; image; image=image->next)
{
(void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
(void) SetImageArtifact(image,attribute,SvPV(sval,na));
}
break;
}
case 'T':
case 't':
{
if (LocaleCompare(attribute,"texture") == 0)
{
if (info)
(void) CloneString(&info->image_info->texture,SvPV(sval,na));
break;
}
if (LocaleCompare(attribute,"thread-limit") == 0)
{
MagickSizeType
limit;
limit=MagickResourceInfinity;
if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
100.0);
(void) SetMagickResourceLimit(ThreadResource,limit);
break;
}
if (LocaleCompare(attribute,"tile-offset") == 0)
{
char
*geometry;
geometry=GetPageGeometry(SvPV(sval,na));
if (info)
(void) CloneString(&info->image_info->page,geometry);
for ( ; image; image=image->next)
(void) ParsePageGeometry(image,geometry,&image->tile_offset,
exception);
geometry=(char *) RelinquishMagickMemory(geometry);
break;
}
if (LocaleCompare(attribute,"time-limit") == 0)
{
MagickSizeType
limit;
limit=MagickResourceInfinity;
if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
100.0);
(void) SetMagickResourceLimit(TimeResource,limit);
break;
}
if (LocaleCompare(attribute,"transparent-color") == 0)
{
(void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
exception);
if (info)
info->image_info->transparent_color=target_color;
for ( ; image; image=image->next)
image->transparent_color=target_color;
break;
}
if (LocaleCompare(attribute,"type") == 0)
{
sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
SvPV(sval,na)) : SvIV(sval);
if (sp < 0)
{
ThrowPerlException(exception,OptionError,"UnrecognizedType",
SvPV(sval,na));
break;
}
if (info)
info->image_info->type=(ImageType) sp;
for ( ; image; image=image->next)
SetImageType(image,(ImageType) sp,exception);
break;
}
if (info)
SetImageOption(info->image_info,attribute,SvPV(sval,na));
for ( ; image; image=image->next)
{
(void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
(void) SetImageArtifact(image,attribute,SvPV(sval,na));
}
break;
}
case 'U':
case 'u':
{
if (LocaleCompare(attribute,"units") == 0)
{
sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
MagickFalse,SvPV(sval,na)) : SvIV(sval);
if (sp < 0)
{
ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
SvPV(sval,na));
break;
}
if (info)
info->image_info->units=(ResolutionType) sp;
for ( ; image; image=image->next)
{
ResolutionType
units;
units=(ResolutionType) sp;
if (image->units != units)
switch (image->units)
{
case UndefinedResolution:
case PixelsPerInchResolution:
{
if (units == PixelsPerCentimeterResolution)
{
image->resolution.x*=2.54;
image->resolution.y*=2.54;
}
break;
}
case PixelsPerCentimeterResolution:
{
if (units == PixelsPerInchResolution)
{
image->resolution.x/=2.54;
image->resolution.y/=2.54;
}
break;
}
}
image->units=units;
}
break;
}
if (info)
SetImageOption(info->image_info,attribute,SvPV(sval,na));
for ( ; image; image=image->next)
{
(void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
(void) SetImageArtifact(image,attribute,SvPV(sval,na));
}
break;
}
case 'V':
case 'v':
{
if (LocaleCompare(attribute,"verbose") == 0)
{
sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
SvPV(sval,na)) : SvIV(sval);
if (sp < 0)
{
ThrowPerlException(exception,OptionError,"UnrecognizedType",
SvPV(sval,na));
break;
}
if (info)
info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
break;
}
if (LocaleCompare(attribute,"virtual-pixel") == 0)
{
sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
MagickFalse,SvPV(sval,na)) : SvIV(sval);
if (sp < 0)
{
ThrowPerlException(exception,OptionError,
"UnrecognizedVirtualPixelMethod",SvPV(sval,na));
break;
}
for ( ; image; image=image->next)
SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
break;
}
if (info)
SetImageOption(info->image_info,attribute,SvPV(sval,na));
for ( ; image; image=image->next)
{
(void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
(void) SetImageArtifact(image,attribute,SvPV(sval,na));
}
break;
}
case 'W':
case 'w':
{
if (LocaleCompare(attribute,"white-point") == 0)
{
for ( ; image; image=image->next)
{
flags=ParseGeometry(SvPV(sval,na),&geometry_info);
image->chromaticity.white_point.x=geometry_info.rho;
image->chromaticity.white_point.y=geometry_info.sigma;
if ((flags & SigmaValue) == 0)
image->chromaticity.white_point.y=
image->chromaticity.white_point.x;
}
break;
}
if (LocaleCompare(attribute,"write-mask") == 0)
{
Image
*mask;
mask=(Image *) NULL;
if (SvPOK(sval))
mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
for ( ; image; image=image->next)
SetImageMask(image,WritePixelMask,mask,exception);
break;
}
if (info)
SetImageOption(info->image_info,attribute,SvPV(sval,na));
for ( ; image; image=image->next)
{
(void) SetImageProperty(image,attribute,SvPV(sval,na),exception);