diff -urN ImageMagick-6.9.7-0/PerlMagick/Magick.pm ImageMagick-6.9.6-6/PerlMagick/Magick.pm --- ImageMagick-6.9.7-0/PerlMagick/Magick.pm 1970-01-01 01:00:00.000000000 +0100 +++ ImageMagick-6.9.6-6/PerlMagick/Magick.pm 2016-11-25 16:58:55.000000000 +0100 @@ -0,0 +1,144 @@ +package Image::Magick; + +# Copyright 1999-2016 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 +# +# http://www.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. +# +# Initial version, written by Kyle Shorter. + +use strict; +use Carp; +use vars qw($VERSION @ISA @EXPORT $AUTOLOAD); + +require 5.002; +require Exporter; +require DynaLoader; +require AutoLoader; + +@ISA = qw(Exporter DynaLoader); +# Items to export into callers namespace by default. Note: do not export +# names by default without a very good reason. Use EXPORT_OK instead. +# Do not simply export all your public functions/methods/constants. +@EXPORT = + qw( + Success Transparent Opaque QuantumDepth QuantumRange MaxRGB + WarningException ResourceLimitWarning TypeWarning OptionWarning + DelegateWarning MissingDelegateWarning CorruptImageWarning + FileOpenWarning BlobWarning StreamWarning CacheWarning CoderWarning + ModuleWarning DrawWarning ImageWarning XServerWarning RegistryWarning + ConfigureWarning ErrorException ResourceLimitError TypeError + OptionError DelegateError MissingDelegateError CorruptImageError + FileOpenError BlobError StreamError CacheError CoderError + ModuleError DrawError ImageError XServerError RegistryError + ConfigureError FatalErrorException + ); + +$VERSION = '6.96'; + +sub AUTOLOAD { + # This AUTOLOAD is used to 'autoload' constants from the constant() + # XS function. If a constant is not found then control is passed + # to the AUTOLOAD in AutoLoader. + + my $constname; + ($constname = $AUTOLOAD) =~ s/.*:://; + die "&${AUTOLOAD} not defined. The required ImageMagick libraries are not installed or not installed properly.\n" if $constname eq 'constant'; + my $val = constant($constname, @_ ? $_[0] : 0); + if ($! != 0) { + if ($! =~ /Invalid/) { + $AutoLoader::AUTOLOAD = $AUTOLOAD; + goto &AutoLoader::AUTOLOAD; + } + else { + my($pack,$file,$line) = caller; + die "Your vendor has not defined PerlMagick macro $pack\:\:$constname, used at $file line $line.\n"; + } + } + eval "sub $AUTOLOAD { $val }"; + goto &$AUTOLOAD; +} + +bootstrap Image::Magick $VERSION; + +# Preloaded methods go here. + +sub new +{ + my $this = shift; + my $class = ref($this) || $this || "Image::Magick"; + my $self = [ ]; + bless $self, $class; + $self->set(@_) if @_; + return $self; +} + +sub New +{ + my $this = shift; + my $class = ref($this) || $this || "Image::Magick"; + my $self = [ ]; + bless $self, $class; + $self->set(@_) if @_; + return $self; +} + +# Autoload methods go after =cut, and are processed by the autosplit program. + +END { UNLOAD () }; + +1; +__END__ + +=head1 NAME + +Image::Magick - objected-oriented Perl interface to ImageMagick. Use it to create, edit, compose, or convert bitmap images from within a Perl script. + +=head1 SYNOPSIS + + use Image::Magick; + $p = new Image::Magick; + $p->Read("imagefile"); + $p->Set(attribute => value, ...) + ($a, ...) = $p->Get("attribute", ...) + $p->routine(parameter => value, ...) + $p->Mogrify("Routine", parameter => value, ...) + $p->Write("filename"); + +=head1 DESCRIPTION + +This Perl extension allows the reading, manipulation and writing of +a large number of image file formats using the ImageMagick library. +It was originally developed to be used by CGI scripts for Web pages. + +A web page has been set up for this extension. See: + + file:///usr/share/doc/ImageMagick-6.8.0/www/perl-magick.html + http://www.imagemagick.org/script/perl-magick.php + +If you have problems, go to + + http://www.imagemagick.org/discourse-server/viewforum.php?f=7 + +=head1 AUTHOR + +Kyle Shorter magick-users@imagemagick.org + +=head1 BUGS + +Has all the bugs of ImageMagick and much, much more! + +=head1 SEE ALSO + +perl(1). + +=cut diff -urN ImageMagick-6.9.7-0/PerlMagick/Magick.xs ImageMagick-6.9.6-6/PerlMagick/Magick.xs --- ImageMagick-6.9.7-0/PerlMagick/Magick.xs 1970-01-01 01:00:00.000000000 +0100 +++ ImageMagick-6.9.6-6/PerlMagick/Magick.xs 2016-11-25 16:58:55.000000000 +0100 @@ -0,0 +1,14450 @@ +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% 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-2016 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 % +% % +% http://www.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 "EXTERN.h" +#include "perl.h" +#include "XSUB.h" +#include +#include +#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 33 +#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[MaxTextExtent]; \ + \ + if ((exception)->severity != UndefinedException) \ + { \ + (void) FormatLocaleString(message,MaxTextExtent,"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 +{ + 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; + + MagickRealType + 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}, + {"channel", MagickChannelOptions} } }, + { "Colorize", { {"fill", StringReference}, {"opacity", 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", }, + { "Edge", { {"radius", RealReference} } }, + { "Emboss", { {"geometry", StringReference}, {"radius", RealReference}, + {"sigma", RealReference} } }, + { "Enhance", }, + { "Flip", }, + { "Flop", }, + { "Frame", { {"geometry", StringReference}, {"width", IntegerReference}, + {"height", IntegerReference}, {"inner", IntegerReference}, + {"outer", IntegerReference}, {"fill", StringReference}, + {"color", StringReference}, {"compose", MagickComposeOptions} } }, + { "Implode", { {"amount", RealReference}, + {"interpolate", MagickInterpolateOptions} } }, + { "Magnify", }, + { "MedianFilter", { {"geometry", StringReference}, + {"width", IntegerReference},{"height", IntegerReference}, + {"channel", MagickChannelOptions} } }, + { "Minify", }, + { "OilPaint", { {"radius", RealReference} } }, + { "ReduceNoise", { {"geometry", StringReference}, + {"width", IntegerReference},{"height", IntegerReference}, + {"channel", MagickChannelOptions} } }, + { "Roll", { {"geometry", StringReference}, {"x", IntegerReference}, + {"y", IntegerReference} } }, + { "Rotate", { {"degrees", RealReference}, {"fill", StringReference}, + {"color", StringReference}, {"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 }, {"blur", RealReference } } }, + { "Zoom", { {"geometry", StringReference}, {"width", IntegerReference}, + {"height", IntegerReference}, {"filter", MagickFilterOptions}, + {"support", RealReference }, {"blur", RealReference } } }, + { "Annotate", { {"text", StringReference}, {"font", StringReference}, + {"pointsize", RealReference}, {"density", StringReference}, + {"undercolor", StringReference}, {"stroke", StringReference}, + {"fill", StringReference}, {"geometry", StringReference}, + {"pen", 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} } }, + { "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} } }, + { "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", MagickBooleanOptions}, + {"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", }, + { "Opaque", { {"color", StringReference}, {"fill", StringReference}, + {"fuzz", StringReference}, {"channel", MagickChannelOptions}, + {"invert", MagickBooleanOptions} } }, + { "Quantize", { {"colors", IntegerReference}, + {"treedepth", IntegerReference}, {"colorspace", MagickColorspaceOptions}, + {"dither", MagickBooleanOptions}, {"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", }, + { "Solarize", { {"geometry", StringReference}, + {"threshold", StringReference}, {"channel", MagickChannelOptions} } }, + { "Sync", }, + { "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", }, + { "Stereo", { {"image", ImageReference}, {"x", IntegerReference}, + {"y", IntegerReference} } }, + { "Stegano", { {"image", ImageReference}, {"offset", IntegerReference} } }, + { "Deconstruct", }, + { "GaussianBlur", { {"geometry", StringReference}, + {"radius", RealReference}, {"sigma", RealReference}, + {"channel", MagickChannelOptions} } }, + { "Convolve", { {"coefficients", ArrayReference}, + {"channel", MagickChannelOptions}, {"bias", StringReference} } }, + { "Profile", { {"name", StringReference}, {"profile", StringReference}, + { "rendering-intent", MagickIntentOptions}, + { "black-point-compensation", MagickBooleanOptions} } }, + { "UnsharpMask", { {"geometry", StringReference}, + {"radius", RealReference}, {"sigma", RealReference}, + {"amount", 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}, + {"offset", IntegerReference} } }, + { "Resample", { {"density", StringReference}, {"x", RealReference}, + {"y", RealReference}, {"filter", MagickFilterOptions}, + {"support", RealReference }, {"blur", 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", }, + { "Tint", { {"fill", StringReference}, {"opacity", 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}, {"opacity", 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", }, + { "Sans1", }, + { "AdaptiveSharpen", { {"geometry", StringReference}, + {"radius", RealReference}, {"sigma", RealReference}, + {"channel", MagickChannelOptions} } }, + { "Transpose", }, + { "Transverse", }, + { "AutoOrient", }, + { "AdaptiveBlur", { {"geometry", StringReference}, + {"radius", RealReference}, {"sigma", RealReference}, + {"channel", MagickChannelOptions} } }, + { "Sketch", { {"geometry", StringReference}, + {"radius", RealReference}, {"sigma", RealReference}, + {"angle", RealReference} } }, + { "UniqueColors", }, + { "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} } }, + { "Recolor", { {"matrix", ArrayReference} } }, + { "Mask", { {"mask", ImageReference} } }, + { "Polaroid", { {"caption", StringReference}, {"angle", RealReference}, + {"font", StringReference}, {"stroke", StringReference}, + {"fill", StringReference}, {"strokewidth", RealReference}, + {"pointsize", RealReference}, {"gravity", MagickGravityOptions}, + {"background", StringReference} } }, + { "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}, + {"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", MagickBooleanOptions}, + {"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} } }, + { "Filter", { {"kernel", StringReference}, + {"channel", MagickChannelOptions}, {"bias", StringReference} } }, + { "BrightnessContrast", { {"levels", StringReference}, + {"brightness", RealReference},{"contrast", RealReference}, + {"channel", MagickChannelOptions} } }, + { "Morphology", { {"kernel", StringReference}, + {"channel", MagickChannelOptions}, {"method", MagickMorphologyOptions}, + {"iterations", IntegerReference} } }, + { "ColorMatrix", { {"matrix", ArrayReference} } }, + { "Color", { {"color", StringReference} } }, + { "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", MagickPixelIntensityOptions} } }, + { "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} } }, + { "WaveletDenoise", { {"geometry", StringReference}, + {"threshold", RealReference}, {"softness", 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(OpaqueOpacity); + 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(TransparentOpacity); + 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[MaxTextExtent]; + + struct PackageInfo + *clone_info; + + SV + *sv; + + (void) FormatLocaleString(message,MaxTextExtent,"%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; + + MagickPixelPacket + pixel; + + MagickStatusType + flags; + + PixelPacket + *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(MagickAlphaOptions,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,(AlphaChannelType) sp); + 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) + (void) CloneString(&info->image_info->authenticate,SvPV(sval,na)); + break; + } + if (info) + SetImageOption(info->image_info,attribute,SvPV(sval,na)); + for ( ; image; image=image->next) + SetImageProperty(image,attribute,SvPV(sval,na)); + break; + } + case 'B': + case 'b': + { + if (LocaleCompare(attribute,"background") == 0) + { + (void) QueryColorDatabase(SvPV(sval,na),&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,"bias") == 0) + { + for ( ; image; image=image->next) + image->bias=StringToDoubleInterval(SvPV(sval,na),(double) + QuantumRange+1.0); + 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) QueryColorDatabase(SvPV(sval,na),&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) + SetImageProperty(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) + SetImageClipMask(image,clip_mask); + 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)) + QueryColorDatabase(SvPV(sval,na),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) TransformImageColorspace(image,(ColorspaceType) sp); + 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))); + 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) + SetImageProperty(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->x_resolution=geometry_info.rho; + image->y_resolution=geometry_info.sigma; + if ((flags & SigmaValue) == 0) + image->y_resolution=image->x_resolution; + } + break; + } + if (LocaleCompare(attribute,"depth") == 0) + { + if (info) + info->image_info->depth=SvIV(sval); + for ( ; image; image=image->next) + (void) SetImageDepth(image,SvIV(sval)); + 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) + SetImageProperty(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) + SetImageProperty(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), + MaxTextExtent); + for ( ; image; image=image->next) + (void) CopyMagickString(image->filename,SvPV(sval,na), + MaxTextExtent); + 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) + SetImageProperty(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) + SetImageProperty(image,attribute,SvPV(sval,na)); + break; + } + case 'I': + case 'i': + { + if (LocaleNCompare(attribute,"index",5) == 0) + { + IndexPacket + *indexes; + + int + items; + + long + index; + + register PixelPacket + *p; + + 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); + p=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception); + if (p != (PixelPacket *) NULL) + { + indexes=GetCacheViewAuthenticIndexQueue(image_view); + items=sscanf(SvPV(sval,na),"%ld",&index); + if ((index >= 0) && (index < (ssize_t) image->colors)) + SetPixelIndex(indexes,index); + (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) + SetImageProperty(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))); + break; + } + if (LocaleCompare(attribute,"loop") == 0) + goto iterations; + if (info) + SetImageOption(info->image_info,attribute,SvPV(sval,na)); + for ( ; image; image=image->next) + SetImageProperty(image,attribute,SvPV(sval,na)); + break; + } + case 'M': + case 'm': + { + if (LocaleCompare(attribute,"magick") == 0) + { + if (info) + (void) FormatLocaleString(info->image_info->filename,MaxTextExtent, + "%s:",SvPV(sval,na)); + for ( ; image; image=image->next) + (void) CopyMagickString(image->magick,SvPV(sval,na),MaxTextExtent); + 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,mask); + break; + } + if (LocaleCompare(attribute,"mattecolor") == 0) + { + (void) QueryColorDatabase(SvPV(sval,na),&target_color,exception); + if (info) + info->image_info->matte_color=target_color; + for ( ; image; image=image->next) + image->matte_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->matte=sp != 0 ? MagickTrue : MagickFalse; + 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); + break; + } + if (info) + SetImageOption(info->image_info,attribute,SvPV(sval,na)); + for ( ; image; image=image->next) + SetImageProperty(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) + SetImageProperty(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 (LocaleCompare(attribute,"pen") == 0) + { + if (info) + (void) SetImageOption(info->image_info,"fill",SvPV(sval,na)); + break; + } + if (LocaleNCompare(attribute,"pixel",5) == 0) + { + int + items; + + MagickPixelPacket + pixel; + + register IndexPacket + *indexes; + + register PixelPacket + *q; + + CacheView + *image_view; + + for ( ; image; image=image->next) + { + if (SetImageStorageClass(image,DirectClass) == MagickFalse) + break; + 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); + indexes=GetCacheViewAuthenticIndexQueue(image_view); + if (q != (PixelPacket *) NULL) + { + if ((strchr(SvPV(sval,na),',') == 0) || + (strchr(SvPV(sval,na),')') != 0)) + QueryMagickColor(SvPV(sval,na),&pixel,exception); + else + { + GetMagickPixelPacket(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.opacity=geometry_info.psi; + if ((flags & ChiValue) != 0) + pixel.index=geometry_info.chi; + } + SetPixelRed(q,ClampToQuantum(pixel.red)); + SetPixelGreen(q,ClampToQuantum(pixel.green)); + SetPixelBlue(q,ClampToQuantum(pixel.blue)); + SetPixelOpacity(q,ClampToQuantum(pixel.opacity)); + if (((image->colorspace == CMYKColorspace) || + (image->storage_class == PseudoClass)) && + (indexes != (IndexPacket *) NULL)) + SetPixelIndex(indexes,ClampToQuantum(pixel.index)); + (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 (LocaleCompare(attribute,"preview") == 0) + { + sp=SvPOK(sval) ? ParseCommandOption(MagickPreviewOptions,MagickFalse, + SvPV(sval,na)) : SvIV(sval); + if (sp < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(sval,na)); + break; + } + if (info) + info->image_info->preview_type=(PreviewType) sp; + break; + } + if (info) + SetImageOption(info->image_info,attribute,SvPV(sval,na)); + for ( ; image; image=image->next) + SetImageProperty(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) + SetImageProperty(image,attribute,SvPV(sval,na)); + break; + } + case 'R': + case 'r': + { + 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) + SetImageProperty(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,"subimage") == 0) + { + if (info) + info->image_info->subimage=SvIV(sval); + break; + } + if (LocaleCompare(attribute,"subrange") == 0) + { + if (info) + info->image_info->subrange=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) + SetImageProperty(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") == 0) + { + if (info) + (void) CloneString(&info->image_info->tile,SvPV(sval,na)); + 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) QueryColorDatabase(SvPV(sval,na),&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); + break; + } + if (info) + SetImageOption(info->image_info,attribute,SvPV(sval,na)); + for ( ; image; image=image->next) + SetImageProperty(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->x_resolution*=2.54; + image->y_resolution*=2.54; + } + break; + } + case PixelsPerCentimeterResolution: + { + if (units == PixelsPerInchResolution) + { + image->x_resolution/=2.54; + image->y_resolution/=2.54; + } + break; + } + } + image->units=units; + } + break; + } + if (info) + SetImageOption(info->image_info,attribute,SvPV(sval,na)); + for ( ; image; image=image->next) + SetImageProperty(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,"view") == 0) + { + if (info) + (void) CloneString(&info->image_info->view,SvPV(sval,na)); + 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; + } + if (info) + info->image_info->virtual_pixel_method=(VirtualPixelMethod) sp; + for ( ; image; image=image->next) + SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp); + break; + } + if (info) + SetImageOption(info->image_info,attribute,SvPV(sval,na)); + for ( ; image; image=image->next) + SetImageProperty(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 (info) + SetImageOption(info->image_info,attribute,SvPV(sval,na)); + for ( ; image; image=image->next) + SetImageProperty(image,attribute,SvPV(sval,na)); + break; + } + default: + { + if (info) + SetImageOption(info->image_info,attribute,SvPV(sval,na)); + for ( ; image; image=image->next) + SetImageProperty(image,attribute,SvPV(sval,na)); + break; + } + } +} + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % +% S e t u p L i s t % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Method SetupList returns the list of all the images linked by their +% image->next and image->previous link lists for use with ImageMagick. If +% info is non-NULL, an info structure is returned in *info. If +% reference_vector is non-NULL,an array of SV* are returned in +% *reference_vector. Reference_vector is used when the images are going to be +% replaced with new Image*'s. +% +% The format of the SetupList routine is: +% +% Image *SetupList(SV *reference,struct PackageInfo **info, +% SV ***reference_vector,ExceptionInfo *exception) +% +% A description of each parameter follows: +% +% o list: a list of strings. +% +% o string: a character string. +% +% o exception: Return any errors or warnings in this structure. +% +*/ +static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info, + SV ***reference_vector,ExceptionInfo *exception) +{ + Image + *image; + + ssize_t + current, + last; + + if (reference_vector) + *reference_vector=NULL; + if (info) + *info=NULL; + current=0; + last=0; + image=GetList(aTHX_ reference,reference_vector,¤t,&last,exception); + if (info && (SvTYPE(reference) == SVt_PVAV)) + *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL, + exception); + return(image); +} + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % +% s t r E Q c a s e % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% strEQcase() compares two strings and returns 0 if they are the +% same or if the second string runs out first. The comparison is case +% insensitive. +% +% The format of the strEQcase routine is: +% +% ssize_t strEQcase(const char *p,const char *q) +% +% A description of each parameter follows: +% +% o p: a character string. +% +% o q: a character string. +% +% +*/ +static ssize_t strEQcase(const char *p,const char *q) +{ + char + c; + + register ssize_t + i; + + for (i=0 ; (c=(*q)) != 0; i++) + { + if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) != + (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p)) + return(0); + p++; + q++; + } + return(((*q == 0) && (*p == 0)) ? i : 0); +} + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % +% I m a g e : : M a g i c k % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% +*/ +MODULE = Image::Magick PACKAGE = Image::Magick + +PROTOTYPES: ENABLE + +BOOT: + MagickCoreGenesis("PerlMagick",MagickFalse); + SetWarningHandler(NULL); + SetErrorHandler(NULL); + magick_registry=NewSplayTree((int (*)(const void *,const void *)) + NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL); + +void +UNLOAD() + PPCODE: + { + if (magick_registry != (SplayTreeInfo *) NULL) + magick_registry=DestroySplayTree(magick_registry); + MagickCoreTerminus(); + } + +double +constant(name,argument) + char *name + ssize_t argument + +# +############################################################################### +# # +# # +# # +# A n i m a t e # +# # +# # +# # +############################################################################### +# +# +void +Animate(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + AnimateImage = 1 + animate = 2 + animateimage = 3 + PPCODE: + { + ExceptionInfo + *exception; + + Image + *image; + + register ssize_t + i; + + struct PackageInfo + *info, + *package_info; + + SV + *perl_exception, + *reference; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + package_info=(struct PackageInfo *) NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + package_info=ClonePackageInfo(info,exception); + if (items == 2) + SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception); + else + if (items > 2) + for (i=2; i < items; i+=2) + SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i), + exception); + (void) AnimateImages(package_info->image_info,image); + (void) CatchImageException(image); + InheritException(exception,&image->exception); + + PerlException: + if (package_info != (struct PackageInfo *) NULL) + DestroyPackageInfo(package_info); + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0); + SvPOK_on(perl_exception); + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# A p p e n d # +# # +# # +# # +############################################################################### +# +# +void +Append(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + AppendImage = 1 + append = 2 + appendimage = 3 + PPCODE: + { + AV + *av; + + char + *attribute; + + ExceptionInfo + *exception; + + HV + *hv; + + Image + *image; + + register ssize_t + i; + + ssize_t + stack; + + struct PackageInfo + *info; + + SV + *av_reference, + *perl_exception, + *reference, + *rv, + *sv; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + sv=NULL; + attribute=NULL; + av=NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + hv=SvSTASH(reference); + av=newAV(); + av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv)); + SvREFCNT_dec(av); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + info=GetPackageInfo(aTHX_ (void *) av,info,exception); + /* + Get options. + */ + stack=MagickTrue; + for (i=2; i < items; i+=2) + { + attribute=(char *) SvPV(ST(i-1),na); + switch (*attribute) + { + case 'S': + case 's': + { + if (LocaleCompare(attribute,"stack") == 0) + { + stack=ParseCommandOption(MagickBooleanOptions,MagickFalse, + SvPV(ST(i),na)); + if (stack < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(ST(i),na)); + return; + } + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + default: + { + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + } + } + image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception); + if (image == (Image *) NULL) + goto PerlException; + for ( ; image; image=image->next) + { + AddImageToRegistry(sv,image); + rv=newRV(sv); + av_push(av,sv_bless(rv,hv)); + SvREFCNT_dec(sv); + } + exception=DestroyExceptionInfo(exception); + ST(0)=av_reference; + SvREFCNT_dec(perl_exception); + XSRETURN(1); + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0); + SvPOK_on(perl_exception); + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# A v e r a g e # +# # +# # +# # +############################################################################### +# +# +void +Average(ref) + Image::Magick ref = NO_INIT + ALIAS: + AverageImage = 1 + average = 2 + averageimage = 3 + PPCODE: + { + AV + *av; + + char + *p; + + ExceptionInfo + *exception; + + HV + *hv; + + Image + *image; + + struct PackageInfo + *info; + + SV + *perl_exception, + *reference, + *rv, + *sv; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + sv=NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + hv=SvSTASH(reference); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + image=EvaluateImages(image,MeanEvaluateOperator,exception); + if (image == (Image *) NULL) + goto PerlException; + /* + Create blessed Perl array for the returned image. + */ + av=newAV(); + ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv)); + SvREFCNT_dec(av); + AddImageToRegistry(sv,image); + rv=newRV(sv); + av_push(av,sv_bless(rv,hv)); + SvREFCNT_dec(sv); + info=GetPackageInfo(aTHX_ (void *) av,info,exception); + (void) FormatLocaleString(info->image_info->filename,MaxTextExtent, + "average-%.*s",(int) (MaxTextExtent-9), + ((p=strrchr(image->filename,'/')) ? p+1 : image->filename)); + (void) CopyMagickString(image->filename,info->image_info->filename, + MaxTextExtent); + SetImageInfo(info->image_info,0,exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); + XSRETURN(1); + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0); + SvPOK_on(perl_exception); + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# B l o b T o I m a g e # +# # +# # +# # +############################################################################### +# +# +void +BlobToImage(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + BlobToImage = 1 + blobtoimage = 2 + blobto = 3 + PPCODE: + { + AV + *av; + + char + **keep, + **list; + + ExceptionInfo + *exception; + + HV + *hv; + + Image + *image; + + register char + **p; + + register ssize_t + i; + + ssize_t + ac, + n, + number_images; + + STRLEN + *length; + + struct PackageInfo + *info; + + SV + *perl_exception, + *reference, + *rv, + *sv; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + sv=NULL; + number_images=0; + ac=(items < 2) ? 1 : items-1; + length=(STRLEN *) NULL; + list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list)); + if (list == (char **) NULL) + { + ThrowPerlException(exception,ResourceLimitError, + "MemoryAllocationFailed",PackageName); + goto PerlException; + } + length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length)); + if (length == (STRLEN *) NULL) + { + ThrowPerlException(exception,ResourceLimitError, + "MemoryAllocationFailed",PackageName); + goto PerlException; + } + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + hv=SvSTASH(reference); + if (SvTYPE(reference) != SVt_PVAV) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + av=(AV *) reference; + info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL, + exception); + n=1; + if (items <= 1) + { + ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName); + goto PerlException; + } + for (n=0, i=0; i < ac; i++) + { + list[n]=(char *) (SvPV(ST(i+1),length[n])); + if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob")) + { + list[n]=(char *) (SvPV(ST(i+2),length[n])); + continue; + } + n++; + } + list[n]=(char *) NULL; + keep=list; + for (i=number_images=0; i < n; i++) + { + image=BlobToImage(info->image_info,list[i],length[i],exception); + if (image == (Image *) NULL) + break; + for ( ; image; image=image->next) + { + AddImageToRegistry(sv,image); + rv=newRV(sv); + av_push(av,sv_bless(rv,hv)); + SvREFCNT_dec(sv); + number_images++; + } + } + /* + Free resources. + */ + for (i=0; i < n; i++) + if (list[i] != (char *) NULL) + for (p=keep; list[i] != *p++; ) + if (*p == (char *) NULL) + { + list[i]=(char *) RelinquishMagickMemory(list[i]); + break; + } + + PerlException: + if (list) + list=(char **) RelinquishMagickMemory(list); + if (length) + length=(STRLEN *) RelinquishMagickMemory(length); + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) number_images); + SvPOK_on(perl_exception); + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# C l o n e # +# # +# # +# # +############################################################################### +# +# +void +Clone(ref) + Image::Magick ref = NO_INIT + ALIAS: + CopyImage = 1 + copy = 2 + copyimage = 3 + CloneImage = 4 + clone = 5 + cloneimage = 6 + Clone = 7 + PPCODE: + { + AV + *av; + + ExceptionInfo + *exception; + + HV + *hv; + + Image + *clone, + *image; + + struct PackageInfo + *info; + + SV + *perl_exception, + *reference, + *rv, + *sv; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + sv=NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + hv=SvSTASH(reference); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + /* + Create blessed Perl array for the returned image. + */ + av=newAV(); + ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv)); + SvREFCNT_dec(av); + for ( ; image; image=image->next) + { + clone=CloneImage(image,0,0,MagickTrue,exception); + if (clone == (Image *) NULL) + break; + AddImageToRegistry(sv,clone); + rv=newRV(sv); + av_push(av,sv_bless(rv,hv)); + SvREFCNT_dec(sv); + } + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); + XSRETURN(1); + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0); + SvPOK_on(perl_exception); + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# C L O N E # +# # +# # +# # +############################################################################### +# +# +void +CLONE(ref,...) + SV *ref; + CODE: + { + PERL_UNUSED_VAR(ref); + if (magick_registry != (SplayTreeInfo *) NULL) + { + register Image + *p; + + ResetSplayTreeIterator(magick_registry); + p=(Image *) GetNextKeyInSplayTree(magick_registry); + while (p != (Image *) NULL) + { + ReferenceImage(p); + p=(Image *) GetNextKeyInSplayTree(magick_registry); + } + } + } + +# +############################################################################### +# # +# # +# # +# C o a l e s c e # +# # +# # +# # +############################################################################### +# +# +void +Coalesce(ref) + Image::Magick ref = NO_INIT + ALIAS: + CoalesceImage = 1 + coalesce = 2 + coalesceimage = 3 + PPCODE: + { + AV + *av; + + ExceptionInfo + *exception; + + HV + *hv; + + Image + *image; + + struct PackageInfo + *info; + + SV + *av_reference, + *perl_exception, + *reference, + *rv, + *sv; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + sv=NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + hv=SvSTASH(reference); + av=newAV(); + av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv)); + SvREFCNT_dec(av); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + image=CoalesceImages(image,exception); + if (image == (Image *) NULL) + goto PerlException; + for ( ; image; image=image->next) + { + AddImageToRegistry(sv,image); + rv=newRV(sv); + av_push(av,sv_bless(rv,hv)); + SvREFCNT_dec(sv); + } + exception=DestroyExceptionInfo(exception); + ST(0)=av_reference; + SvREFCNT_dec(perl_exception); + XSRETURN(1); + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0); + SvPOK_on(perl_exception); + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# C o m p a r e # +# # +# # +# # +############################################################################### +# +# +void +Compare(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + CompareImage = 1 + compare = 2 + compareimage = 3 + PPCODE: + { + AV + *av; + + char + *attribute; + + ChannelType + channel; + + double + distortion; + + ExceptionInfo + *exception; + + HV + *hv; + + Image + *difference_image, + *image, + *reconstruct_image; + + MetricType + metric; + + register ssize_t + i; + + ssize_t + option; + + struct PackageInfo + *info; + + SV + *av_reference, + *perl_exception, + *reference, + *rv, + *sv; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + sv=NULL; + av=NULL; + attribute=NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + hv=SvSTASH(reference); + av=newAV(); + av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv)); + SvREFCNT_dec(av); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + info=GetPackageInfo(aTHX_ (void *) av,info,exception); + /* + Get attribute. + */ + channel=DefaultChannels; + reconstruct_image=image; + metric=RootMeanSquaredErrorMetric; + for (i=2; i < items; i+=2) + { + attribute=(char *) SvPV(ST(i-1),na); + switch (*attribute) + { + case 'C': + case 'c': + { + if (LocaleCompare(attribute,"channel") == 0) + { + ssize_t + option; + + option=ParseChannelOption(SvPV(ST(i),na)); + if (option < 0) + { + ThrowPerlException(exception,OptionError, + "UnrecognizedType",SvPV(ST(i),na)); + return; + } + channel=(ChannelType) option; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'F': + case 'f': + { + if (LocaleCompare(attribute,"fuzz") == 0) + { + image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'I': + case 'i': + { + if (LocaleCompare(attribute,"image") == 0) + { + reconstruct_image=SetupList(aTHX_ SvRV(ST(i)), + (struct PackageInfo **) NULL,(SV ***) NULL,exception); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'M': + case 'm': + { + if (LocaleCompare(attribute,"metric") == 0) + { + option=ParseCommandOption(MagickMetricOptions,MagickFalse, + SvPV(ST(i),na)); + if (option < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(ST(i),na)); + break; + } + metric=(MetricType) option; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + default: + { + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + } + } + difference_image=CompareImageChannels(image,reconstruct_image,channel, + metric,&distortion,exception); + if (difference_image != (Image *) NULL) + { + difference_image->error.mean_error_per_pixel=distortion; + AddImageToRegistry(sv,difference_image); + rv=newRV(sv); + av_push(av,sv_bless(rv,hv)); + SvREFCNT_dec(sv); + } + exception=DestroyExceptionInfo(exception); + ST(0)=av_reference; + SvREFCNT_dec(perl_exception); /* can't return warning messages */ + XSRETURN(1); + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0); + SvPOK_on(perl_exception); + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# C o m p a r e L a y e r s # +# # +# # +# # +############################################################################### +# +# +void +CompareLayers(ref) + Image::Magick ref = NO_INIT + ALIAS: + CompareImageLayers = 1 + comparelayers = 2 + compareimagelayers = 3 + PPCODE: + { + AV + *av; + + char + *attribute; + + ExceptionInfo + *exception; + + HV + *hv; + + Image + *image; + + ImageLayerMethod + method; + + register ssize_t + i; + + ssize_t + option; + + struct PackageInfo + *info; + + SV + *av_reference, + *perl_exception, + *reference, + *rv, + *sv; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + sv=NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + hv=SvSTASH(reference); + av=newAV(); + av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv)); + SvREFCNT_dec(av); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + method=CompareAnyLayer; + for (i=2; i < items; i+=2) + { + attribute=(char *) SvPV(ST(i-1),na); + switch (*attribute) + { + case 'M': + case 'm': + { + if (LocaleCompare(attribute,"method") == 0) + { + option=ParseCommandOption(MagickLayerOptions,MagickFalse, + SvPV(ST(i),na)); + if (option < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(ST(i),na)); + break; + } + method=(ImageLayerMethod) option; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + default: + { + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + } + } + image=CompareImageLayers(image,method,exception); + if (image == (Image *) NULL) + goto PerlException; + for ( ; image; image=image->next) + { + AddImageToRegistry(sv,image); + rv=newRV(sv); + av_push(av,sv_bless(rv,hv)); + SvREFCNT_dec(sv); + } + exception=DestroyExceptionInfo(exception); + ST(0)=av_reference; + SvREFCNT_dec(perl_exception); + XSRETURN(1); + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0); + SvPOK_on(perl_exception); + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# C o m p l e x I m a g e s # +# # +# # +# # +############################################################################### +# +# +void +ComplexImages(ref) + Image::Magick ref = NO_INIT + ALIAS: + ComplexImages = 1 + compleximages = 2 + PPCODE: + { + AV + *av; + + char + *attribute, + *p; + + ExceptionInfo + *exception; + + HV + *hv; + + Image + *image; + + ComplexOperator + op; + + register ssize_t + i; + + struct PackageInfo + *info; + + SV + *perl_exception, + *reference, + *rv, + *sv; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + sv=NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + hv=SvSTASH(reference); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + op=UndefinedComplexOperator; + if (items == 2) + { + ssize_t + in; + + in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *) + SvPV(ST(1),na)); + if (in < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(ST(1),na)); + return; + } + op=(ComplexOperator) in; + } + else + for (i=2; i < items; i+=2) + { + attribute=(char *) SvPV(ST(i-1),na); + switch (*attribute) + { + case 'O': + case 'o': + { + if (LocaleCompare(attribute,"operator") == 0) + { + ssize_t + in; + + in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption( + MagickComplexOptions,MagickFalse,SvPV(ST(i),na)); + if (in < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(ST(i),na)); + return; + } + op=(ComplexOperator) in; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + default: + { + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + } + } + image=ComplexImages(image,op,exception); + if (image == (Image *) NULL) + goto PerlException; + /* + Create blessed Perl array for the returned image. + */ + av=newAV(); + ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv)); + SvREFCNT_dec(av); + AddImageToRegistry(sv,image); + rv=newRV(sv); + av_push(av,sv_bless(rv,hv)); + SvREFCNT_dec(sv); + info=GetPackageInfo(aTHX_ (void *) av,info,exception); + (void) FormatLocaleString(info->image_info->filename,MaxTextExtent, + "complex-%.*s",(int) (MaxTextExtent-9), + ((p=strrchr(image->filename,'/')) ? p+1 : image->filename)); + (void) CopyMagickString(image->filename,info->image_info->filename, + MaxTextExtent); + SetImageInfo(info->image_info,0,exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); + XSRETURN(1); + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0); + SvPOK_on(perl_exception); + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# D e s t r o y # +# # +# # +# # +############################################################################### +# +# +void +DESTROY(ref) + Image::Magick ref = NO_INIT + PPCODE: + { + SV + *reference; + + PERL_UNUSED_VAR(ref); + if (sv_isobject(ST(0)) == 0) + croak("ReferenceIsNotMyType"); + reference=SvRV(ST(0)); + switch (SvTYPE(reference)) + { + case SVt_PVAV: + { + char + message[MaxTextExtent]; + + const SV + *key; + + HV + *hv; + + GV + **gvp; + + struct PackageInfo + *info; + + SV + *sv; + + /* + Array (AV *) reference + */ + (void) FormatLocaleString(message,MaxTextExtent,"package%s%p", + XS_VERSION,reference); + hv=gv_stashpv(PackageName, FALSE); + if (!hv) + break; + gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE); + if (!gvp) + break; + sv=GvSV(*gvp); + if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv)) + { + info=INT2PTR(struct PackageInfo *,SvIV(sv)); + DestroyPackageInfo(info); + } + key=hv_delete(hv,message,(long) strlen(message),G_DISCARD); + (void) key; + break; + } + case SVt_PVMG: + { + Image + *image; + + /* + Blessed scalar = (Image *) SvIV(reference) + */ + image=INT2PTR(Image *,SvIV(reference)); + if (image != (Image *) NULL) + DeleteImageFromRegistry(reference,image); + break; + } + default: + break; + } + } + +# +############################################################################### +# # +# # +# # +# D i s p l a y # +# # +# # +# # +############################################################################### +# +# +void +Display(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + DisplayImage = 1 + display = 2 + displayimage = 3 + PPCODE: + { + ExceptionInfo + *exception; + + Image + *image; + + register ssize_t + i; + + struct PackageInfo + *info, + *package_info; + + SV + *perl_exception, + *reference; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + package_info=(struct PackageInfo *) NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + package_info=ClonePackageInfo(info,exception); + if (items == 2) + SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception); + else + if (items > 2) + for (i=2; i < items; i+=2) + SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i), + exception); + (void) DisplayImages(package_info->image_info,image); + (void) CatchImageException(image); + InheritException(exception,&image->exception); + + PerlException: + if (package_info != (struct PackageInfo *) NULL) + DestroyPackageInfo(package_info); + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0); + SvPOK_on(perl_exception); + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# E v a l u a t e I m a g e s # +# # +# # +# # +############################################################################### +# +# +void +EvaluateImages(ref) + Image::Magick ref = NO_INIT + ALIAS: + EvaluateImages = 1 + evaluateimages = 2 + PPCODE: + { + AV + *av; + + char + *attribute, + *p; + + ExceptionInfo + *exception; + + HV + *hv; + + Image + *image; + + MagickEvaluateOperator + op; + + register ssize_t + i; + + struct PackageInfo + *info; + + SV + *perl_exception, + *reference, + *rv, + *sv; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + sv=NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + hv=SvSTASH(reference); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + op=MeanEvaluateOperator; + if (items == 2) + { + ssize_t + in; + + in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *) + SvPV(ST(1),na)); + if (in < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(ST(1),na)); + return; + } + op=(MagickEvaluateOperator) in; + } + else + for (i=2; i < items; i+=2) + { + attribute=(char *) SvPV(ST(i-1),na); + switch (*attribute) + { + case 'O': + case 'o': + { + if (LocaleCompare(attribute,"operator") == 0) + { + ssize_t + in; + + in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption( + MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na)); + if (in < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(ST(i),na)); + return; + } + op=(MagickEvaluateOperator) in; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + default: + { + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + } + } + image=EvaluateImages(image,op,exception); + if (image == (Image *) NULL) + goto PerlException; + /* + Create blessed Perl array for the returned image. + */ + av=newAV(); + ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv)); + SvREFCNT_dec(av); + AddImageToRegistry(sv,image); + rv=newRV(sv); + av_push(av,sv_bless(rv,hv)); + SvREFCNT_dec(sv); + info=GetPackageInfo(aTHX_ (void *) av,info,exception); + (void) FormatLocaleString(info->image_info->filename,MaxTextExtent, + "evaluate-%.*s",(int) (MaxTextExtent-9), + ((p=strrchr(image->filename,'/')) ? p+1 : image->filename)); + (void) CopyMagickString(image->filename,info->image_info->filename, + MaxTextExtent); + SetImageInfo(info->image_info,0,exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); + XSRETURN(1); + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0); + SvPOK_on(perl_exception); + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# F e a t u r e s # +# # +# # +# # +############################################################################### +# +# +void +Features(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + FeaturesImage = 1 + features = 2 + featuresimage = 3 + PPCODE: + { +#define ChannelFeatures(channel,direction) \ +{ \ + (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \ + channel_features[channel].angular_second_moment[direction]); \ + PUSHs(sv_2mortal(newSVpv(message,0))); \ + (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \ + channel_features[channel].contrast[direction]); \ + PUSHs(sv_2mortal(newSVpv(message,0))); \ + (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \ + channel_features[channel].contrast[direction]); \ + PUSHs(sv_2mortal(newSVpv(message,0))); \ + (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \ + channel_features[channel].variance_sum_of_squares[direction]); \ + PUSHs(sv_2mortal(newSVpv(message,0))); \ + (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \ + channel_features[channel].inverse_difference_moment[direction]); \ + PUSHs(sv_2mortal(newSVpv(message,0))); \ + (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \ + channel_features[channel].sum_average[direction]); \ + PUSHs(sv_2mortal(newSVpv(message,0))); \ + (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \ + channel_features[channel].sum_variance[direction]); \ + PUSHs(sv_2mortal(newSVpv(message,0))); \ + (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \ + channel_features[channel].sum_entropy[direction]); \ + PUSHs(sv_2mortal(newSVpv(message,0))); \ + (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \ + channel_features[channel].entropy[direction]); \ + PUSHs(sv_2mortal(newSVpv(message,0))); \ + (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \ + channel_features[channel].difference_variance[direction]); \ + PUSHs(sv_2mortal(newSVpv(message,0))); \ + (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \ + channel_features[channel].difference_entropy[direction]); \ + PUSHs(sv_2mortal(newSVpv(message,0))); \ + (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \ + channel_features[channel].measure_of_correlation_1[direction]); \ + PUSHs(sv_2mortal(newSVpv(message,0))); \ + (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \ + channel_features[channel].measure_of_correlation_2[direction]); \ + PUSHs(sv_2mortal(newSVpv(message,0))); \ + (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \ + channel_features[channel].maximum_correlation_coefficient[direction]); \ + PUSHs(sv_2mortal(newSVpv(message,0))); \ +} + + AV + *av; + + char + *attribute, + message[MaxTextExtent]; + + ChannelFeatures + *channel_features; + + double + distance; + + ExceptionInfo + *exception; + + Image + *image; + + register ssize_t + i; + + ssize_t + count; + + struct PackageInfo + *info; + + SV + *perl_exception, + *reference; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + av=NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + av=newAV(); + SvREFCNT_dec(av); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + distance=1.0; + for (i=2; i < items; i+=2) + { + attribute=(char *) SvPV(ST(i-1),na); + switch (*attribute) + { + case 'D': + case 'd': + { + if (LocaleCompare(attribute,"distance") == 0) + { + distance=StringToLong((char *) SvPV(ST(1),na)); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + default: + { + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + } + } + count=0; + for ( ; image; image=image->next) + { + channel_features=GetImageChannelFeatures(image,distance, + &image->exception); + if (channel_features == (ChannelFeatures *) NULL) + continue; + count++; + EXTEND(sp,280*count); + for (i=0; i < 4; i++) + { + ChannelFeatures(RedChannel,i); + ChannelFeatures(GreenChannel,i); + ChannelFeatures(BlueChannel,i); + if (image->colorspace == CMYKColorspace) + ChannelFeatures(IndexChannel,i); + if (image->matte != MagickFalse) + ChannelFeatures(OpacityChannel,i); + } + channel_features=(ChannelFeatures *) + RelinquishMagickMemory(channel_features); + } + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); + } + +# +############################################################################### +# # +# # +# # +# F l a t t e n # +# # +# # +# # +############################################################################### +# +# +void +Flatten(ref) + Image::Magick ref = NO_INIT + ALIAS: + FlattenImage = 1 + flatten = 2 + flattenimage = 3 + PPCODE: + { + AV + *av; + + char + *attribute, + *p; + + ExceptionInfo + *exception; + + HV + *hv; + + Image + *image; + + PixelPacket + background_color; + + register ssize_t + i; + + struct PackageInfo + *info; + + SV + *perl_exception, + *reference, + *rv, + *sv; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + sv=NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + hv=SvSTASH(reference); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + background_color=image->background_color; + if (items == 2) + (void) QueryColorDatabase((char *) SvPV(ST(1),na),&background_color, + exception); + else + for (i=2; i < items; i+=2) + { + attribute=(char *) SvPV(ST(i-1),na); + switch (*attribute) + { + case 'B': + case 'b': + { + if (LocaleCompare(attribute,"background") == 0) + { + (void) QueryColorDatabase((char *) SvPV(ST(1),na), + &background_color,exception); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + default: + { + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + } + } + image->background_color=background_color; + image=MergeImageLayers(image,FlattenLayer,exception); + if (image == (Image *) NULL) + goto PerlException; + /* + Create blessed Perl array for the returned image. + */ + av=newAV(); + ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv)); + SvREFCNT_dec(av); + AddImageToRegistry(sv,image); + rv=newRV(sv); + av_push(av,sv_bless(rv,hv)); + SvREFCNT_dec(sv); + info=GetPackageInfo(aTHX_ (void *) av,info,exception); + (void) FormatLocaleString(info->image_info->filename,MaxTextExtent, + "flatten-%.*s",(int) (MaxTextExtent-9), + ((p=strrchr(image->filename,'/')) ? p+1 : image->filename)); + (void) CopyMagickString(image->filename,info->image_info->filename, + MaxTextExtent); + SetImageInfo(info->image_info,0,exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); + XSRETURN(1); + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0); + SvPOK_on(perl_exception); /* return messages in string context */ + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# F x # +# # +# # +# # +############################################################################### +# +# +void +Fx(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + FxImage = 1 + fx = 2 + fximage = 3 + PPCODE: + { + AV + *av; + + char + *attribute, + expression[MaxTextExtent]; + + ChannelType + channel; + + ExceptionInfo + *exception; + + HV + *hv; + + Image + *image; + + register ssize_t + i; + + struct PackageInfo + *info; + + SV + *av_reference, + *perl_exception, + *reference, + *rv, + *sv; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + sv=NULL; + attribute=NULL; + av=NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + hv=SvSTASH(reference); + av=newAV(); + av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv)); + SvREFCNT_dec(av); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + info=GetPackageInfo(aTHX_ (void *) av,info,exception); + /* + Get options. + */ + channel=DefaultChannels; + (void) CopyMagickString(expression,"u",MaxTextExtent); + if (items == 2) + (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MaxTextExtent); + else + for (i=2; i < items; i+=2) + { + attribute=(char *) SvPV(ST(i-1),na); + switch (*attribute) + { + case 'C': + case 'c': + { + if (LocaleCompare(attribute,"channel") == 0) + { + ssize_t + option; + + option=ParseChannelOption(SvPV(ST(i),na)); + if (option < 0) + { + ThrowPerlException(exception,OptionError, + "UnrecognizedType",SvPV(ST(i),na)); + return; + } + channel=(ChannelType) option; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'E': + case 'e': + { + if (LocaleCompare(attribute,"expression") == 0) + { + (void) CopyMagickString(expression,SvPV(ST(i),na), + MaxTextExtent); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + default: + { + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + } + } + image=FxImageChannel(image,channel,expression,exception); + if (image == (Image *) NULL) + goto PerlException; + for ( ; image; image=image->next) + { + AddImageToRegistry(sv,image); + rv=newRV(sv); + av_push(av,sv_bless(rv,hv)); + SvREFCNT_dec(sv); + } + exception=DestroyExceptionInfo(exception); + ST(0)=av_reference; + SvREFCNT_dec(perl_exception); /* can't return warning messages */ + XSRETURN(1); + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0); + SvPOK_on(perl_exception); + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# G e t # +# # +# # +# # +############################################################################### +# +# +void +Get(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + GetAttributes = 1 + GetAttribute = 2 + get = 3 + getattributes = 4 + getattribute = 5 + PPCODE: + { + char + *attribute, + color[MaxTextExtent]; + + const char + *value; + + ExceptionInfo + *exception; + + Image + *image; + + long + j; + + register ssize_t + i; + + struct PackageInfo + *info; + + SV + *perl_exception, + *reference, + *s; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + XSRETURN_EMPTY; + } + reference=SvRV(ST(0)); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL && !info) + XSRETURN_EMPTY; + EXTEND(sp,items); + for (i=1; i < items; i++) + { + attribute=(char *) SvPV(ST(i),na); + s=NULL; + switch (*attribute) + { + case 'A': + case 'a': + { + if (LocaleCompare(attribute,"adjoin") == 0) + { + if (info) + s=newSViv((ssize_t) info->image_info->adjoin); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"antialias") == 0) + { + if (info) + s=newSViv((ssize_t) info->image_info->antialias); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"area") == 0) + { + s=newSViv(GetMagickResource(AreaResource)); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"attenuate") == 0) + { + const char + *value; + + value=GetImageProperty(image,attribute); + if (value != (const char *) NULL) + s=newSVpv(value,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"authenticate") == 0) + { + if (info) + s=newSVpv(info->image_info->authenticate,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'B': + case 'b': + { + if (LocaleCompare(attribute,"background") == 0) + { + if (image == (Image *) NULL) + break; + (void) FormatLocaleString(color,MaxTextExtent,QuantumFormat "," + QuantumFormat "," QuantumFormat "," QuantumFormat, + image->background_color.red,image->background_color.green, + image->background_color.blue,image->background_color.opacity); + s=newSVpv(color,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"base-columns") == 0) + { + if (image != (Image *) NULL) + s=newSViv((ssize_t) image->magick_columns); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"base-filename") == 0) + { + if (image != (Image *) NULL) + s=newSVpv(image->magick_filename,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"base-height") == 0) + { + if (image != (Image *) NULL) + s=newSViv((ssize_t) image->magick_rows); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"base-rows") == 0) + { + if (image != (Image *) NULL) + s=newSViv((ssize_t) image->magick_rows); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"base-width") == 0) + { + if (image != (Image *) NULL) + s=newSViv((ssize_t) image->magick_columns); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"bias") == 0) + { + if (image != (Image *) NULL) + s=newSVnv(image->bias); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"blue-primary") == 0) + { + if (image == (Image *) NULL) + break; + (void) FormatLocaleString(color,MaxTextExtent,"%.15g,%.15g", + image->chromaticity.blue_primary.x, + image->chromaticity.blue_primary.y); + s=newSVpv(color,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"bordercolor") == 0) + { + if (image == (Image *) NULL) + break; + (void) FormatLocaleString(color,MaxTextExtent,QuantumFormat "," + QuantumFormat "," QuantumFormat "," QuantumFormat, + image->border_color.red,image->border_color.green, + image->border_color.blue,image->border_color.opacity); + s=newSVpv(color,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"bounding-box") == 0) + { + char + geometry[MaxTextExtent]; + + RectangleInfo + page; + + if (image == (Image *) NULL) + break; + page=GetImageBoundingBox(image,&image->exception); + (void) FormatLocaleString(geometry,MaxTextExtent, + "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double) + page.height,(double) page.x,(double) page.y); + s=newSVpv(geometry,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'C': + case 'c': + { + if (LocaleCompare(attribute,"class") == 0) + { + if (image == (Image *) NULL) + break; + s=newSViv(image->storage_class); + (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions, + image->storage_class)); + SvIOK_on(s); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"clip-mask") == 0) + { + if (image != (Image *) NULL) + { + SV + *sv; + + sv=NULL; + if (image->mask == (Image *) NULL) + ClipImage(image); + if (image->mask != (Image *) NULL) + { + AddImageToRegistry(sv,image->mask); + s=sv_bless(newRV(sv),SvSTASH(reference)); + } + } + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"clip-path") == 0) + { + if (image != (Image *) NULL) + { + SV + *sv; + + sv=NULL; + if (image->clip_mask == (Image *) NULL) + ClipImage(image); + if (image->clip_mask != (Image *) NULL) + { + AddImageToRegistry(sv,image->clip_mask); + s=sv_bless(newRV(sv),SvSTASH(reference)); + } + } + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"compression") == 0) + { + j=info ? info->image_info->compression : image ? + image->compression : UndefinedCompression; + if (info) + if (info->image_info->compression == UndefinedCompression) + j=image->compression; + s=newSViv(j); + (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions, + j)); + SvIOK_on(s); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"colorspace") == 0) + { + j=image ? image->colorspace : RGBColorspace; + s=newSViv(j); + (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions, + j)); + SvIOK_on(s); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"colors") == 0) + { + if (image != (Image *) NULL) + s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL, + &image->exception)); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleNCompare(attribute,"colormap",8) == 0) + { + int + items; + + if (image == (Image *) NULL || !image->colormap) + break; + j=0; + items=sscanf(attribute,"%*[^[][%ld",&j); + (void) items; + if (j > (ssize_t) image->colors) + j%=image->colors; + (void) FormatLocaleString(color,MaxTextExtent,QuantumFormat "," + QuantumFormat "," QuantumFormat "," QuantumFormat, + image->colormap[j].red,image->colormap[j].green, + image->colormap[j].blue,image->colormap[j].opacity); + s=newSVpv(color,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"columns") == 0) + { + if (image != (Image *) NULL) + s=newSViv((ssize_t) image->columns); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"comment") == 0) + { + const char + *value; + + value=GetImageProperty(image,attribute); + if (value != (const char *) NULL) + s=newSVpv(value,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"copyright") == 0) + { + s=newSVpv(GetMagickCopyright(),0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'D': + case 'd': + { + if (LocaleCompare(attribute,"density") == 0) + { + char + geometry[MaxTextExtent]; + + if (image == (Image *) NULL) + break; + (void) FormatLocaleString(geometry,MaxTextExtent,"%.15gx%.15g", + image->x_resolution,image->y_resolution); + s=newSVpv(geometry,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"delay") == 0) + { + if (image != (Image *) NULL) + s=newSViv((ssize_t) image->delay); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"depth") == 0) + { + s=newSViv(MAGICKCORE_QUANTUM_DEPTH); + if (image != (Image *) NULL) + s=newSViv((ssize_t) GetImageDepth(image,&image->exception)); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"directory") == 0) + { + if (image && image->directory) + s=newSVpv(image->directory,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"dispose") == 0) + { + if (image == (Image *) NULL) + break; + + s=newSViv(image->dispose); + (void) sv_setpv(s, + CommandOptionToMnemonic(MagickDisposeOptions,image->dispose)); + SvIOK_on(s); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"disk") == 0) + { + s=newSViv(GetMagickResource(DiskResource)); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"dither") == 0) + { + if (info) + s=newSViv((ssize_t) info->image_info->dither); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"display") == 0) /* same as server */ + { + if (info && info->image_info->server_name) + s=newSVpv(info->image_info->server_name,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'E': + case 'e': + { + if (LocaleCompare(attribute,"elapsed-time") == 0) + { + if (image != (Image *) NULL) + s=newSVnv(GetElapsedTime(&image->timer)); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"endian") == 0) + { + j=info ? info->image_info->endian : image ? image->endian : + UndefinedEndian; + s=newSViv(j); + (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j)); + SvIOK_on(s); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"error") == 0) + { + if (image != (Image *) NULL) + s=newSVnv(image->error.mean_error_per_pixel); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'F': + case 'f': + { + if (LocaleCompare(attribute,"filesize") == 0) + { + if (image != (Image *) NULL) + s=newSViv((ssize_t) GetBlobSize(image)); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"filename") == 0) + { + if (info && info->image_info->filename && + *info->image_info->filename) + s=newSVpv(info->image_info->filename,0); + if (image != (Image *) NULL) + s=newSVpv(image->filename,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"filter") == 0) + { + s=image ? newSViv(image->filter) : newSViv(0); + (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions, + image->filter)); + SvIOK_on(s); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"font") == 0) + { + if (info && info->image_info->font) + s=newSVpv(info->image_info->font,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"foreground") == 0) + continue; + if (LocaleCompare(attribute,"format") == 0) + { + const MagickInfo + *magick_info; + + magick_info=(const MagickInfo *) NULL; + if (info && (*info->image_info->magick != '\0')) + magick_info=GetMagickInfo(info->image_info->magick,exception); + if (image != (Image *) NULL) + magick_info=GetMagickInfo(image->magick,&image->exception); + if ((magick_info != (const MagickInfo *) NULL) && + (*magick_info->description != '\0')) + s=newSVpv((char *) magick_info->description,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"fuzz") == 0) + { + if (info) + s=newSVnv(info->image_info->fuzz); + if (image != (Image *) NULL) + s=newSVnv(image->fuzz); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'G': + case 'g': + { + if (LocaleCompare(attribute,"gamma") == 0) + { + if (image != (Image *) NULL) + s=newSVnv(image->gamma); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"geometry") == 0) + { + if (image && image->geometry) + s=newSVpv(image->geometry,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"gravity") == 0) + { + s=image ? newSViv(image->gravity) : newSViv(0); + (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions, + image->gravity)); + SvIOK_on(s); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"green-primary") == 0) + { + if (image == (Image *) NULL) + break; + (void) FormatLocaleString(color,MaxTextExtent,"%.15g,%.15g", + image->chromaticity.green_primary.x, + image->chromaticity.green_primary.y); + s=newSVpv(color,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'H': + case 'h': + { + if (LocaleCompare(attribute,"height") == 0) + { + if (image != (Image *) NULL) + s=newSViv((ssize_t) image->rows); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'I': + case 'i': + { + if (LocaleCompare(attribute,"icc") == 0) + { + if (image != (Image *) NULL) + { + const StringInfo + *profile; + + profile=GetImageProfile(image,"icc"); + if (profile != (StringInfo *) NULL) + s=newSVpv((const char *) GetStringInfoDatum(profile), + GetStringInfoLength(profile)); + } + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"icm") == 0) + { + if (image != (Image *) NULL) + { + const StringInfo + *profile; + + profile=GetImageProfile(image,"icm"); + if (profile != (const StringInfo *) NULL) + s=newSVpv((const char *) GetStringInfoDatum(profile), + GetStringInfoLength(profile)); + } + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"id") == 0) + { + if (image != (Image *) NULL) + { + char + key[MaxTextExtent]; + + MagickBooleanType + status; + + static ssize_t + id = 0; + + (void) FormatLocaleString(key,MaxTextExtent,"%.20g\n",(double) + id); + status=SetImageRegistry(ImageRegistryType,key,image, + &image->exception); + (void) status; + s=newSViv(id++); + } + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleNCompare(attribute,"index",5) == 0) + { + char + name[MaxTextExtent]; + + int + items; + + long + x, + y; + + register const IndexPacket + *indexes; + + register const PixelPacket + *p; + + CacheView + *image_view; + + if (image == (Image *) NULL) + break; + if (image->storage_class != PseudoClass) + break; + x=0; + y=0; + items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y); + (void) items; + image_view=AcquireVirtualCacheView(image,exception); + p=GetCacheViewVirtualPixels(image_view,x,y,1,1,&image->exception); + if (p != (const PixelPacket *) NULL) + { + indexes=GetCacheViewVirtualIndexQueue(image_view); + (void) FormatLocaleString(name,MaxTextExtent,QuantumFormat, + GetPixelIndex(indexes)); + s=newSVpv(name,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + } + image_view=DestroyCacheView(image_view); + continue; + } + if (LocaleCompare(attribute,"iptc") == 0) + { + if (image != (Image *) NULL) + { + const StringInfo + *profile; + + profile=GetImageProfile(image,"iptc"); + if (profile != (const StringInfo *) NULL) + s=newSVpv((const char *) GetStringInfoDatum(profile), + GetStringInfoLength(profile)); + } + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */ + { + if (image != (Image *) NULL) + s=newSViv((ssize_t) image->iterations); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"interlace") == 0) + { + j=info ? info->image_info->interlace : image ? image->interlace : + UndefinedInterlace; + s=newSViv(j); + (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions, + j)); + SvIOK_on(s); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'L': + case 'l': + { + if (LocaleCompare(attribute,"label") == 0) + { + const char + *value; + + if (image == (Image *) NULL) + break; + value=GetImageProperty(image,"Label"); + if (value != (const char *) NULL) + s=newSVpv(value,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */ + { + if (image != (Image *) NULL) + s=newSViv((ssize_t) image->iterations); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'M': + case 'm': + { + if (LocaleCompare(attribute,"magick") == 0) + { + if (info && *info->image_info->magick) + s=newSVpv(info->image_info->magick,0); + if (image != (Image *) NULL) + s=newSVpv(image->magick,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"map") == 0) + { + s=newSViv(GetMagickResource(MapResource)); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"maximum-error") == 0) + { + if (image != (Image *) NULL) + s=newSVnv(image->error.normalized_maximum_error); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"memory") == 0) + { + s=newSViv(GetMagickResource(MemoryResource)); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"mean-error") == 0) + { + if (image != (Image *) NULL) + s=newSVnv(image->error.normalized_mean_error); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"mime") == 0) + { + if (info && *info->image_info->magick) + s=newSVpv(MagickToMime(info->image_info->magick),0); + if (image != (Image *) NULL) + s=newSVpv(MagickToMime(image->magick),0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"mattecolor") == 0) + { + if (image == (Image *) NULL) + break; + (void) FormatLocaleString(color,MaxTextExtent,QuantumFormat "," + QuantumFormat "," QuantumFormat "," QuantumFormat, + image->matte_color.red,image->matte_color.green, + image->matte_color.blue,image->matte_color.opacity); + s=newSVpv(color,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"matte") == 0) + { + if (image != (Image *) NULL) + s=newSViv((ssize_t) image->matte); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"mime") == 0) + { + const char + *magick; + + magick=NULL; + if (info && *info->image_info->magick) + magick=info->image_info->magick; + if (image != (Image *) NULL) + magick=image->magick; + if (magick) + { + char + *mime; + + mime=MagickToMime(magick); + s=newSVpv(mime,0); + mime=(char *) RelinquishMagickMemory(mime); + } + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"monochrome") == 0) + { + if (image == (Image *) NULL) + continue; + j=info ? info->image_info->monochrome : + IsMonochromeImage(image,&image->exception); + s=newSViv(j); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"montage") == 0) + { + if (image && image->montage) + s=newSVpv(image->montage,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'O': + case 'o': + { + if (LocaleCompare(attribute,"orientation") == 0) + { + j=info ? info->image_info->orientation : image ? + image->orientation : UndefinedOrientation; + s=newSViv(j); + (void) sv_setpv(s,CommandOptionToMnemonic( + MagickOrientationOptions,j)); + SvIOK_on(s); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'P': + case 'p': + { + if (LocaleCompare(attribute,"page") == 0) + { + if (info && info->image_info->page) + s=newSVpv(info->image_info->page,0); + if (image != (Image *) NULL) + { + char + geometry[MaxTextExtent]; + + (void) FormatLocaleString(geometry,MaxTextExtent, + "%.20gx%.20g%+.20g%+.20g",(double) image->page.width, + (double) image->page.height,(double) image->page.x,(double) + image->page.y); + s=newSVpv(geometry,0); + } + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"page.x") == 0) + { + if (image != (Image *) NULL) + s=newSViv((ssize_t) image->page.x); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"page.y") == 0) + { + if (image != (Image *) NULL) + s=newSViv((ssize_t) image->page.y); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleNCompare(attribute,"pixel",5) == 0) + { + char + tuple[MaxTextExtent]; + + int + items; + + long + x, + y; + + register const PixelPacket + *p; + + register const IndexPacket + *indexes; + + if (image == (Image *) NULL) + break; + x=0; + y=0; + items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y); + (void) items; + p=GetVirtualPixels(image,x,y,1,1,exception); + indexes=GetVirtualIndexQueue(image); + if (image->colorspace != CMYKColorspace) + (void) FormatLocaleString(tuple,MaxTextExtent,QuantumFormat "," + QuantumFormat "," QuantumFormat "," QuantumFormat, + GetPixelRed(p),GetPixelGreen(p), + GetPixelBlue(p),GetPixelOpacity(p)); + else + (void) FormatLocaleString(tuple,MaxTextExtent,QuantumFormat "," + QuantumFormat "," QuantumFormat "," QuantumFormat "," + QuantumFormat,GetPixelRed(p), + GetPixelGreen(p),GetPixelBlue(p), + GetPixelIndex(indexes),GetPixelOpacity(p)); + s=newSVpv(tuple,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"pointsize") == 0) + { + if (info) + s=newSViv((ssize_t) info->image_info->pointsize); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"preview") == 0) + { + s=newSViv(info->image_info->preview_type); + (void) sv_setpv(s,CommandOptionToMnemonic(MagickPreviewOptions, + info->image_info->preview_type)); + SvIOK_on(s); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'Q': + case 'q': + { + if (LocaleCompare(attribute,"quality") == 0) + { + if (info) + s=newSViv((ssize_t) info->image_info->quality); + if (image != (Image *) NULL) + s=newSViv((ssize_t) image->quality); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"quantum") == 0) + { + if (info) + s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'R': + case 'r': + { + if (LocaleCompare(attribute,"rendering-intent") == 0) + { + s=newSViv(image->rendering_intent); + (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions, + image->rendering_intent)); + SvIOK_on(s); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"red-primary") == 0) + { + if (image == (Image *) NULL) + break; + (void) FormatLocaleString(color,MaxTextExtent,"%.15g,%.15g", + image->chromaticity.red_primary.x, + image->chromaticity.red_primary.y); + s=newSVpv(color,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"rows") == 0) + { + if (image != (Image *) NULL) + s=newSViv((ssize_t) image->rows); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'S': + case 's': + { + if (LocaleCompare(attribute,"sampling-factor") == 0) + { + if (info && info->image_info->sampling_factor) + s=newSVpv(info->image_info->sampling_factor,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"subimage") == 0) + { + if (info) + s=newSViv((ssize_t) info->image_info->subimage); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"subrange") == 0) + { + if (info) + s=newSViv((ssize_t) info->image_info->subrange); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"server") == 0) /* same as display */ + { + if (info && info->image_info->server_name) + s=newSVpv(info->image_info->server_name,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"size") == 0) + { + if (info && info->image_info->size) + s=newSVpv(info->image_info->size,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"scene") == 0) + { + if (image != (Image *) NULL) + s=newSViv((ssize_t) image->scene); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"scenes") == 0) + { + if (image != (Image *) NULL) + s=newSViv((ssize_t) info->image_info->number_scenes); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"signature") == 0) + { + const char + *value; + + if (image == (Image *) NULL) + break; + (void) SignatureImage(image); + value=GetImageProperty(image,"Signature"); + if (value != (const char *) NULL) + s=newSVpv(value,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'T': + case 't': + { + if (LocaleCompare(attribute,"taint") == 0) + { + if (image != (Image *) NULL) + s=newSViv((ssize_t) IsTaintImage(image)); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"tile") == 0) + { + if (info && info->image_info->tile) + s=newSVpv(info->image_info->tile,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"texture") == 0) + { + if (info && info->image_info->texture) + s=newSVpv(info->image_info->texture,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"total-ink-density") == 0) + { + s=newSViv(MAGICKCORE_QUANTUM_DEPTH); + if (image != (Image *) NULL) + s=newSVnv(GetImageTotalInkDensity(image)); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"transparent-color") == 0) + { + if (image == (Image *) NULL) + break; + (void) FormatLocaleString(color,MaxTextExtent,QuantumFormat "," + QuantumFormat "," QuantumFormat "," QuantumFormat, + image->transparent_color.red,image->transparent_color.green, + image->transparent_color.blue,image->transparent_color.opacity); + s=newSVpv(color,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"type") == 0) + { + if (image == (Image *) NULL) + break; + j=(ssize_t) GetImageType(image,&image->exception); + s=newSViv(j); + (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j)); + SvIOK_on(s); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'U': + case 'u': + { + if (LocaleCompare(attribute,"units") == 0) + { + j=info ? info->image_info->units : image ? image->units : + UndefinedResolution; + if (info && (info->image_info->units == UndefinedResolution)) + if (image) + j=image->units; + if (j == UndefinedResolution) + s=newSVpv("undefined units",0); + else + if (j == PixelsPerInchResolution) + s=newSVpv("pixels / inch",0); + else + s=newSVpv("pixels / centimeter",0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"user-time") == 0) + { + if (image != (Image *) NULL) + s=newSVnv(GetUserTime(&image->timer)); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'V': + case 'v': + { + if (LocaleCompare(attribute,"verbose") == 0) + { + if (info) + s=newSViv((ssize_t) info->image_info->verbose); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"version") == 0) + { + s=newSVpv(GetMagickVersion((size_t *) NULL),0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"view") == 0) + { + if (info && info->image_info->view) + s=newSVpv(info->image_info->view,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"virtual-pixel") == 0) + { + if (image == (Image *) NULL) + break; + j=(ssize_t) GetImageVirtualPixelMethod(image); + s=newSViv(j); + (void) sv_setpv(s,CommandOptionToMnemonic( + MagickVirtualPixelOptions,j)); + SvIOK_on(s); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'W': + case 'w': + { + if (LocaleCompare(attribute,"white-point") == 0) + { + if (image == (Image *) NULL) + break; + (void) FormatLocaleString(color,MaxTextExtent,"%.15g,%.15g", + image->chromaticity.white_point.x, + image->chromaticity.white_point.y); + s=newSVpv(color,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"width") == 0) + { + if (image != (Image *) NULL) + s=newSViv((ssize_t) image->columns); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'X': + case 'x': + { + if (LocaleCompare(attribute,"xmp") == 0) + { + if (image != (Image *) NULL) + { + const StringInfo + *profile; + + profile=GetImageProfile(image,"xmp"); + if (profile != (StringInfo *) NULL) + s=newSVpv((const char *) GetStringInfoDatum(profile), + GetStringInfoLength(profile)); + } + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + if (LocaleCompare(attribute,"x-resolution") == 0) + { + if (image != (Image *) NULL) + s=newSVnv(image->x_resolution); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'Y': + case 'y': + { + if (LocaleCompare(attribute,"y-resolution") == 0) + { + if (image != (Image *) NULL) + s=newSVnv(image->y_resolution); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + default: + break; + } + if (image == (Image *) NULL) + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute) + else + { + value=GetImageProperty(image,attribute); + if (value != (const char *) NULL) + { + s=newSVpv(value,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + } + else + if (*attribute != '%') + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute) + else + { + char + *meta; + + meta=InterpretImageProperties(info ? info->image_info : + (ImageInfo *) NULL,image,attribute); + s=newSVpv(meta,0); + PUSHs(s ? sv_2mortal(s) : &sv_undef); + meta=(char *) RelinquishMagickMemory(meta); + } + } + } + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); /* can't return warning messages */ + } + +# +############################################################################### +# # +# # +# # +# G e t A u t h e n t i c P i x e l s # +# # +# # +# # +############################################################################### +# +# +void * +GetAuthenticPixels(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + getauthenticpixels = 1 + GetImagePixels = 2 + getimagepixels = 3 + CODE: + { + char + *attribute; + + ExceptionInfo + *exception; + + Image + *image; + + RectangleInfo + region; + + ssize_t + i; + + struct PackageInfo + *info; + + SV + *perl_exception, + *reference; + + void + *blob = NULL; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + + region.x=0; + region.y=0; + region.width=image->columns; + region.height=1; + if (items == 1) + (void) ParseAbsoluteGeometry(SvPV(ST(1),na),®ion); + for (i=2; i < items; i+=2) + { + attribute=(char *) SvPV(ST(i-1),na); + switch (*attribute) + { + case 'g': + case 'G': + { + if (LocaleCompare(attribute,"geometry") == 0) + { + (void) ParseAbsoluteGeometry(SvPV(ST(i),na),®ion); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'H': + case 'h': + { + if (LocaleCompare(attribute,"height") == 0) + { + region.height=SvIV(ST(i)); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedOption", + attribute); + break; + } + case 'X': + case 'x': + { + if (LocaleCompare(attribute,"x") == 0) + { + region.x=SvIV(ST(i)); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedOption", + attribute); + break; + } + case 'Y': + case 'y': + { + if (LocaleCompare(attribute,"y") == 0) + { + region.y=SvIV(ST(i)); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedOption", + attribute); + break; + } + case 'W': + case 'w': + { + if (LocaleCompare(attribute,"width") == 0) + { + region.width=SvIV(ST(i)); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedOption", + attribute); + break; + } + } + } + blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width, + region.height,exception); + if (blob != (void *) NULL) + goto PerlEnd; + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); /* throw away all errors */ + + PerlEnd: + RETVAL = blob; + } + OUTPUT: + RETVAL + +# +############################################################################### +# # +# # +# # +# G e t V i r t u a l P i x e l s # +# # +# # +# # +############################################################################### +# +# +void * +GetVirtualPixels(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + getvirtualpixels = 1 + AcquireImagePixels = 2 + acquireimagepixels = 3 + CODE: + { + char + *attribute; + + const void + *blob = NULL; + + ExceptionInfo + *exception; + + Image + *image; + + RectangleInfo + region; + + ssize_t + i; + + struct PackageInfo + *info; + + SV + *perl_exception, + *reference; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + + region.x=0; + region.y=0; + region.width=image->columns; + region.height=1; + if (items == 1) + (void) ParseAbsoluteGeometry(SvPV(ST(1),na),®ion); + for (i=2; i < items; i+=2) + { + attribute=(char *) SvPV(ST(i-1),na); + switch (*attribute) + { + case 'g': + case 'G': + { + if (LocaleCompare(attribute,"geometry") == 0) + { + (void) ParseAbsoluteGeometry(SvPV(ST(i),na),®ion); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'H': + case 'h': + { + if (LocaleCompare(attribute,"height") == 0) + { + region.height=SvIV(ST(i)); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedOption", + attribute); + break; + } + case 'X': + case 'x': + { + if (LocaleCompare(attribute,"x") == 0) + { + region.x=SvIV(ST(i)); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedOption", + attribute); + break; + } + case 'Y': + case 'y': + { + if (LocaleCompare(attribute,"y") == 0) + { + region.y=SvIV(ST(i)); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedOption", + attribute); + break; + } + case 'W': + case 'w': + { + if (LocaleCompare(attribute,"width") == 0) + { + region.width=SvIV(ST(i)); + continue; + } + ThrowPerlException(exception,OptionError,"UnrecognizedOption", + attribute); + break; + } + } + } + blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width, + region.height,exception); + if (blob != (void *) NULL) + goto PerlEnd; + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); /* throw away all errors */ + + PerlEnd: + RETVAL = (void *) blob; + } + OUTPUT: + RETVAL + +# +############################################################################### +# # +# # +# # +# G e t A u t h e n t i c I n d e x Q u e u e # +# # +# # +# # +############################################################################### +# +# +void * +GetAuthenticIndexQueue(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + getauthenticindexqueue = 1 + GetIndexes = 2 + getindexes = 3 + CODE: + { + ExceptionInfo + *exception; + + Image + *image; + + struct PackageInfo + *info; + + SV + *perl_exception, + *reference; + + void + *blob = NULL; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + + blob=(void *) GetAuthenticIndexQueue(image); + if (blob != (void *) NULL) + goto PerlEnd; + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); /* throw away all errors */ + + PerlEnd: + RETVAL = blob; + } + OUTPUT: + RETVAL + +# +############################################################################### +# # +# # +# # +# G e t V i r t u a l I n d e x Q u e u e # +# # +# # +# # +############################################################################### +# +# +void * +GetVirtualIndexQueue(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + getvirtualindexqueue = 1 + CODE: + { + ExceptionInfo + *exception; + + Image + *image; + + struct PackageInfo + *info; + + SV + *perl_exception, + *reference; + + void + *blob = NULL; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + + blob=(void *) GetVirtualIndexQueue(image); + if (blob != (void *) NULL) + goto PerlEnd; + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); /* throw away all errors */ + + PerlEnd: + RETVAL = blob; + } + OUTPUT: + RETVAL + +# +############################################################################### +# # +# # +# # +# H i s t o g r a m # +# # +# # +# # +############################################################################### +# +# +void +Histogram(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + HistogramImage = 1 + histogram = 2 + histogramimage = 3 + PPCODE: + { + AV + *av; + + char + message[MaxTextExtent]; + + ColorPacket + *histogram; + + ExceptionInfo + *exception; + + Image + *image; + + register ssize_t + i; + + ssize_t + count; + + struct PackageInfo + *info; + + SV + *perl_exception, + *reference; + + size_t + number_colors; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + av=NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + av=newAV(); + SvREFCNT_dec(av); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + count=0; + for ( ; image; image=image->next) + { + histogram=GetImageHistogram(image,&number_colors,&image->exception); + if (histogram == (ColorPacket *) NULL) + continue; + count+=(ssize_t) number_colors; + EXTEND(sp,6*count); + for (i=0; i < (ssize_t) number_colors; i++) + { + (void) FormatLocaleString(message,MaxTextExtent,QuantumFormat, + histogram[i].pixel.red); + PUSHs(sv_2mortal(newSVpv(message,0))); + (void) FormatLocaleString(message,MaxTextExtent,QuantumFormat, + histogram[i].pixel.green); + PUSHs(sv_2mortal(newSVpv(message,0))); + (void) FormatLocaleString(message,MaxTextExtent,QuantumFormat, + histogram[i].pixel.blue); + PUSHs(sv_2mortal(newSVpv(message,0))); + if (image->colorspace == CMYKColorspace) + { + (void) FormatLocaleString(message,MaxTextExtent,QuantumFormat, + histogram[i].index); + PUSHs(sv_2mortal(newSVpv(message,0))); + } + (void) FormatLocaleString(message,MaxTextExtent,QuantumFormat, + histogram[i].pixel.opacity); + PUSHs(sv_2mortal(newSVpv(message,0))); + (void) FormatLocaleString(message,MaxTextExtent,"%.20g",(double) + histogram[i].count); + PUSHs(sv_2mortal(newSVpv(message,0))); + } + histogram=(ColorPacket *) RelinquishMagickMemory(histogram); + } + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); + } + +# +############################################################################### +# # +# # +# # +# G e t P i x e l # +# # +# # +# # +############################################################################### +# +# +void +GetPixel(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + getpixel = 1 + getPixel = 2 + PPCODE: + { + AV + *av; + + char + *attribute; + + ChannelType + channel; + + ExceptionInfo + *exception; + + Image + *image; + + MagickBooleanType + normalize; + + RectangleInfo + region; + + register const IndexPacket + *indexes; + + register const PixelPacket + *p; + + register ssize_t + i; + + ssize_t + option; + + struct PackageInfo + *info; + + SV + *perl_exception, + *reference; /* reference is the SV* of ref=SvIV(reference) */ + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + reference=SvRV(ST(0)); + av=(AV *) reference; + info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL, + exception); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + channel=DefaultChannels; + normalize=MagickTrue; + region.x=0; + region.y=0; + region.width=image->columns; + region.height=1; + if (items == 1) + (void) ParseAbsoluteGeometry(SvPV(ST(1),na),®ion); + for (i=2; i < items; i+=2) + { + attribute=(char *) SvPV(ST(i-1),na); + switch (*attribute) + { + case 'C': + case 'c': + { + if (LocaleCompare(attribute,"channel") == 0) + { + ssize_t + option; + + option=ParseChannelOption(SvPV(ST(i),na)); + if (option < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(ST(i),na)); + return; + } + channel=(ChannelType) option; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'g': + case 'G': + { + if (LocaleCompare(attribute,"geometry") == 0) + { + (void) ParseAbsoluteGeometry(SvPV(ST(i),na),®ion); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'N': + case 'n': + { + if (LocaleCompare(attribute,"normalize") == 0) + { + option=ParseCommandOption(MagickBooleanOptions,MagickFalse, + SvPV(ST(i),na)); + if (option < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(ST(i),na)); + break; + } + normalize=option != 0 ? MagickTrue : MagickFalse; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'x': + case 'X': + { + if (LocaleCompare(attribute,"x") == 0) + { + region.x=SvIV(ST(i)); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'y': + case 'Y': + { + if (LocaleCompare(attribute,"y") == 0) + { + region.y=SvIV(ST(i)); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + default: + { + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + } + } + p=GetVirtualPixels(image,region.x,region.y,1,1,exception); + if (p == (const PixelPacket *) NULL) + PUSHs(&sv_undef); + else + { + double + scale; + + indexes=GetVirtualIndexQueue(image); + scale=1.0; + if (normalize != MagickFalse) + scale=1.0/QuantumRange; + if ((channel & RedChannel) != 0) + PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(p)))); + if ((channel & GreenChannel) != 0) + PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(p)))); + if ((channel & BlueChannel) != 0) + PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(p)))); + if (((channel & IndexChannel) != 0) && + (image->colorspace == CMYKColorspace)) + PUSHs(sv_2mortal(newSVnv(scale*GetPixelIndex(indexes)))); + if ((channel & OpacityChannel) != 0) + PUSHs(sv_2mortal(newSVnv(scale*GetPixelOpacity(p)))); + } + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); + } + +# +############################################################################### +# # +# # +# # +# G e t P i x e l s # +# # +# # +# # +############################################################################### +# +# +void +GetPixels(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + getpixels = 1 + getPixels = 2 + PPCODE: + { + AV + *av; + + char + *attribute; + + const char + *map; + + ExceptionInfo + *exception; + + Image + *image; + + MagickBooleanType + normalize, + status; + + RectangleInfo + region; + + register ssize_t + i; + + ssize_t + option; + + struct PackageInfo + *info; + + SV + *perl_exception, + *reference; /* reference is the SV* of ref=SvIV(reference) */ + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + reference=SvRV(ST(0)); + av=(AV *) reference; + info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL, + exception); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + map="RGB"; + if (image->matte != MagickFalse) + map="RGBA"; + if (image->colorspace == CMYKColorspace) + { + map="CMYK"; + if (image->matte != MagickFalse) + map="CMYKA"; + } + normalize=MagickFalse; + region.x=0; + region.y=0; + region.width=image->columns; + region.height=1; + if (items == 1) + (void) ParseAbsoluteGeometry(SvPV(ST(1),na),®ion); + for (i=2; i < items; i+=2) + { + attribute=(char *) SvPV(ST(i-1),na); + switch (*attribute) + { + case 'g': + case 'G': + { + if (LocaleCompare(attribute,"geometry") == 0) + { + (void) ParseAbsoluteGeometry(SvPV(ST(i),na),®ion); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'H': + case 'h': + { + if (LocaleCompare(attribute,"height") == 0) + { + region.height=SvIV(ST(i)); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'M': + case 'm': + { + if (LocaleCompare(attribute,"map") == 0) + { + map=SvPV(ST(i),na); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'N': + case 'n': + { + if (LocaleCompare(attribute,"normalize") == 0) + { + option=ParseCommandOption(MagickBooleanOptions,MagickFalse, + SvPV(ST(i),na)); + if (option < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(ST(i),na)); + break; + } + normalize=option != 0 ? MagickTrue : MagickFalse; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'W': + case 'w': + { + if (LocaleCompare(attribute,"width") == 0) + { + region.width=SvIV(ST(i)); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'x': + case 'X': + { + if (LocaleCompare(attribute,"x") == 0) + { + region.x=SvIV(ST(i)); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'y': + case 'Y': + { + if (LocaleCompare(attribute,"y") == 0) + { + region.y=SvIV(ST(i)); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + default: + { + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + } + } + if (normalize != MagickFalse) + { + float + *pixels; + + pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width, + region.height*sizeof(*pixels)); + if (pixels == (float *) NULL) + { + ThrowPerlException(exception,ResourceLimitError, + "MemoryAllocationFailed",PackageName); + goto PerlException; + } + status=ExportImagePixels(image,region.x,region.y,region.width, + region.height,map,FloatPixel,pixels,exception); + if (status == MagickFalse) + PUSHs(&sv_undef); + else + { + EXTEND(sp,strlen(map)*region.width*region.height); + for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++) + PUSHs(sv_2mortal(newSVnv(pixels[i]))); + } + pixels=(float *) RelinquishMagickMemory(pixels); + } + else + { + Quantum + *pixels; + + pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width, + region.height*sizeof(*pixels)); + if (pixels == (Quantum *) NULL) + { + ThrowPerlException(exception,ResourceLimitError, + "MemoryAllocationFailed",PackageName); + goto PerlException; + } + status=ExportImagePixels(image,region.x,region.y,region.width, + region.height,map,QuantumPixel,pixels,exception); + if (status == MagickFalse) + PUSHs(&sv_undef); + else + { + EXTEND(sp,strlen(map)*region.width*region.height); + for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++) + PUSHs(sv_2mortal(newSViv(pixels[i]))); + } + pixels=(Quantum *) RelinquishMagickMemory(pixels); + } + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); + } + +# +############################################################################### +# # +# # +# # +# I m a g e T o B l o b # +# # +# # +# # +############################################################################### +# +# +void +ImageToBlob(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + ImageToBlob = 1 + imagetoblob = 2 + toblob = 3 + blob = 4 + PPCODE: + { + char + filename[MaxTextExtent]; + + ExceptionInfo + *exception; + + Image + *image, + *next; + + register ssize_t + i; + + struct PackageInfo + *info, + *package_info; + + size_t + length; + + ssize_t + scene; + + SV + *perl_exception, + *reference; + + void + *blob; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + package_info=(struct PackageInfo *) NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + package_info=ClonePackageInfo(info,exception); + for (i=2; i < items; i+=2) + SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception); + (void) CopyMagickString(filename,package_info->image_info->filename, + MaxTextExtent); + scene=0; + for (next=image; next; next=next->next) + { + (void) CopyMagickString(next->filename,filename,MaxTextExtent); + next->scene=scene++; + } + SetImageInfo(package_info->image_info,(unsigned int) + GetImageListLength(image),&image->exception); + EXTEND(sp,(ssize_t) GetImageListLength(image)); + for ( ; image; image=image->next) + { + length=0; + blob=ImagesToBlob(package_info->image_info,image,&length,exception); + if (blob != (char *) NULL) + { + PUSHs(sv_2mortal(newSVpv((const char *) blob,length))); + blob=(unsigned char *) RelinquishMagickMemory(blob); + } + if (package_info->image_info->adjoin) + break; + } + + PerlException: + if (package_info != (struct PackageInfo *) NULL) + DestroyPackageInfo(package_info); + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); /* throw away all errors */ + } + +# +############################################################################### +# # +# # +# # +# L a y e r s # +# # +# # +# # +############################################################################### +# +# +void +Layers(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + Layers = 1 + layers = 2 + OptimizeImageLayers = 3 + optimizelayers = 4 + optimizeimagelayers = 5 + PPCODE: + { + AV + *av; + + char + *attribute; + + CompositeOperator + compose; + + ExceptionInfo + *exception; + + HV + *hv; + + Image + *image, + *layers; + + ImageLayerMethod + method; + + register ssize_t + i; + + ssize_t + option, + sp; + + struct PackageInfo + *info; + + SV + *av_reference, + *perl_exception, + *reference, + *rv, + *sv; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + sv=NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + hv=SvSTASH(reference); + av=newAV(); + av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv)); + SvREFCNT_dec(av); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + compose=image->compose; + method=OptimizeLayer; + for (i=2; i < items; i+=2) + { + attribute=(char *) SvPV(ST(i-1),na); + switch (*attribute) + { + case 'C': + case 'c': + { + if (LocaleCompare(attribute,"compose") == 0) + { + sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption( + MagickComposeOptions,MagickFalse,SvPV(ST(i),na)); + if (sp < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(ST(i),na)); + break; + } + compose=(CompositeOperator) sp; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'M': + case 'm': + { + if (LocaleCompare(attribute,"method") == 0) + { + option=ParseCommandOption(MagickLayerOptions,MagickFalse, + SvPV(ST(i),na)); + if (option < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(ST(i),na)); + break; + } + method=(ImageLayerMethod) option; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + default: + { + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + } + } + layers=(Image *) NULL; + switch (method) + { + case CompareAnyLayer: + case CompareClearLayer: + case CompareOverlayLayer: + default: + { + layers=CompareImageLayers(image,method,exception); + break; + } + case MergeLayer: + case FlattenLayer: + case MosaicLayer: + { + layers=MergeImageLayers(image,method,exception); + break; + } + case DisposeLayer: + { + layers=DisposeImages(image,exception); + break; + } + case OptimizeImageLayer: + { + layers=OptimizeImageLayers(image,exception); + break; + } + case OptimizePlusLayer: + { + layers=OptimizePlusImageLayers(image,exception); + break; + } + case OptimizeTransLayer: + { + OptimizeImageTransparency(image,exception); + InheritException(&(image->exception),exception); + break; + } + case RemoveDupsLayer: + { + RemoveDuplicateLayers(&image,exception); + InheritException(&(image->exception),exception); + break; + } + case RemoveZeroLayer: + { + RemoveZeroDelayLayers(&image,exception); + InheritException(&(image->exception),exception); + break; + } + case OptimizeLayer: + { + QuantizeInfo + *quantize_info; + + /* + General Purpose, GIF Animation Optimizer. + */ + layers=CoalesceImages(image,exception); + if (layers == (Image *) NULL) + break; + InheritException(&(layers->exception),exception); + image=layers; + layers=OptimizeImageLayers(image,exception); + if (layers == (Image *) NULL) + break; + InheritException(&(layers->exception),exception); + image=DestroyImageList(image); + image=layers; + layers=(Image *) NULL; + OptimizeImageTransparency(image,exception); + InheritException(&(image->exception),exception); + quantize_info=AcquireQuantizeInfo(info->image_info); + (void) RemapImages(quantize_info,image,(Image *) NULL); + quantize_info=DestroyQuantizeInfo(quantize_info); + break; + } + case CompositeLayer: + { + Image + *source; + + RectangleInfo + geometry; + + /* + Split image sequence at the first 'NULL:' image. + */ + source=image; + while (source != (Image *) NULL) + { + source=GetNextImageInList(source); + if ((source != (Image *) NULL) && + (LocaleCompare(source->magick,"NULL") == 0)) + break; + } + if (source != (Image *) NULL) + { + if ((GetPreviousImageInList(source) == (Image *) NULL) || + (GetNextImageInList(source) == (Image *) NULL)) + source=(Image *) NULL; + else + { + /* + Separate the two lists, junk the null: image. + */ + source=SplitImageList(source->previous); + DeleteImageFromList(&source); + } + } + if (source == (Image *) NULL) + { + (void) ThrowMagickException(exception,GetMagickModule(), + OptionError,"MissingNullSeparator","layers Composite"); + break; + } + /* + Adjust offset with gravity and virtual canvas. + */ + SetGeometry(image,&geometry); + (void) ParseAbsoluteGeometry(image->geometry,&geometry); + geometry.width=source->page.width != 0 ? source->page.width : + source->columns; + geometry.height=source->page.height != 0 ? source->page.height : + source->rows; + GravityAdjustGeometry(image->page.width != 0 ? image->page.width : + image->columns,image->page.height != 0 ? image->page.height : + image->rows,image->gravity,&geometry); + CompositeLayers(image,compose,source,geometry.x,geometry.y,exception); + source=DestroyImageList(source); + InheritException(&(image->exception),exception); + break; + } + } + if (layers == (Image *) NULL) + image=CloneImage(image,0,0,MagickTrue,exception); + else + { + InheritException(&(layers->exception),exception); + image=layers; + } + if (image == (Image *) NULL) + goto PerlException; + for ( ; image; image=image->next) + { + AddImageToRegistry(sv,image); + rv=newRV(sv); + av_push(av,sv_bless(rv,hv)); + SvREFCNT_dec(sv); + } + exception=DestroyExceptionInfo(exception); + ST(0)=av_reference; + SvREFCNT_dec(perl_exception); + XSRETURN(1); + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0); + SvPOK_on(perl_exception); + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# M a g i c k T o M i m e # +# # +# # +# # +############################################################################### +# +# +SV * +MagickToMime(ref,name) + Image::Magick ref = NO_INIT + char *name + ALIAS: + magicktomime = 1 + CODE: + { + char + *mime; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + mime=MagickToMime(name); + RETVAL=newSVpv(mime,0); + mime=(char *) RelinquishMagickMemory(mime); + } + OUTPUT: + RETVAL + +# +############################################################################### +# # +# # +# # +# M o g r i f y # +# # +# # +# # +############################################################################### +# +# +void +Mogrify(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + Comment = 1 + CommentImage = 2 + Label = 3 + LabelImage = 4 + AddNoise = 5 + AddNoiseImage = 6 + Colorize = 7 + ColorizeImage = 8 + Border = 9 + BorderImage = 10 + Blur = 11 + BlurImage = 12 + Chop = 13 + ChopImage = 14 + Crop = 15 + CropImage = 16 + Despeckle = 17 + DespeckleImage = 18 + Edge = 19 + EdgeImage = 20 + Emboss = 21 + EmbossImage = 22 + Enhance = 23 + EnhanceImage = 24 + Flip = 25 + FlipImage = 26 + Flop = 27 + FlopImage = 28 + Frame = 29 + FrameImage = 30 + Implode = 31 + ImplodeImage = 32 + Magnify = 33 + MagnifyImage = 34 + MedianFilter = 35 + MedianFilterImage = 36 + Minify = 37 + MinifyImage = 38 + OilPaint = 39 + OilPaintImage = 40 + ReduceNoise = 41 + ReduceNoiseImage = 42 + Roll = 43 + RollImage = 44 + Rotate = 45 + RotateImage = 46 + Sample = 47 + SampleImage = 48 + Scale = 49 + ScaleImage = 50 + Shade = 51 + ShadeImage = 52 + Sharpen = 53 + SharpenImage = 54 + Shear = 55 + ShearImage = 56 + Spread = 57 + SpreadImage = 58 + Swirl = 59 + SwirlImage = 60 + Resize = 61 + ResizeImage = 62 + Zoom = 63 + ZoomImage = 64 + Annotate = 65 + AnnotateImage = 66 + ColorFloodfill = 67 + ColorFloodfillImage= 68 + Composite = 69 + CompositeImage = 70 + Contrast = 71 + ContrastImage = 72 + CycleColormap = 73 + CycleColormapImage = 74 + Draw = 75 + DrawImage = 76 + Equalize = 77 + EqualizeImage = 78 + Gamma = 79 + GammaImage = 80 + Map = 81 + MapImage = 82 + MatteFloodfill = 83 + MatteFloodfillImage= 84 + Modulate = 85 + ModulateImage = 86 + Negate = 87 + NegateImage = 88 + Normalize = 89 + NormalizeImage = 90 + NumberColors = 91 + NumberColorsImage = 92 + Opaque = 93 + OpaqueImage = 94 + Quantize = 95 + QuantizeImage = 96 + Raise = 97 + RaiseImage = 98 + Segment = 99 + SegmentImage = 100 + Signature = 101 + SignatureImage = 102 + Solarize = 103 + SolarizeImage = 104 + Sync = 105 + SyncImage = 106 + Texture = 107 + TextureImage = 108 + Evaluate = 109 + EvaluateImage = 110 + Transparent = 111 + TransparentImage = 112 + Threshold = 113 + ThresholdImage = 114 + Charcoal = 115 + CharcoalImage = 116 + Trim = 117 + TrimImage = 118 + Wave = 119 + WaveImage = 120 + Separate = 121 + SeparateImage = 122 + Stereo = 125 + StereoImage = 126 + Stegano = 127 + SteganoImage = 128 + Deconstruct = 129 + DeconstructImage = 130 + GaussianBlur = 131 + GaussianBlurImage = 132 + Convolve = 133 + ConvolveImage = 134 + Profile = 135 + ProfileImage = 136 + UnsharpMask = 137 + UnsharpMaskImage = 138 + MotionBlur = 139 + MotionBlurImage = 140 + OrderedDither = 141 + OrderedDitherImage = 142 + Shave = 143 + ShaveImage = 144 + Level = 145 + LevelImage = 146 + Clip = 147 + ClipImage = 148 + AffineTransform = 149 + AffineTransformImage = 150 + Difference = 151 + DifferenceImage = 152 + AdaptiveThreshold = 153 + AdaptiveThresholdImage = 154 + Resample = 155 + ResampleImage = 156 + Describe = 157 + DescribeImage = 158 + BlackThreshold = 159 + BlackThresholdImage= 160 + WhiteThreshold = 161 + WhiteThresholdImage= 162 + RotationalBlur = 163 + RotationalBlurImage= 164 + Thumbnail = 165 + ThumbnailImage = 166 + Strip = 167 + StripImage = 168 + Tint = 169 + TintImage = 170 + Channel = 171 + ChannelImage = 172 + Splice = 173 + SpliceImage = 174 + Posterize = 175 + PosterizeImage = 176 + Shadow = 177 + ShadowImage = 178 + Identify = 179 + IdentifyImage = 180 + SepiaTone = 181 + SepiaToneImage = 182 + SigmoidalContrast = 183 + SigmoidalContrastImage = 184 + Extent = 185 + ExtentImage = 186 + Vignette = 187 + VignetteImage = 188 + ContrastStretch = 189 + ContrastStretchImage = 190 + Sans0 = 191 + Sans0Image = 192 + Sans1 = 193 + Sans1Image = 194 + AdaptiveSharpen = 195 + AdaptiveSharpenImage = 196 + Transpose = 197 + TransposeImage = 198 + Transverse = 199 + TransverseImage = 200 + AutoOrient = 201 + AutoOrientImage = 202 + AdaptiveBlur = 203 + AdaptiveBlurImage = 204 + Sketch = 205 + SketchImage = 206 + UniqueColors = 207 + UniqueColorsImage = 208 + AdaptiveResize = 209 + AdaptiveResizeImage= 210 + ClipMask = 211 + ClipMaskImage = 212 + LinearStretch = 213 + LinearStretchImage = 214 + RecolorImage = 215 + Recolor = 216 + Mask = 217 + MaskImage = 218 + Polaroid = 219 + PolaroidImage = 220 + FloodfillPaint = 221 + FloodfillPaintImage= 222 + Distort = 223 + DistortImage = 224 + Clut = 225 + ClutImage = 226 + LiquidRescale = 227 + LiquidRescaleImage = 228 + Encipher = 229 + EncipherImage = 230 + Decipher = 231 + DecipherImage = 232 + Deskew = 233 + DeskewImage = 234 + Remap = 235 + RemapImage = 236 + SparseColor = 237 + SparseColorImage = 238 + Function = 239 + FunctionImage = 240 + SelectiveBlur = 241 + SelectiveBlurImage = 242 + HaldClut = 243 + HaldClutImage = 244 + BlueShift = 245 + BlueShiftImage = 246 + ForwardFourierTransform = 247 + ForwardFourierTransformImage = 248 + InverseFourierTransform = 249 + InverseFourierTransformImage = 250 + ColorDecisionList = 251 + ColorDecisionListImage = 252 + AutoGamma = 253 + AutoGammaImage = 254 + AutoLevel = 255 + AutoLevelImage = 256 + LevelColors = 257 + LevelColorsImage = 258 + Clamp = 259 + ClampImage = 260 + Filter = 261 + FilterImage = 262 + BrightnessContrast = 263 + BrightnessContrastImage = 264 + Morphology = 265 + MorphologyImage = 266 + ColorMatrix = 267 + ColorMatrixImage = 268 + Color = 269 + ColorImage = 270 + Mode = 271 + ModeImage = 272 + Statistic = 273 + StatisticImage = 274 + Perceptible = 275 + PerceptibleImage = 276 + Poly = 277 + PolyImage = 278 + Grayscale = 279 + GrayscaleImage = 280 + CannyEdge = 281 + CannyEdgeImage = 282 + HoughLine = 283 + HoughLineImage = 284 + MeanShift = 285 + MeanShiftImage = 286 + Kuwahara = 287 + KuwaharaImage = 288 + ConnectedComponent = 289 + ConnectedComponentImage = 290 + CopyPixels = 291 + CopyPixelsImage = 292 + WaveletDenoise = 293 + WaveletDenoiseImage= 294 + MogrifyRegion = 666 + PPCODE: + { + AffineMatrix + affine, + current; + + char + attribute_flag[MaxArguments], + message[MaxTextExtent]; + + ChannelType + channel; + + CompositeOperator + compose; + + const char + *attribute, + *value; + + double + angle; + + ExceptionInfo + *exception; + + GeometryInfo + geometry_info; + + Image + *image, + *next, + *region_image; + + MagickBooleanType + status; + + MagickStatusType + flags; + + PixelPacket + fill_color; + + RectangleInfo + geometry, + region_info; + + register ssize_t + i; + + ssize_t + base, + j, + number_images; + + struct Methods + *rp; + + struct PackageInfo + *info; + + SV + *perl_exception, + **pv, + *reference, + **reference_vector; + + struct ArgumentList + argument_list[MaxArguments]; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + reference_vector=NULL; + region_image=NULL; + number_images=0; + base=2; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + region_info.width=0; + region_info.height=0; + region_info.x=0; + region_info.y=0; + region_image=(Image *) NULL; + image=SetupList(aTHX_ reference,&info,&reference_vector,exception); + if (ix && (ix != 666)) + { + /* + Called as Method(...) + */ + ix=(ix+1)/2; + rp=(&Methods[ix-1]); + attribute=rp->name; + } + else + { + /* + Called as Mogrify("Method",...) + */ + attribute=(char *) SvPV(ST(1),na); + if (ix) + { + flags=ParseGravityGeometry(image,attribute,®ion_info,exception); + attribute=(char *) SvPV(ST(2),na); + base++; + } + for (rp=Methods; ; rp++) + { + if (rp >= EndOf(Methods)) + { + ThrowPerlException(exception,OptionError, + "UnrecognizedPerlMagickMethod",attribute); + goto PerlException; + } + if (strEQcase(attribute,rp->name)) + break; + } + ix=rp-Methods+1; + base++; + } + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute); + goto PerlException; + } + Zero(&argument_list,NumberOf(argument_list),struct ArgumentList); + Zero(&attribute_flag,NumberOf(attribute_flag),char); + for (i=base; (i < items) || ((i == items) && (base == items)); i+=2) + { + Arguments + *pp, + *qq; + + ssize_t + ssize_test; + + struct ArgumentList + *al; + + SV + *sv; + + sv=NULL; + ssize_test=0; + pp=(Arguments *) NULL; + qq=rp->arguments; + if (i == items) + { + pp=rp->arguments, + sv=ST(i-1); + } + else + for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++) + { + if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL)) + break; + if (strEQcase(attribute,qq->method) > ssize_test) + { + pp=qq; + ssize_test=strEQcase(attribute,qq->method); + } + } + if (pp == (Arguments *) NULL) + { + ThrowPerlException(exception,OptionError,"UnrecognizedOption", + attribute); + goto continue_outer_loop; + } + al=(&argument_list[pp-rp->arguments]); + switch (pp->type) + { + case ArrayReference: + { + if (SvTYPE(sv) != SVt_RV) + { + (void) FormatLocaleString(message,MaxTextExtent, + "invalid %.60s value",pp->method); + ThrowPerlException(exception,OptionError,message,SvPV(sv,na)); + goto continue_outer_loop; + } + al->array_reference=SvRV(sv); + break; + } + case RealReference: + { + al->real_reference=SvNV(sv); + break; + } + case FileReference: + { + al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv))); + break; + } + case ImageReference: + { + if (!sv_isobject(sv) || + !(al->image_reference=SetupList(aTHX_ SvRV(sv), + (struct PackageInfo **) NULL,(SV ***) NULL,exception))) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + break; + } + case IntegerReference: + { + al->integer_reference=SvIV(sv); + break; + } + case StringReference: + { + al->string_reference=(char *) SvPV(sv,al->length); + if (sv_isobject(sv)) + al->image_reference=SetupList(aTHX_ SvRV(sv), + (struct PackageInfo **) NULL,(SV ***) NULL,exception); + break; + } + default: + { + /* + Is a string; look up name. + */ + if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@')) + { + al->string_reference=(char *) SvPV(sv,al->length); + al->integer_reference=(-1); + break; + } + al->integer_reference=ParseCommandOption((CommandOption) pp->type, + MagickFalse,SvPV(sv,na)); + if (pp->type == MagickChannelOptions) + al->integer_reference=ParseChannelOption(SvPV(sv,na)); + if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0)) + { + (void) FormatLocaleString(message,MaxTextExtent, + "invalid %.60s value",pp->method); + ThrowPerlException(exception,OptionError,message,SvPV(sv,na)); + goto continue_outer_loop; + } + break; + } + } + attribute_flag[pp-rp->arguments]++; + continue_outer_loop: ; + } + (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color)); + pv=reference_vector; + SetGeometryInfo(&geometry_info); + channel=DefaultChannels; + for (next=image; next; next=next->next) + { + image=next; + SetGeometry(image,&geometry); + if ((region_info.width*region_info.height) != 0) + { + region_image=image; + image=CropImage(image,®ion_info,exception); + } + switch (ix) + { + default: + { + (void) FormatLocaleString(message,MaxTextExtent,"%.20g",(double) ix); + ThrowPerlException(exception,OptionError, + "UnrecognizedPerlMagickMethod",message); + goto PerlException; + } + case 1: /* Comment */ + { + if (attribute_flag[0] == 0) + argument_list[0].string_reference=(char *) NULL; + (void) SetImageProperty(image,"comment",InterpretImageProperties( + info ? info->image_info : (ImageInfo *) NULL,image, + argument_list[0].string_reference)); + break; + } + case 2: /* Label */ + { + if (attribute_flag[0] == 0) + argument_list[0].string_reference=(char *) NULL; + (void) SetImageProperty(image,"label",InterpretImageProperties( + info ? info->image_info : (ImageInfo *) NULL,image, + argument_list[0].string_reference)); + break; + } + case 3: /* AddNoise */ + { + if (attribute_flag[0] == 0) + argument_list[0].integer_reference=UniformNoise; + if (attribute_flag[1] != 0) + channel=(ChannelType) argument_list[1].integer_reference; + image=AddNoiseImageChannel(image,channel,(NoiseType) + argument_list[0].integer_reference,exception); + break; + } + case 4: /* Colorize */ + { + PixelPacket + target; + + (void) GetOneVirtualPixel(image,0,0,&target,exception); + if (attribute_flag[0] != 0) + (void) QueryColorDatabase(argument_list[0].string_reference,&target, + exception); + if (attribute_flag[1] == 0) + argument_list[1].string_reference="100%"; + image=ColorizeImage(image,argument_list[1].string_reference,target, + exception); + break; + } + case 5: /* Border */ + { + geometry.width=0; + geometry.height=0; + if (attribute_flag[0] != 0) + flags=ParsePageGeometry(image,argument_list[0].string_reference, + &geometry,exception); + if (attribute_flag[1] != 0) + geometry.width=argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + geometry.height=argument_list[2].integer_reference; + if (attribute_flag[3] != 0) + QueryColorDatabase(argument_list[3].string_reference, + &image->border_color,exception); + if (attribute_flag[4] != 0) + QueryColorDatabase(argument_list[4].string_reference, + &image->border_color,exception); + if (attribute_flag[5] != 0) + QueryColorDatabase(argument_list[5].string_reference, + &image->border_color,exception); + if (attribute_flag[6] != 0) + image->compose=(CompositeOperator) + argument_list[6].integer_reference; + image=BorderImage(image,&geometry,exception); + break; + } + case 6: /* Blur */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=1.0; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + channel=(ChannelType) argument_list[3].integer_reference; + image=BlurImageChannel(image,channel,geometry_info.rho, + geometry_info.sigma,exception); + break; + } + case 7: /* Chop */ + { + if (attribute_flag[5] != 0) + image->gravity=(GravityType) argument_list[5].integer_reference; + if (attribute_flag[0] != 0) + flags=ParseGravityGeometry(image,argument_list[0].string_reference, + &geometry,exception); + if (attribute_flag[1] != 0) + geometry.width=argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + geometry.height=argument_list[2].integer_reference; + if (attribute_flag[3] != 0) + geometry.x=argument_list[3].integer_reference; + if (attribute_flag[4] != 0) + geometry.y=argument_list[4].integer_reference; + image=ChopImage(image,&geometry,exception); + break; + } + case 8: /* Crop */ + { + if (attribute_flag[6] != 0) + image->gravity=(GravityType) argument_list[6].integer_reference; + if (attribute_flag[0] != 0) + flags=ParseGravityGeometry(image,argument_list[0].string_reference, + &geometry,exception); + if (attribute_flag[1] != 0) + geometry.width=argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + geometry.height=argument_list[2].integer_reference; + if (attribute_flag[3] != 0) + geometry.x=argument_list[3].integer_reference; + if (attribute_flag[4] != 0) + geometry.y=argument_list[4].integer_reference; + if (attribute_flag[5] != 0) + image->fuzz=StringToDoubleInterval( + argument_list[5].string_reference,(double) QuantumRange+1.0); + image=CropImage(image,&geometry,exception); + break; + } + case 9: /* Despeckle */ + { + image=DespeckleImage(image,exception); + break; + } + case 10: /* Edge */ + { + if (attribute_flag[0] != 0) + geometry_info.rho=argument_list[0].real_reference; + image=EdgeImage(image,geometry_info.rho,exception); + break; + } + case 11: /* Emboss */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=1.0; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + image=EmbossImage(image,geometry_info.rho,geometry_info.sigma, + exception); + break; + } + case 12: /* Enhance */ + { + image=EnhanceImage(image,exception); + break; + } + case 13: /* Flip */ + { + image=FlipImage(image,exception); + break; + } + case 14: /* Flop */ + { + image=FlopImage(image,exception); + break; + } + case 15: /* Frame */ + { + FrameInfo + frame_info; + + if (attribute_flag[0] != 0) + { + flags=ParsePageGeometry(image,argument_list[0].string_reference, + &geometry,exception); + frame_info.width=geometry.width; + frame_info.height=geometry.height; + frame_info.outer_bevel=geometry.x; + frame_info.inner_bevel=geometry.y; + } + if (attribute_flag[1] != 0) + frame_info.width=argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + frame_info.height=argument_list[2].integer_reference; + if (attribute_flag[3] != 0) + frame_info.inner_bevel=argument_list[3].integer_reference; + if (attribute_flag[4] != 0) + frame_info.outer_bevel=argument_list[4].integer_reference; + if (attribute_flag[5] != 0) + QueryColorDatabase(argument_list[5].string_reference,&fill_color, + exception); + if (attribute_flag[6] != 0) + QueryColorDatabase(argument_list[6].string_reference,&fill_color, + exception); + frame_info.x=(ssize_t) frame_info.width; + frame_info.y=(ssize_t) frame_info.height; + frame_info.width=image->columns+2*frame_info.x; + frame_info.height=image->rows+2*frame_info.y; + if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0)) + image->matte_color=fill_color; + if (attribute_flag[7] != 0) + image->compose=(CompositeOperator) + argument_list[7].integer_reference; + image=FrameImage(image,&frame_info,exception); + break; + } + case 16: /* Implode */ + { + if (attribute_flag[0] == 0) + argument_list[0].real_reference=0.5; + if (attribute_flag[1] != 0) + image->interpolate=(InterpolatePixelMethod) + argument_list[1].integer_reference; + image=ImplodeImage(image,argument_list[0].real_reference, + exception); + break; + } + case 17: /* Magnify */ + { + image=MagnifyImage(image,exception); + break; + } + case 18: /* MedianFilter */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=1.0; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + channel=(ChannelType) argument_list[3].integer_reference; + image=StatisticImageChannel(image,channel,MedianStatistic, + (size_t) geometry_info.rho,(size_t) geometry_info.sigma,exception); + break; + } + case 19: /* Minify */ + { + image=MinifyImage(image,exception); + break; + } + case 20: /* OilPaint */ + { + if (attribute_flag[0] == 0) + argument_list[0].real_reference=0.0; + image=OilPaintImage(image,argument_list[0].real_reference, + exception); + break; + } + case 21: /* ReduceNoise */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=1.0; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + channel=(ChannelType) argument_list[3].integer_reference; + image=StatisticImageChannel(image,channel,NonpeakStatistic, + (size_t) geometry_info.rho,(size_t) geometry_info.sigma,exception); + break; + } + case 22: /* Roll */ + { + if (attribute_flag[0] != 0) + flags=ParsePageGeometry(image,argument_list[0].string_reference, + &geometry,exception); + if (attribute_flag[1] != 0) + geometry.x=argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + geometry.y=argument_list[2].integer_reference; + image=RollImage(image,geometry.x,geometry.y,exception); + break; + } + case 23: /* Rotate */ + { + if (attribute_flag[0] == 0) + argument_list[0].real_reference=90.0; + if (attribute_flag[1] != 0) + QueryColorDatabase(argument_list[1].string_reference, + &image->background_color,exception); + if (attribute_flag[2] != 0) + QueryColorDatabase(argument_list[2].string_reference, + &image->background_color,exception); + if (attribute_flag[3] != 0) + QueryColorDatabase(argument_list[3].string_reference, + &image->background_color,exception); + image=RotateImage(image,argument_list[0].real_reference,exception); + break; + } + case 24: /* Sample */ + { + if (attribute_flag[0] != 0) + flags=ParseRegionGeometry(image,argument_list[0].string_reference, + &geometry,exception); + if (attribute_flag[1] != 0) + geometry.width=argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + geometry.height=argument_list[2].integer_reference; + image=SampleImage(image,geometry.width,geometry.height,exception); + break; + } + case 25: /* Scale */ + { + if (attribute_flag[0] != 0) + flags=ParseRegionGeometry(image,argument_list[0].string_reference, + &geometry,exception); + if (attribute_flag[1] != 0) + geometry.width=argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + geometry.height=argument_list[2].integer_reference; + image=ScaleImage(image,geometry.width,geometry.height,exception); + break; + } + case 26: /* Shade */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=0.0; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + image=ShadeImage(image, + argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse, + geometry_info.rho,geometry_info.sigma,exception); + break; + } + case 27: /* Sharpen */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=1.0; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + channel=(ChannelType) argument_list[3].integer_reference; + image=SharpenImageChannel(image,channel,geometry_info.rho, + geometry_info.sigma,exception); + break; + } + case 28: /* Shear */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=geometry_info.rho; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + QueryColorDatabase(argument_list[3].string_reference, + &image->background_color,exception); + if (attribute_flag[4] != 0) + QueryColorDatabase(argument_list[4].string_reference, + &image->background_color,exception); + image=ShearImage(image,geometry_info.rho,geometry_info.sigma, + exception); + break; + } + case 29: /* Spread */ + { + if (attribute_flag[0] == 0) + argument_list[0].real_reference=1.0; + image=SpreadImage(image,argument_list[0].real_reference,exception); + break; + } + case 30: /* Swirl */ + { + if (attribute_flag[0] == 0) + argument_list[0].real_reference=50.0; + if (attribute_flag[1] != 0) + image->interpolate=(InterpolatePixelMethod) + argument_list[1].integer_reference; + image=SwirlImage(image,argument_list[0].real_reference,exception); + break; + } + case 31: /* Resize */ + case 32: /* Zoom */ + { + if (attribute_flag[0] != 0) + flags=ParseRegionGeometry(image,argument_list[0].string_reference, + &geometry,exception); + if (attribute_flag[1] != 0) + geometry.width=argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + geometry.height=argument_list[2].integer_reference; + if (attribute_flag[3] == 0) + argument_list[3].integer_reference=(ssize_t) UndefinedFilter; + if (attribute_flag[4] != 0) + SetImageArtifact(image,"filter:support", + argument_list[4].string_reference); + if (attribute_flag[5] == 0) + argument_list[5].real_reference=1.0; + image=ResizeImage(image,geometry.width,geometry.height, + (FilterTypes) argument_list[3].integer_reference, + argument_list[5].real_reference,exception); + break; + } + case 33: /* Annotate */ + { + DrawInfo + *draw_info; + + draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL, + (DrawInfo *) NULL); + if (attribute_flag[0] != 0) + { + char + *text; + + text=InterpretImageProperties(info ? info->image_info : + (ImageInfo *) NULL,image,argument_list[0].string_reference); + (void) CloneString(&draw_info->text,text); + text=DestroyString(text); + } + if (attribute_flag[1] != 0) + (void) CloneString(&draw_info->font, + argument_list[1].string_reference); + if (attribute_flag[2] != 0) + draw_info->pointsize=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + (void) CloneString(&draw_info->density, + argument_list[3].string_reference); + if (attribute_flag[4] != 0) + (void) QueryColorDatabase(argument_list[4].string_reference, + &draw_info->undercolor,exception); + if (attribute_flag[5] != 0) + { + (void) QueryColorDatabase(argument_list[5].string_reference, + &draw_info->stroke,exception); + if (argument_list[5].image_reference != (Image *) NULL) + draw_info->stroke_pattern=CloneImage( + argument_list[5].image_reference,0,0,MagickTrue,exception); + } + if (attribute_flag[6] != 0) + { + (void) QueryColorDatabase(argument_list[6].string_reference, + &draw_info->fill,exception); + if (argument_list[6].image_reference != (Image *) NULL) + draw_info->fill_pattern=CloneImage( + argument_list[6].image_reference,0,0,MagickTrue,exception); + } + if (attribute_flag[7] != 0) + { + (void) CloneString(&draw_info->geometry, + argument_list[7].string_reference); + flags=ParsePageGeometry(image,argument_list[7].string_reference, + &geometry,exception); + if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0)) + geometry_info.sigma=geometry_info.xi; + } + if (attribute_flag[8] != 0) + (void) QueryColorDatabase(argument_list[8].string_reference, + &draw_info->fill,exception); + if (attribute_flag[11] != 0) + draw_info->gravity=(GravityType) argument_list[11].integer_reference; + if (attribute_flag[25] != 0) + { + AV + *av; + + av=(AV *) argument_list[25].array_reference; + if ((av_len(av) != 3) && (av_len(av) != 5)) + { + ThrowPerlException(exception,OptionError, + "affine matrix must have 4 or 6 elements",PackageName); + goto PerlException; + } + draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0))); + draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0))); + draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0))); + draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0))); + if (fabs(draw_info->affine.sx*draw_info->affine.sy- + draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon) + { + ThrowPerlException(exception,OptionError, + "affine matrix is singular",PackageName); + goto PerlException; + } + if (av_len(av) == 5) + { + draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0))); + draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0))); + } + } + for (j=12; j < 17; j++) + { + if (attribute_flag[j] == 0) + continue; + value=argument_list[j].string_reference; + angle=argument_list[j].real_reference; + current=draw_info->affine; + GetAffineMatrix(&affine); + switch (j) + { + case 12: + { + /* + Translate. + */ + flags=ParseGeometry(value,&geometry_info); + affine.tx=geometry_info.xi; + affine.ty=geometry_info.psi; + if ((flags & PsiValue) == 0) + affine.ty=affine.tx; + break; + } + case 13: + { + /* + Scale. + */ + flags=ParseGeometry(value,&geometry_info); + affine.sx=geometry_info.rho; + affine.sy=geometry_info.sigma; + if ((flags & SigmaValue) == 0) + affine.sy=affine.sx; + break; + } + case 14: + { + /* + Rotate. + */ + if (angle == 0.0) + break; + affine.sx=cos(DegreesToRadians(fmod(angle,360.0))); + affine.rx=sin(DegreesToRadians(fmod(angle,360.0))); + affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0)))); + affine.sy=cos(DegreesToRadians(fmod(angle,360.0))); + break; + } + case 15: + { + /* + SkewX. + */ + affine.ry=tan(DegreesToRadians(fmod(angle,360.0))); + break; + } + case 16: + { + /* + SkewY. + */ + affine.rx=tan(DegreesToRadians(fmod(angle,360.0))); + break; + } + } + draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx; + draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx; + draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy; + draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy; + draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+ + current.tx; + draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+ + current.ty; + } + if (attribute_flag[9] == 0) + argument_list[9].real_reference=0.0; + if (attribute_flag[10] == 0) + argument_list[10].real_reference=0.0; + if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0)) + { + char + geometry[MaxTextExtent]; + + (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f", + (double) argument_list[9].real_reference+draw_info->affine.tx, + (double) argument_list[10].real_reference+draw_info->affine.ty); + (void) CloneString(&draw_info->geometry,geometry); + } + if (attribute_flag[17] != 0) + draw_info->stroke_width=argument_list[17].real_reference; + if (attribute_flag[18] != 0) + { + draw_info->text_antialias=argument_list[18].integer_reference != 0 ? + MagickTrue : MagickFalse; + draw_info->stroke_antialias=draw_info->text_antialias; + } + if (attribute_flag[19] != 0) + (void) CloneString(&draw_info->family, + argument_list[19].string_reference); + if (attribute_flag[20] != 0) + draw_info->style=(StyleType) argument_list[20].integer_reference; + if (attribute_flag[21] != 0) + draw_info->stretch=(StretchType) argument_list[21].integer_reference; + if (attribute_flag[22] != 0) + draw_info->weight=argument_list[22].integer_reference; + if (attribute_flag[23] != 0) + draw_info->align=(AlignType) argument_list[23].integer_reference; + if (attribute_flag[24] != 0) + (void) CloneString(&draw_info->encoding, + argument_list[24].string_reference); + if (attribute_flag[25] != 0) + draw_info->fill_pattern=CloneImage( + argument_list[25].image_reference,0,0,MagickTrue,exception); + if (attribute_flag[26] != 0) + draw_info->fill_pattern=CloneImage( + argument_list[26].image_reference,0,0,MagickTrue,exception); + if (attribute_flag[27] != 0) + draw_info->stroke_pattern=CloneImage( + argument_list[27].image_reference,0,0,MagickTrue,exception); + if (attribute_flag[29] != 0) + draw_info->kerning=argument_list[29].real_reference; + if (attribute_flag[30] != 0) + draw_info->interline_spacing=argument_list[30].real_reference; + if (attribute_flag[31] != 0) + draw_info->interword_spacing=argument_list[31].real_reference; + if (attribute_flag[32] != 0) + draw_info->direction=(DirectionType) + argument_list[32].integer_reference; + (void) AnnotateImage(image,draw_info); + draw_info=DestroyDrawInfo(draw_info); + break; + } + case 34: /* ColorFloodfill */ + { + DrawInfo + *draw_info; + + MagickBooleanType + invert; + + MagickPixelPacket + target; + + draw_info=CloneDrawInfo(info ? info->image_info : + (ImageInfo *) NULL,(DrawInfo *) NULL); + if (attribute_flag[0] != 0) + flags=ParsePageGeometry(image,argument_list[0].string_reference, + &geometry,exception); + if (attribute_flag[1] != 0) + geometry.x=argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + geometry.y=argument_list[2].integer_reference; + if (attribute_flag[3] != 0) + (void) QueryColorDatabase(argument_list[3].string_reference, + &draw_info->fill,exception); + (void) GetOneVirtualMagickPixel(image,geometry.x,geometry.y,&target, + exception); + invert=MagickFalse; + if (attribute_flag[4] != 0) + { + QueryMagickColor(argument_list[4].string_reference,&target, + exception); + invert=MagickTrue; + } + if (attribute_flag[5] != 0) + image->fuzz=StringToDoubleInterval( + argument_list[5].string_reference,(double) QuantumRange+1.0); + if (attribute_flag[6] != 0) + invert=(MagickBooleanType) argument_list[6].integer_reference; + (void) FloodfillPaintImage(image,DefaultChannels,draw_info,&target, + geometry.x,geometry.y,invert); + draw_info=DestroyDrawInfo(draw_info); + break; + } + case 35: /* Composite */ + { + char + composite_geometry[MaxTextExtent]; + + Image + *composite_image, + *rotate_image; + + compose=OverCompositeOp; + if (attribute_flag[0] != 0) + composite_image=argument_list[0].image_reference; + else + { + ThrowPerlException(exception,OptionError, + "CompositeImageRequired",PackageName); + goto PerlException; + } + /* + Parameter Handling used for BOTH normal and tiled composition. + */ + if (attribute_flag[1] != 0) /* compose */ + compose=(CompositeOperator) argument_list[1].integer_reference; + if (attribute_flag[6] != 0) /* opacity */ + { + if (compose != DissolveCompositeOp) + (void) SetImageOpacity(composite_image,(Quantum) (QuantumRange- + StringToDoubleInterval(argument_list[6].string_reference, + (double) QuantumRange+1.0))); + else + { + CacheView + *composite_view; + + double + opacity; + + MagickBooleanType + sync; + + register ssize_t + x; + + register PixelPacket + *q; + + ssize_t + y; + + /* + Handle dissolve composite operator. + */ + (void) CloneString(&image->geometry, + argument_list[6].string_reference); + opacity=(Quantum) (QuantumRange-StringToDoubleInterval( + argument_list[6].string_reference,(double) QuantumRange+ + 1.0)); + if (composite_image->matte != MagickTrue) + (void) SetImageOpacity(composite_image,OpaqueOpacity); + composite_view=AcquireAuthenticCacheView(composite_image, + exception); + for (y=0; y < (ssize_t) composite_image->rows ; y++) + { + q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t) + composite_image->columns,1,exception); + for (x=0; x < (ssize_t) composite_image->columns; x++) + { + if (q->opacity == OpaqueOpacity) + q->opacity=ClampToQuantum(opacity); + q++; + } + sync=SyncCacheViewAuthenticPixels(composite_view,exception); + if (sync == MagickFalse) + break; + } + composite_view=DestroyCacheView(composite_view); + } + } + if (attribute_flag[9] != 0) /* "color=>" */ + QueryColorDatabase(argument_list[9].string_reference, + &composite_image->background_color,exception); + if (attribute_flag[12] != 0) /* "interpolate=>" */ + image->interpolate=(InterpolatePixelMethod) + argument_list[12].integer_reference; + if (attribute_flag[13] != 0) /* "args=>" */ + (void) SetImageArtifact(composite_image,"compose:args", + argument_list[13].string_reference); + if (attribute_flag[14] != 0) /* "blend=>" depreciated */ + (void) SetImageArtifact(composite_image,"compose:args", + argument_list[14].string_reference); + /* + Tiling Composition (with orthogonal rotate). + */ + rotate_image=(Image *) NULL; + if (attribute_flag[8] != 0) /* "rotate=>" */ + { + /* + Rotate image. + */ + rotate_image=RotateImage(composite_image, + argument_list[8].real_reference,exception); + if (rotate_image == (Image *) NULL) + break; + } + if ((attribute_flag[7] != 0) && + (argument_list[7].integer_reference != 0)) /* tile */ + { + ssize_t + x, + y; + + /* + Tile the composite image. + */ + if (attribute_flag[8] != 0) /* "tile=>" */ + (void) SetImageArtifact(rotate_image,"compose:outside-overlay", + "false"); + else + (void) SetImageArtifact(composite_image, + "compose:outside-overlay","false"); + for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows) + for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns) + { + if (attribute_flag[8] != 0) /* rotate */ + (void) CompositeImage(image,compose,rotate_image,x,y); + else + (void) CompositeImage(image,compose,composite_image,x,y); + } + if (attribute_flag[8] != 0) /* rotate */ + rotate_image=DestroyImage(rotate_image); + break; + } + /* + Parameter Handling used used ONLY for normal composition. + */ + if (attribute_flag[5] != 0) /* gravity */ + image->gravity=(GravityType) argument_list[5].integer_reference; + if (attribute_flag[2] != 0) /* geometry offset */ + { + SetGeometry(image,&geometry); + (void) ParseAbsoluteGeometry(argument_list[2].string_reference, + &geometry); + GravityAdjustGeometry(image->columns,image->rows,image->gravity, + &geometry); + } + if (attribute_flag[3] != 0) /* x offset */ + geometry.x=argument_list[3].integer_reference; + if (attribute_flag[4] != 0) /* y offset */ + geometry.y=argument_list[4].integer_reference; + if (attribute_flag[10] != 0) /* mask */ + { + if ((image->compose == DisplaceCompositeOp) || + (image->compose == DistortCompositeOp)) + { + /* + Merge Y displacement into X displacement image. + */ + composite_image=CloneImage(composite_image,0,0,MagickTrue, + &image->exception); + (void) CompositeImage(composite_image,CopyGreenCompositeOp, + argument_list[10].image_reference,0,0); + } + else + { + /* + Set a blending mask for the composition. + */ + image->mask=CloneImage(argument_list[10].image_reference,0,0, + MagickTrue,&image->exception); + (void) NegateImage(image->mask,MagickFalse); + } + } + if (attribute_flag[11] != 0) /* channel */ + channel=(ChannelType) argument_list[11].integer_reference; + /* + Composite two images (normal composition). + */ + (void) FormatLocaleString(composite_geometry,MaxTextExtent, + "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns, + (double) composite_image->rows,(double) geometry.x,(double) + geometry.y); + flags=ParseGravityGeometry(image,composite_geometry,&geometry, + exception); + if (attribute_flag[8] == 0) /* no rotate */ + CompositeImageChannel(image,channel,compose,composite_image, + geometry.x,geometry.y); + else + { + /* + Position adjust rotated image then composite. + */ + geometry.x-=(ssize_t) (rotate_image->columns- + composite_image->columns)/2; + geometry.y-=(ssize_t) (rotate_image->rows- + composite_image->rows)/2; + CompositeImageChannel(image,channel,compose,rotate_image, + geometry.x,geometry.y); + rotate_image=DestroyImage(rotate_image); + } + if (attribute_flag[10] != 0) /* mask */ + { + if ((image->compose == DisplaceCompositeOp) || + (image->compose == DistortCompositeOp)) + composite_image=DestroyImage(composite_image); + else + image->mask=DestroyImage(image->mask); + } + break; + } + case 36: /* Contrast */ + { + if (attribute_flag[0] == 0) + argument_list[0].integer_reference=0; + (void) ContrastImage(image,argument_list[0].integer_reference != 0 ? + MagickTrue : MagickFalse); + break; + } + case 37: /* CycleColormap */ + { + if (attribute_flag[0] == 0) + argument_list[0].integer_reference=6; + (void) CycleColormapImage(image,argument_list[0].integer_reference); + break; + } + case 38: /* Draw */ + { + DrawInfo + *draw_info; + + draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL, + (DrawInfo *) NULL); + (void) CloneString(&draw_info->primitive,"point"); + if (attribute_flag[0] != 0) + { + if (argument_list[0].integer_reference < 0) + (void) CloneString(&draw_info->primitive, + argument_list[0].string_reference); + else + (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic( + MagickPrimitiveOptions,argument_list[0].integer_reference)); + } + if (attribute_flag[1] != 0) + { + if (LocaleCompare(draw_info->primitive,"path") == 0) + { + (void) ConcatenateString(&draw_info->primitive," '"); + ConcatenateString(&draw_info->primitive, + argument_list[1].string_reference); + (void) ConcatenateString(&draw_info->primitive,"'"); + } + else + { + (void) ConcatenateString(&draw_info->primitive," "); + ConcatenateString(&draw_info->primitive, + argument_list[1].string_reference); + } + } + if (attribute_flag[2] != 0) + { + (void) ConcatenateString(&draw_info->primitive," "); + (void) ConcatenateString(&draw_info->primitive, + CommandOptionToMnemonic(MagickMethodOptions, + argument_list[2].integer_reference)); + } + if (attribute_flag[3] != 0) + { + (void) QueryColorDatabase(argument_list[3].string_reference, + &draw_info->stroke,exception); + if (argument_list[3].image_reference != (Image *) NULL) + draw_info->stroke_pattern=CloneImage( + argument_list[3].image_reference,0,0,MagickTrue,exception); + } + if (attribute_flag[4] != 0) + { + (void) QueryColorDatabase(argument_list[4].string_reference, + &draw_info->fill,exception); + if (argument_list[4].image_reference != (Image *) NULL) + draw_info->fill_pattern=CloneImage( + argument_list[4].image_reference,0,0,MagickTrue,exception); + } + if (attribute_flag[5] != 0) + draw_info->stroke_width=argument_list[5].real_reference; + if (attribute_flag[6] != 0) + (void) CloneString(&draw_info->font, + argument_list[6].string_reference); + if (attribute_flag[7] != 0) + (void) QueryColorDatabase(argument_list[7].string_reference, + &draw_info->border_color,exception); + if (attribute_flag[8] != 0) + draw_info->affine.tx=argument_list[8].real_reference; + if (attribute_flag[9] != 0) + draw_info->affine.ty=argument_list[9].real_reference; + if (attribute_flag[20] != 0) + { + AV + *av; + + av=(AV *) argument_list[20].array_reference; + if ((av_len(av) != 3) && (av_len(av) != 5)) + { + ThrowPerlException(exception,OptionError, + "affine matrix must have 4 or 6 elements",PackageName); + goto PerlException; + } + draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0))); + draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0))); + draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0))); + draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0))); + if (fabs(draw_info->affine.sx*draw_info->affine.sy- + draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon) + { + ThrowPerlException(exception,OptionError, + "affine matrix is singular",PackageName); + goto PerlException; + } + if (av_len(av) == 5) + { + draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0))); + draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0))); + } + } + for (j=10; j < 15; j++) + { + if (attribute_flag[j] == 0) + continue; + value=argument_list[j].string_reference; + angle=argument_list[j].real_reference; + current=draw_info->affine; + GetAffineMatrix(&affine); + switch (j) + { + case 10: + { + /* + Translate. + */ + flags=ParseGeometry(value,&geometry_info); + affine.tx=geometry_info.xi; + affine.ty=geometry_info.psi; + if ((flags & PsiValue) == 0) + affine.ty=affine.tx; + break; + } + case 11: + { + /* + Scale. + */ + flags=ParseGeometry(value,&geometry_info); + affine.sx=geometry_info.rho; + affine.sy=geometry_info.sigma; + if ((flags & SigmaValue) == 0) + affine.sy=affine.sx; + break; + } + case 12: + { + /* + Rotate. + */ + if (angle == 0.0) + break; + affine.sx=cos(DegreesToRadians(fmod(angle,360.0))); + affine.rx=sin(DegreesToRadians(fmod(angle,360.0))); + affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0)))); + affine.sy=cos(DegreesToRadians(fmod(angle,360.0))); + break; + } + case 13: + { + /* + SkewX. + */ + affine.ry=tan(DegreesToRadians(fmod(angle,360.0))); + break; + } + case 14: + { + /* + SkewY. + */ + affine.rx=tan(DegreesToRadians(fmod(angle,360.0))); + break; + } + } + draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx; + draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx; + draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy; + draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy; + draw_info->affine.tx= + current.sx*affine.tx+current.ry*affine.ty+current.tx; + draw_info->affine.ty= + current.rx*affine.tx+current.sy*affine.ty+current.ty; + } + if (attribute_flag[15] != 0) + draw_info->fill_pattern=CloneImage( + argument_list[15].image_reference,0,0,MagickTrue,exception); + if (attribute_flag[16] != 0) + draw_info->pointsize=argument_list[16].real_reference; + if (attribute_flag[17] != 0) + { + draw_info->stroke_antialias=argument_list[17].integer_reference != 0 + ? MagickTrue : MagickFalse; + draw_info->text_antialias=draw_info->stroke_antialias; + } + if (attribute_flag[18] != 0) + (void) CloneString(&draw_info->density, + argument_list[18].string_reference); + if (attribute_flag[19] != 0) + draw_info->stroke_width=argument_list[19].real_reference; + if (attribute_flag[21] != 0) + draw_info->dash_offset=argument_list[21].real_reference; + if (attribute_flag[22] != 0) + { + AV + *av; + + av=(AV *) argument_list[22].array_reference; + draw_info->dash_pattern=(double *) AcquireQuantumMemory( + av_len(av)+2UL,sizeof(*draw_info->dash_pattern)); + if (draw_info->dash_pattern != (double *) NULL) + { + for (i=0; i <= av_len(av); i++) + draw_info->dash_pattern[i]=(double) + SvNV(*(av_fetch(av,i,0))); + draw_info->dash_pattern[i]=0.0; + } + } + if (attribute_flag[23] != 0) + image->interpolate=(InterpolatePixelMethod) + argument_list[23].integer_reference; + if ((attribute_flag[24] != 0) && + (draw_info->fill_pattern != (Image *) NULL)) + flags=ParsePageGeometry(draw_info->fill_pattern, + argument_list[24].string_reference, + &draw_info->fill_pattern->tile_offset,exception); + if (attribute_flag[25] != 0) + { + (void) ConcatenateString(&draw_info->primitive," '"); + (void) ConcatenateString(&draw_info->primitive, + argument_list[25].string_reference); + (void) ConcatenateString(&draw_info->primitive,"'"); + } + if (attribute_flag[26] != 0) + draw_info->fill_pattern=CloneImage( + argument_list[26].image_reference,0,0,MagickTrue,exception); + if (attribute_flag[27] != 0) + draw_info->stroke_pattern=CloneImage( + argument_list[27].image_reference,0,0,MagickTrue,exception); + if (attribute_flag[28] != 0) + (void) CloneString(&draw_info->primitive, + argument_list[28].string_reference); + if (attribute_flag[29] != 0) + draw_info->kerning=argument_list[29].real_reference; + if (attribute_flag[30] != 0) + draw_info->interline_spacing=argument_list[30].real_reference; + if (attribute_flag[31] != 0) + draw_info->interword_spacing=argument_list[31].real_reference; + if (attribute_flag[32] != 0) + draw_info->direction=(DirectionType) + argument_list[32].integer_reference; + DrawImage(image,draw_info); + draw_info=DestroyDrawInfo(draw_info); + break; + } + case 39: /* Equalize */ + { + if (attribute_flag[0] != 0) + channel=(ChannelType) argument_list[0].integer_reference; + EqualizeImageChannel(image,channel); + break; + } + case 40: /* Gamma */ + { + if (attribute_flag[1] != 0) + channel=(ChannelType) argument_list[1].integer_reference; + if (attribute_flag[2] == 0) + argument_list[2].real_reference=1.0; + if (attribute_flag[3] == 0) + argument_list[3].real_reference=1.0; + if (attribute_flag[4] == 0) + argument_list[4].real_reference=1.0; + if (attribute_flag[0] == 0) + { + (void) FormatLocaleString(message,MaxTextExtent, + "%.15g,%.15g,%.15g",(double) argument_list[2].real_reference, + (double) argument_list[3].real_reference, + (double) argument_list[4].real_reference); + argument_list[0].string_reference=message; + } + if (strchr(argument_list[0].string_reference,',') != (char *) NULL) + (void) GammaImage(image,argument_list[0].string_reference); + else + (void) GammaImageChannel(image,channel,StringToDouble( + argument_list[0].string_reference,(char **) NULL)); + break; + } + case 41: /* Map */ + { + QuantizeInfo + *quantize_info; + + if (attribute_flag[0] == 0) + { + ThrowPerlException(exception,OptionError,"MapImageRequired", + PackageName); + goto PerlException; + } + quantize_info=AcquireQuantizeInfo(info->image_info); + if (attribute_flag[1] != 0) + quantize_info->dither=(MagickBooleanType) + argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + quantize_info->dither_method=(DitherMethod) + argument_list[2].integer_reference; + (void) RemapImages(quantize_info,image, + argument_list[0].image_reference); + quantize_info=DestroyQuantizeInfo(quantize_info); + break; + } + case 42: /* MatteFloodfill */ + { + DrawInfo + *draw_info; + + MagickBooleanType + invert; + + MagickPixelPacket + target; + + draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL, + (DrawInfo *) NULL); + if (attribute_flag[0] != 0) + flags=ParsePageGeometry(image,argument_list[0].string_reference, + &geometry,exception); + if (attribute_flag[1] != 0) + geometry.x=argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + geometry.y=argument_list[2].integer_reference; + if (image->matte == MagickFalse) + (void) SetImageOpacity(image,OpaqueOpacity); + (void) GetOneVirtualMagickPixel(image,geometry.x,geometry.y,&target, + exception); + if (attribute_flag[4] != 0) + QueryMagickColor(argument_list[4].string_reference,&target, + exception); + if (attribute_flag[3] != 0) + target.opacity=StringToDoubleInterval( + argument_list[3].string_reference,(double) QuantumRange+1.0); + if (attribute_flag[5] != 0) + image->fuzz=StringToDoubleInterval( + argument_list[5].string_reference,(double) QuantumRange+1.0); + invert=MagickFalse; + if (attribute_flag[6] != 0) + invert=(MagickBooleanType) argument_list[6].integer_reference; + (void) FloodfillPaintImage(image,OpacityChannel,draw_info,&target, + geometry.x,geometry.y,invert); + draw_info=DestroyDrawInfo(draw_info); + break; + } + case 43: /* Modulate */ + { + char + modulate[MaxTextExtent]; + + geometry_info.rho=100.0; + geometry_info.sigma=100.0; + geometry_info.xi=100.0; + if (attribute_flag[0] != 0) + (void)ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if (attribute_flag[1] != 0) + geometry_info.xi=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + { + geometry_info.sigma=argument_list[3].real_reference; + SetImageArtifact(image,"modulate:colorspace","HWB"); + } + if (attribute_flag[4] != 0) + { + geometry_info.rho=argument_list[4].real_reference; + SetImageArtifact(image,"modulate:colorspace","HSB"); + } + if (attribute_flag[5] != 0) + { + geometry_info.sigma=argument_list[5].real_reference; + SetImageArtifact(image,"modulate:colorspace","HSL"); + } + if (attribute_flag[6] != 0) + { + geometry_info.rho=argument_list[6].real_reference; + SetImageArtifact(image,"modulate:colorspace","HWB"); + } + (void) FormatLocaleString(modulate,MaxTextExtent,"%.15g,%.15g,%.15g", + geometry_info.rho,geometry_info.sigma,geometry_info.xi); + (void) ModulateImage(image,modulate); + break; + } + case 44: /* Negate */ + { + if (attribute_flag[0] == 0) + argument_list[0].integer_reference=0; + if (attribute_flag[1] != 0) + channel=(ChannelType) argument_list[1].integer_reference; + (void) NegateImageChannel(image,channel, + argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse); + break; + } + case 45: /* Normalize */ + { + if (attribute_flag[0] != 0) + channel=(ChannelType) argument_list[0].integer_reference; + NormalizeImageChannel(image,channel); + break; + } + case 46: /* NumberColors */ + break; + case 47: /* Opaque */ + { + MagickBooleanType + invert; + + MagickPixelPacket + fill_color, + target; + + (void) QueryMagickColor("none",&target,exception); + (void) QueryMagickColor("none",&fill_color,exception); + if (attribute_flag[0] != 0) + (void) QueryMagickColor(argument_list[0].string_reference, + &target,exception); + if (attribute_flag[1] != 0) + (void) QueryMagickColor(argument_list[1].string_reference, + &fill_color,exception); + if (attribute_flag[2] != 0) + image->fuzz=StringToDoubleInterval( + argument_list[2].string_reference,(double) QuantumRange+1.0); + if (attribute_flag[3] != 0) + channel=(ChannelType) argument_list[3].integer_reference; + invert=MagickFalse; + if (attribute_flag[4] != 0) + invert=(MagickBooleanType) argument_list[4].integer_reference; + (void) OpaquePaintImageChannel(image,channel,&target,&fill_color, + invert); + break; + } + case 48: /* Quantize */ + { + QuantizeInfo + *quantize_info; + + quantize_info=AcquireQuantizeInfo(info->image_info); + if (attribute_flag[0] != 0) + quantize_info->number_colors=(size_t) + argument_list[0].integer_reference; + if (attribute_flag[1] != 0) + quantize_info->tree_depth=(size_t) + argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + quantize_info->colorspace=(ColorspaceType) + argument_list[2].integer_reference; + if (attribute_flag[3] != 0) + quantize_info->dither=argument_list[3].integer_reference != 0 ? + MagickTrue : MagickFalse; + if (attribute_flag[4] != 0) + quantize_info->measure_error= + argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse; + if (attribute_flag[6] != 0) + (void) QueryColorDatabase(argument_list[6].string_reference, + &image->transparent_color,exception); + if (attribute_flag[7] != 0) + quantize_info->dither_method=(DitherMethod) + argument_list[7].integer_reference; + if (attribute_flag[5] && argument_list[5].integer_reference) + (void) QuantizeImages(quantize_info,image); + else if ((image->storage_class == DirectClass) || + (image->colors > quantize_info->number_colors) || + (quantize_info->colorspace == GRAYColorspace)) + (void) QuantizeImage(quantize_info,image); + else + CompressImageColormap(image); + quantize_info=DestroyQuantizeInfo(quantize_info); + break; + } + case 49: /* Raise */ + { + if (attribute_flag[0] != 0) + flags=ParsePageGeometry(image,argument_list[0].string_reference, + &geometry,exception); + if (attribute_flag[1] != 0) + geometry.width=argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + geometry.height=argument_list[2].integer_reference; + if (attribute_flag[3] == 0) + argument_list[3].integer_reference=1; + (void) RaiseImage(image,&geometry,argument_list[3].integer_reference + != 0 ? MagickTrue : MagickFalse); + break; + } + case 50: /* Segment */ + { + ColorspaceType + colorspace; + + double + cluster_threshold, + smoothing_threshold; + + MagickBooleanType + verbose; + + cluster_threshold=1.0; + smoothing_threshold=1.5; + colorspace=sRGBColorspace; + verbose=MagickFalse; + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + cluster_threshold=geometry_info.rho; + if (flags & SigmaValue) + smoothing_threshold=geometry_info.sigma; + } + if (attribute_flag[1] != 0) + cluster_threshold=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + smoothing_threshold=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + colorspace=(ColorspaceType) argument_list[3].integer_reference; + if (attribute_flag[4] != 0) + verbose=argument_list[4].integer_reference != 0 ? + MagickTrue : MagickFalse; + (void) SegmentImage(image,colorspace,verbose,cluster_threshold, + smoothing_threshold); + break; + } + case 51: /* Signature */ + { + (void) SignatureImage(image); + break; + } + case 52: /* Solarize */ + { + geometry_info.rho=QuantumRange/2.0; + if (attribute_flag[0] != 0) + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if (attribute_flag[1] != 0) + geometry_info.rho=StringToDoubleInterval( + argument_list[1].string_reference,(double) QuantumRange+1.0); + if (attribute_flag[2] != 0) + channel=(ChannelType) argument_list[2].integer_reference; + (void) SolarizeImageChannel(image,channel,geometry_info.rho, + exception); + break; + } + case 53: /* Sync */ + { + (void) SyncImage(image); + break; + } + case 54: /* Texture */ + { + if (attribute_flag[0] == 0) + break; + TextureImage(image,argument_list[0].image_reference); + break; + } + case 55: /* Evalute */ + { + MagickEvaluateOperator + op; + + op=SetEvaluateOperator; + if (attribute_flag[0] == MagickFalse) + argument_list[0].real_reference=0.0; + if (attribute_flag[1] != MagickFalse) + op=(MagickEvaluateOperator) argument_list[1].integer_reference; + if (attribute_flag[2] != MagickFalse) + channel=(ChannelType) argument_list[2].integer_reference; + (void) EvaluateImageChannel(image,channel,op, + argument_list[0].real_reference,exception); + break; + } + case 56: /* Transparent */ + { + double + opacity; + + MagickBooleanType + invert; + + MagickPixelPacket + target; + + (void) QueryMagickColor("none",&target,exception); + if (attribute_flag[0] != 0) + (void) QueryMagickColor(argument_list[0].string_reference,&target, + exception); + opacity=TransparentOpacity; + if (attribute_flag[1] != 0) + opacity=StringToDoubleInterval(argument_list[1].string_reference, + (double) QuantumRange+1.0); + if (attribute_flag[2] != 0) + image->fuzz=StringToDoubleInterval( + argument_list[2].string_reference,(double) QuantumRange+1.0); + if (attribute_flag[3] == 0) + argument_list[3].integer_reference=0; + invert=MagickFalse; + if (attribute_flag[3] != 0) + invert=(MagickBooleanType) argument_list[3].integer_reference; + (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity), + invert); + break; + } + case 57: /* Threshold */ + { + double + threshold; + + if (attribute_flag[0] == 0) + argument_list[0].string_reference="50%"; + if (attribute_flag[1] != 0) + channel=(ChannelType) argument_list[1].integer_reference; + threshold=StringToDoubleInterval(argument_list[0].string_reference, + (double) QuantumRange+1.0); + (void) BilevelImageChannel(image,channel,threshold); + break; + } + case 58: /* Charcoal */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=1.0; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma, + exception); + break; + } + case 59: /* Trim */ + { + if (attribute_flag[0] != 0) + image->fuzz=StringToDoubleInterval( + argument_list[0].string_reference,(double) QuantumRange+1.0); + image=TrimImage(image,exception); + break; + } + case 60: /* Wave */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=1.0; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + image->interpolate=(InterpolatePixelMethod) + argument_list[3].integer_reference; + image=WaveImage(image,geometry_info.rho,geometry_info.sigma, + exception); + break; + } + case 61: /* Separate */ + { + if (attribute_flag[0] != 0) + channel=(ChannelType) argument_list[0].integer_reference; + (void) SeparateImageChannel(image,channel); + break; + } + case 63: /* Stereo */ + { + if (attribute_flag[0] == 0) + { + ThrowPerlException(exception,OptionError,"StereoImageRequired", + PackageName); + goto PerlException; + } + if (attribute_flag[1] != 0) + geometry.x=argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + geometry.y=argument_list[2].integer_reference; + image=StereoAnaglyphImage(image,argument_list[0].image_reference, + geometry.x,geometry.y,exception); + break; + } + case 64: /* Stegano */ + { + if (attribute_flag[0] == 0) + { + ThrowPerlException(exception,OptionError,"SteganoImageRequired", + PackageName); + goto PerlException; + } + if (attribute_flag[1] == 0) + argument_list[1].integer_reference=0; + image->offset=argument_list[1].integer_reference; + image=SteganoImage(image,argument_list[0].image_reference,exception); + break; + } + case 65: /* Deconstruct */ + { + image=DeconstructImages(image,exception); + break; + } + case 66: /* GaussianBlur */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=1.0; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + channel=(ChannelType) argument_list[3].integer_reference; + image=GaussianBlurImageChannel(image,channel,geometry_info.rho, + geometry_info.sigma,exception); + break; + } + case 67: /* Convolve */ + { + AV + *av; + + double + *kernel; + + size_t + order; + + if (attribute_flag[0] == 0) + break; + if (attribute_flag[1] != 0) + channel=(ChannelType) argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + image->bias=StringToDoubleInterval( + argument_list[2].string_reference,(double) QuantumRange+1.0); + av=(AV *) argument_list[0].array_reference; + order=(size_t) sqrt(av_len(av)+1); + kernel=(double *) AcquireQuantumMemory(order,order*sizeof(*kernel)); + if (kernel == (double *) NULL) + { + ThrowPerlException(exception,ResourceLimitFatalError, + "MemoryAllocationFailed",PackageName); + goto PerlException; + } + for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++) + kernel[j]=(double) SvNV(*(av_fetch(av,j,0))); + for ( ; j < (ssize_t) (order*order); j++) + kernel[j]=0.0; + image=ConvolveImageChannel(image,channel,order,kernel,exception); + kernel=(double *) RelinquishMagickMemory(kernel); + break; + } + case 68: /* Profile */ + { + const char + *name; + + Image + *profile_image; + + ImageInfo + *profile_info; + + StringInfo + *profile; + + name="*"; + if (attribute_flag[0] != 0) + name=argument_list[0].string_reference; + if (attribute_flag[2] != 0) + image->rendering_intent=(RenderingIntent) + argument_list[2].integer_reference; + if (attribute_flag[3] != 0) + image->black_point_compensation= + argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse; + if (attribute_flag[1] != 0) + { + if (argument_list[1].length == 0) + { + /* + Remove a profile from the image. + */ + (void) ProfileImage(image,name,(const unsigned char *) NULL,0, + MagickTrue); + break; + } + /* + Associate user supplied profile with the image. + */ + profile=AcquireStringInfo(argument_list[1].length); + SetStringInfoDatum(profile,(const unsigned char *) + argument_list[1].string_reference); + (void) ProfileImage(image,name,GetStringInfoDatum(profile), + (size_t) GetStringInfoLength(profile),MagickFalse); + profile=DestroyStringInfo(profile); + break; + } + /* + Associate a profile with the image. + */ + profile_info= + CloneImageInfo(info ? info->image_info : (ImageInfo *) NULL); + (void) CopyMagickString(profile_info->filename,name,MaxTextExtent); + profile_image=ReadImages(profile_info,&image->exception); + if (profile_image == (Image *) NULL) + break; + ResetImageProfileIterator(profile_image); + name=GetNextImageProfile(profile_image); + while (name != (const char *) NULL) + { + const StringInfo + *profile; + + profile=GetImageProfile(profile_image,name); + if (profile != (const StringInfo *) NULL) + (void) ProfileImage(image,name,GetStringInfoDatum(profile), + (size_t) GetStringInfoLength(profile),MagickFalse); + name=GetNextImageProfile(profile_image); + } + profile_image=DestroyImage(profile_image); + profile_info=DestroyImageInfo(profile_info); + break; + } + case 69: /* UnsharpMask */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=1.0; + if ((flags & XiValue) == 0) + geometry_info.xi=1.0; + if ((flags & PsiValue) == 0) + geometry_info.psi=0.5; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + geometry_info.xi=argument_list[3].real_reference; + if (attribute_flag[4] != 0) + geometry_info.psi=argument_list[4].real_reference; + if (attribute_flag[5] != 0) + channel=(ChannelType) argument_list[5].integer_reference; + image=UnsharpMaskImageChannel(image,channel,geometry_info.rho, + geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception); + break; + } + case 70: /* MotionBlur */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=1.0; + if ((flags & XiValue) == 0) + geometry_info.xi=1.0; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + geometry_info.xi=argument_list[3].real_reference; + if (attribute_flag[4] != 0) + channel=(ChannelType) argument_list[4].integer_reference; + image=MotionBlurImageChannel(image,channel,geometry_info.rho, + geometry_info.sigma,geometry_info.xi,exception); + break; + } + case 71: /* OrderedDither */ + { + if (attribute_flag[0] == 0) + argument_list[0].string_reference="o8x8"; + if (attribute_flag[1] != 0) + channel=(ChannelType) argument_list[1].integer_reference; + (void) OrderedPosterizeImageChannel(image,channel, + argument_list[0].string_reference,exception); + break; + } + case 72: /* Shave */ + { + if (attribute_flag[0] != 0) + flags=ParsePageGeometry(image,argument_list[0].string_reference, + &geometry,exception); + if (attribute_flag[1] != 0) + geometry.width=argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + geometry.height=argument_list[2].integer_reference; + image=ShaveImage(image,&geometry,exception); + break; + } + case 73: /* Level */ + { + double + black_point, + gamma, + white_point; + + black_point=0.0; + white_point=(MagickRealType) image->columns*image->rows; + gamma=1.0; + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + black_point=geometry_info.rho; + if ((flags & SigmaValue) != 0) + white_point=geometry_info.sigma; + if ((flags & XiValue) != 0) + gamma=geometry_info.xi; + if ((flags & PercentValue) != 0) + { + black_point*=(double) (QuantumRange/100.0); + white_point*=(double) (QuantumRange/100.0); + } + if ((flags & SigmaValue) == 0) + white_point=(double) QuantumRange-black_point; + } + if (attribute_flag[1] != 0) + black_point=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + white_point=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + gamma=argument_list[3].real_reference; + if (attribute_flag[4] != 0) + channel=(ChannelType) argument_list[4].integer_reference; + if (attribute_flag[5] != 0) + { + argument_list[0].real_reference=argument_list[5].real_reference; + attribute_flag[0]=attribute_flag[5]; + } + (void) LevelImageChannel(image,channel,black_point,white_point,gamma); + break; + } + case 74: /* Clip */ + { + if (attribute_flag[0] == 0) + argument_list[0].string_reference="#1"; + if (attribute_flag[1] == 0) + argument_list[1].integer_reference=MagickTrue; + (void) ClipImagePath(image,argument_list[0].string_reference, + argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse); + break; + } + case 75: /* AffineTransform */ + { + DrawInfo + *draw_info; + + draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL, + (DrawInfo *) NULL); + if (attribute_flag[0] != 0) + { + AV + *av; + + av=(AV *) argument_list[0].array_reference; + if ((av_len(av) != 3) && (av_len(av) != 5)) + { + ThrowPerlException(exception,OptionError, + "affine matrix must have 4 or 6 elements",PackageName); + goto PerlException; + } + draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0))); + draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0))); + draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0))); + draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0))); + if (fabs(draw_info->affine.sx*draw_info->affine.sy- + draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon) + { + ThrowPerlException(exception,OptionError, + "affine matrix is singular",PackageName); + goto PerlException; + } + if (av_len(av) == 5) + { + draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0))); + draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0))); + } + } + for (j=1; j < 6; j++) + { + if (attribute_flag[j] == 0) + continue; + value=argument_list[j].string_reference; + angle=argument_list[j].real_reference; + current=draw_info->affine; + GetAffineMatrix(&affine); + switch (j) + { + case 1: + { + /* + Translate. + */ + flags=ParseGeometry(value,&geometry_info); + affine.tx=geometry_info.xi; + affine.ty=geometry_info.psi; + if ((flags & PsiValue) == 0) + affine.ty=affine.tx; + break; + } + case 2: + { + /* + Scale. + */ + flags=ParseGeometry(value,&geometry_info); + affine.sx=geometry_info.rho; + affine.sy=geometry_info.sigma; + if ((flags & SigmaValue) == 0) + affine.sy=affine.sx; + break; + } + case 3: + { + /* + Rotate. + */ + if (angle == 0.0) + break; + affine.sx=cos(DegreesToRadians(fmod(angle,360.0))); + affine.rx=sin(DegreesToRadians(fmod(angle,360.0))); + affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0)))); + affine.sy=cos(DegreesToRadians(fmod(angle,360.0))); + break; + } + case 4: + { + /* + SkewX. + */ + affine.ry=tan(DegreesToRadians(fmod(angle,360.0))); + break; + } + case 5: + { + /* + SkewY. + */ + affine.rx=tan(DegreesToRadians(fmod(angle,360.0))); + break; + } + } + draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx; + draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx; + draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy; + draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy; + draw_info->affine.tx= + current.sx*affine.tx+current.ry*affine.ty+current.tx; + draw_info->affine.ty= + current.rx*affine.tx+current.sy*affine.ty+current.ty; + } + if (attribute_flag[6] != 0) + image->interpolate=(InterpolatePixelMethod) + argument_list[6].integer_reference; + if (attribute_flag[7] != 0) + QueryColorDatabase(argument_list[7].string_reference, + &image->background_color,exception); + image=AffineTransformImage(image,&draw_info->affine,exception); + draw_info=DestroyDrawInfo(draw_info); + break; + } + case 76: /* Difference */ + { + if (attribute_flag[0] == 0) + { + ThrowPerlException(exception,OptionError, + "ReferenceImageRequired",PackageName); + goto PerlException; + } + if (attribute_flag[1] != 0) + image->fuzz=StringToDoubleInterval( + argument_list[1].string_reference,(double) QuantumRange+1.0); + (void) IsImagesEqual(image,argument_list[0].image_reference); + break; + } + case 77: /* AdaptiveThreshold */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & PercentValue) != 0) + geometry_info.xi=QuantumRange*geometry_info.xi/100.0; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].integer_reference; + if (attribute_flag[3] != 0) + geometry_info.xi=argument_list[3].integer_reference;; + image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho, + (size_t) geometry_info.sigma,(ssize_t) geometry_info.xi, + exception); + break; + } + case 78: /* Resample */ + { + size_t + height, + width; + + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=geometry_info.rho; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + if (attribute_flag[3] == 0) + argument_list[3].integer_reference=(ssize_t) UndefinedFilter; + if (attribute_flag[4] == 0) + SetImageArtifact(image,"filter:support", + argument_list[4].string_reference); + if (attribute_flag[5] != 0) + argument_list[5].real_reference=1.0; + width=(size_t) (geometry_info.rho*image->columns/ + (image->x_resolution == 0.0 ? 72.0 : image->x_resolution)+0.5); + height=(size_t) (geometry_info.sigma*image->rows/ + (image->y_resolution == 0.0 ? 72.0 : image->y_resolution)+0.5); + image=ResizeImage(image,width,height,(FilterTypes) + argument_list[3].integer_reference,argument_list[5].real_reference, + exception); + if (image != (Image *) NULL) + { + image->x_resolution=geometry_info.rho; + image->y_resolution=geometry_info.sigma; + } + break; + } + case 79: /* Describe */ + { + if (attribute_flag[0] == 0) + argument_list[0].file_reference=(FILE *) NULL; + if (attribute_flag[1] != 0) + (void) SetImageArtifact(image,"identify:features", + argument_list[1].string_reference); + (void) IdentifyImage(image,argument_list[0].file_reference, + MagickTrue); + break; + } + case 80: /* BlackThreshold */ + { + if (attribute_flag[0] == 0) + argument_list[0].string_reference="50%"; + if (attribute_flag[2] != 0) + channel=(ChannelType) argument_list[2].integer_reference; + BlackThresholdImageChannel(image,channel, + argument_list[0].string_reference,exception); + break; + } + case 81: /* WhiteThreshold */ + { + if (attribute_flag[0] == 0) + argument_list[0].string_reference="50%"; + if (attribute_flag[2] != 0) + channel=(ChannelType) argument_list[2].integer_reference; + WhiteThresholdImageChannel(image,channel, + argument_list[0].string_reference,exception); + break; + } + case 82: /* RotationalBlur */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=1.0; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + channel=(ChannelType) argument_list[2].integer_reference; + image=RotationalBlurImageChannel(image,channel,geometry_info.rho, + exception); + break; + } + case 83: /* Thumbnail */ + { + if (attribute_flag[0] != 0) + flags=ParseRegionGeometry(image,argument_list[0].string_reference, + &geometry,exception); + if (attribute_flag[1] != 0) + geometry.width=argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + geometry.height=argument_list[2].integer_reference; + image=ThumbnailImage(image,geometry.width,geometry.height,exception); + break; + } + case 84: /* Strip */ + { + (void) StripImage(image); + break; + } + case 85: /* Tint */ + { + PixelPacket + target; + + (void) GetOneVirtualPixel(image,0,0,&target,exception); + if (attribute_flag[0] != 0) + (void) QueryColorDatabase(argument_list[0].string_reference,&target, + exception); + if (attribute_flag[1] == 0) + argument_list[1].string_reference="100"; + image=TintImage(image,argument_list[1].string_reference,target, + exception); + break; + } + case 86: /* Channel */ + { + if (attribute_flag[0] != 0) + channel=(ChannelType) argument_list[0].integer_reference; + (void) SeparateImageChannel(image,channel); + break; + } + case 87: /* Splice */ + { + if (attribute_flag[7] != 0) + image->gravity=(GravityType) argument_list[7].integer_reference; + if (attribute_flag[0] != 0) + flags=ParseGravityGeometry(image,argument_list[0].string_reference, + &geometry,exception); + if (attribute_flag[1] != 0) + geometry.width=argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + geometry.height=argument_list[2].integer_reference; + if (attribute_flag[3] != 0) + geometry.x=argument_list[3].integer_reference; + if (attribute_flag[4] != 0) + geometry.y=argument_list[4].integer_reference; + if (attribute_flag[5] != 0) + image->fuzz=StringToDoubleInterval( + argument_list[5].string_reference,(double) QuantumRange+1.0); + if (attribute_flag[6] != 0) + (void) QueryColorDatabase(argument_list[6].string_reference, + &image->background_color,exception); + image=SpliceImage(image,&geometry,exception); + break; + } + case 88: /* Posterize */ + { + if (attribute_flag[0] == 0) + argument_list[0].integer_reference=3; + if (attribute_flag[1] == 0) + argument_list[1].integer_reference=0; + (void) PosterizeImage(image,argument_list[0].integer_reference, + argument_list[1].integer_reference ? MagickTrue : MagickFalse); + break; + } + case 89: /* Shadow */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=1.0; + if ((flags & XiValue) == 0) + geometry_info.xi=4.0; + if ((flags & PsiValue) == 0) + geometry_info.psi=4.0; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + geometry_info.xi=argument_list[3].integer_reference; + if (attribute_flag[4] != 0) + geometry_info.psi=argument_list[4].integer_reference; + image=ShadowImage(image,geometry_info.rho,geometry_info.sigma, + (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t) ceil(geometry_info.psi- + 0.5),exception); + break; + } + case 90: /* Identify */ + { + if (attribute_flag[0] == 0) + argument_list[0].file_reference=(FILE *) NULL; + if (attribute_flag[1] != 0) + (void) SetImageArtifact(image,"identify:features", + argument_list[1].string_reference); + if ((attribute_flag[2] != 0) && + (argument_list[2].integer_reference != 0)) + (void) SetImageArtifact(image,"identify:unique","true"); + (void) IdentifyImage(image,argument_list[0].file_reference, + MagickTrue); + break; + } + case 91: /* SepiaTone */ + { + if (attribute_flag[0] == 0) + argument_list[0].real_reference=80.0*QuantumRange/100.0; + image=SepiaToneImage(image,argument_list[0].real_reference, + exception); + break; + } + case 92: /* SigmoidalContrast */ + { + MagickBooleanType + sharpen; + + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=QuantumRange/2.0; + if ((flags & PercentValue) != 0) + geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + channel=(ChannelType) argument_list[3].integer_reference; + sharpen=MagickTrue; + if (attribute_flag[4] != 0) + sharpen=argument_list[4].integer_reference != 0 ? MagickTrue : + MagickFalse; + (void) SigmoidalContrastImageChannel(image,channel,sharpen, + geometry_info.rho,geometry_info.sigma); + break; + } + case 93: /* Extent */ + { + if (attribute_flag[7] != 0) + image->gravity=(GravityType) argument_list[7].integer_reference; + if (attribute_flag[0] != 0) + { + int + flags; + + flags=ParseGravityGeometry(image, + argument_list[0].string_reference,&geometry,exception); + (void) flags; + if (geometry.width == 0) + geometry.width=image->columns; + if (geometry.height == 0) + geometry.height=image->rows; + } + if (attribute_flag[1] != 0) + geometry.width=argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + geometry.height=argument_list[2].integer_reference; + if (attribute_flag[3] != 0) + geometry.x=argument_list[3].integer_reference; + if (attribute_flag[4] != 0) + geometry.y=argument_list[4].integer_reference; + if (attribute_flag[5] != 0) + image->fuzz=StringToDoubleInterval( + argument_list[5].string_reference,(double) QuantumRange+1.0); + if (attribute_flag[6] != 0) + (void) QueryColorDatabase(argument_list[6].string_reference, + &image->background_color,exception); + image=ExtentImage(image,&geometry,exception); + break; + } + case 94: /* Vignette */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=1.0; + if ((flags & XiValue) == 0) + geometry_info.xi=0.1*image->columns; + if ((flags & PsiValue) == 0) + geometry_info.psi=0.1*image->rows; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + geometry_info.xi=argument_list[3].integer_reference; + if (attribute_flag[4] != 0) + geometry_info.psi=argument_list[4].integer_reference; + if (attribute_flag[5] != 0) + (void) QueryColorDatabase(argument_list[5].string_reference, + &image->background_color,exception); + image=VignetteImage(image,geometry_info.rho,geometry_info.sigma, + (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t) ceil(geometry_info.psi- + 0.5),exception); + break; + } + case 95: /* ContrastStretch */ + { + double + black_point, + white_point; + + black_point=0.0; + white_point=(MagickRealType) image->columns*image->rows; + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + black_point=geometry_info.rho; + white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma : + black_point; + if ((flags & PercentValue) != 0) + { + black_point*=(double) image->columns*image->rows/100.0; + white_point*=(double) image->columns*image->rows/100.0; + } + white_point=(MagickRealType) image->columns*image->rows- + white_point; + } + if (attribute_flag[1] != 0) + black_point=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + white_point=argument_list[2].real_reference; + if (attribute_flag[4] != 0) + channel=(ChannelType) argument_list[4].integer_reference; + (void) ContrastStretchImageChannel(image,channel,black_point, + white_point); + break; + } + case 96: /* Sans0 */ + { + break; + } + case 97: /* Sans1 */ + { + break; + } + case 98: /* AdaptiveSharpen */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=1.0; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + channel=(ChannelType) argument_list[3].integer_reference; + image=AdaptiveSharpenImageChannel(image,channel,geometry_info.rho, + geometry_info.sigma,exception); + break; + } + case 99: /* Transpose */ + { + image=TransposeImage(image,exception); + break; + } + case 100: /* Tranverse */ + { + image=TransverseImage(image,exception); + break; + } + case 101: /* AutoOrient */ + { + image=AutoOrientImage(image,image->orientation,exception); + break; + } + case 102: /* AdaptiveBlur */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=1.0; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + channel=(ChannelType) argument_list[3].integer_reference; + image=AdaptiveBlurImageChannel(image,channel,geometry_info.rho, + geometry_info.sigma,exception); + break; + } + case 103: /* Sketch */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=1.0; + if ((flags & XiValue) == 0) + geometry_info.xi=1.0; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + geometry_info.xi=argument_list[3].real_reference; + image=SketchImage(image,geometry_info.rho,geometry_info.sigma, + geometry_info.xi,exception); + break; + } + case 104: /* UniqueColors */ + { + image=UniqueImageColors(image,exception); + break; + } + case 105: /* AdaptiveResize */ + { + if (attribute_flag[0] != 0) + flags=ParseRegionGeometry(image,argument_list[0].string_reference, + &geometry,exception); + if (attribute_flag[1] != 0) + geometry.width=argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + geometry.height=argument_list[2].integer_reference; + if (attribute_flag[3] != 0) + image->filter=(FilterTypes) argument_list[4].integer_reference; + if (attribute_flag[4] != 0) + SetImageArtifact(image,"filter:support", + argument_list[4].string_reference); + if (attribute_flag[5] != 0) + image->blur=argument_list[5].real_reference; + image=AdaptiveResizeImage(image,geometry.width,geometry.height, + exception); + break; + } + case 106: /* ClipMask */ + { + if (attribute_flag[0] == 0) + { + ThrowPerlException(exception,OptionError,"MaskImageRequired", + PackageName); + goto PerlException; + } + image->clip_mask=CloneImage(argument_list[0].image_reference,0,0, + MagickTrue,exception); + (void) NegateImage(image->clip_mask,MagickFalse); + break; + } + case 107: /* LinearStretch */ + { + double + black_point, + white_point; + + black_point=0.0; + white_point=(MagickRealType) image->columns*image->rows; + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) != 0) + white_point=geometry_info.sigma; + if ((flags & PercentValue) != 0) + { + black_point*=(double) image->columns*image->rows/100.0; + white_point*=(double) image->columns*image->rows/100.0; + } + if ((flags & SigmaValue) == 0) + white_point=(double) image->columns*image->rows-black_point; + } + if (attribute_flag[1] != 0) + black_point=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + white_point=argument_list[2].real_reference; + (void) LinearStretchImage(image,black_point,white_point); + break; + } + case 109: /* Mask */ + { + if (attribute_flag[0] == 0) + { + ThrowPerlException(exception,OptionError,"MaskImageRequired", + PackageName); + goto PerlException; + } + image->mask=CloneImage(argument_list[0].image_reference,0,0, + MagickTrue,exception); + (void) NegateImage(image->mask,MagickFalse); + break; + } + case 110: /* Polaroid */ + { + DrawInfo + *draw_info; + + double + angle; + + draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL, + (DrawInfo *) NULL); + if (attribute_flag[0] != 0) + (void) SetImageProperty(image,"caption",InterpretImageProperties( + info ? info->image_info : (ImageInfo *) NULL,image, + argument_list[0].string_reference)); + angle=0.0; + if (attribute_flag[1] != 0) + angle=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + (void) CloneString(&draw_info->font, + argument_list[2].string_reference); + if (attribute_flag[3] != 0) + (void) QueryColorDatabase(argument_list[3].string_reference, + &draw_info->stroke,exception); + if (attribute_flag[4] != 0) + (void) QueryColorDatabase(argument_list[4].string_reference, + &draw_info->fill,exception); + if (attribute_flag[5] != 0) + draw_info->stroke_width=argument_list[5].real_reference; + if (attribute_flag[6] != 0) + draw_info->pointsize=argument_list[6].real_reference; + if (attribute_flag[7] != 0) + draw_info->gravity=(GravityType) argument_list[7].integer_reference; + if (attribute_flag[8] != 0) + (void) QueryColorDatabase(argument_list[8].string_reference, + &image->background_color,exception); + image=PolaroidImage(image,draw_info,angle,exception); + draw_info=DestroyDrawInfo(draw_info); + break; + } + case 111: /* FloodfillPaint */ + { + DrawInfo + *draw_info; + + MagickBooleanType + invert; + + MagickPixelPacket + target; + + draw_info=CloneDrawInfo(info ? info->image_info : + (ImageInfo *) NULL,(DrawInfo *) NULL); + if (attribute_flag[0] != 0) + flags=ParsePageGeometry(image,argument_list[0].string_reference, + &geometry,exception); + if (attribute_flag[1] != 0) + geometry.x=argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + geometry.y=argument_list[2].integer_reference; + if (attribute_flag[3] != 0) + (void) QueryColorDatabase(argument_list[3].string_reference, + &draw_info->fill,exception); + (void) GetOneVirtualMagickPixel(image,geometry.x,geometry.y,&target, + exception); + if (attribute_flag[4] != 0) + QueryMagickColor(argument_list[4].string_reference,&target, + exception); + if (attribute_flag[5] != 0) + image->fuzz=StringToDoubleInterval( + argument_list[5].string_reference,(double) QuantumRange+1.0); + if (attribute_flag[6] != 0) + channel=(ChannelType) argument_list[6].integer_reference; + invert=MagickFalse; + if (attribute_flag[7] != 0) + invert=(MagickBooleanType) argument_list[7].integer_reference; + (void) FloodfillPaintImage(image,channel,draw_info,&target,geometry.x, + geometry.y,invert); + draw_info=DestroyDrawInfo(draw_info); + break; + } + case 112: /* Distort */ + { + AV + *av; + + double + *coordinates; + + DistortImageMethod + method; + + size_t + number_coordinates; + + VirtualPixelMethod + virtual_pixel; + + if (attribute_flag[0] == 0) + break; + method=UndefinedDistortion; + if (attribute_flag[1] != 0) + method=(DistortImageMethod) argument_list[1].integer_reference; + av=(AV *) argument_list[0].array_reference; + number_coordinates=(size_t) av_len(av)+1; + coordinates=(double *) AcquireQuantumMemory(number_coordinates, + sizeof(*coordinates)); + if (coordinates == (double *) NULL) + { + ThrowPerlException(exception,ResourceLimitFatalError, + "MemoryAllocationFailed",PackageName); + goto PerlException; + } + for (j=0; j < (ssize_t) number_coordinates; j++) + coordinates[j]=(double) SvNV(*(av_fetch(av,j,0))); + virtual_pixel=UndefinedVirtualPixelMethod; + if (attribute_flag[2] != 0) + virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod) + argument_list[2].integer_reference); + image=DistortImage(image,method,number_coordinates,coordinates, + argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse, + exception); + if ((attribute_flag[2] != 0) && (image != (Image *) NULL)) + virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel); + coordinates=(double *) RelinquishMagickMemory(coordinates); + break; + } + case 113: /* Clut */ + { + if (attribute_flag[0] == 0) + { + ThrowPerlException(exception,OptionError,"ClutImageRequired", + PackageName); + goto PerlException; + } + if (attribute_flag[1] != 0) + channel=(ChannelType) argument_list[1].integer_reference; + (void) ClutImageChannel(image,channel, + argument_list[0].image_reference); + break; + } + case 114: /* LiquidRescale */ + { + if (attribute_flag[0] != 0) + flags=ParseRegionGeometry(image,argument_list[0].string_reference, + &geometry,exception); + if (attribute_flag[1] != 0) + geometry.width=argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + geometry.height=argument_list[2].integer_reference; + if (attribute_flag[3] == 0) + argument_list[3].real_reference=1.0; + if (attribute_flag[4] == 0) + argument_list[4].real_reference=0.0; + image=LiquidRescaleImage(image,geometry.width,geometry.height, + argument_list[3].real_reference,argument_list[4].real_reference, + exception); + break; + } + case 115: /* EncipherImage */ + { + (void) EncipherImage(image,argument_list[0].string_reference, + exception); + break; + } + case 116: /* DecipherImage */ + { + (void) DecipherImage(image,argument_list[0].string_reference, + exception); + break; + } + case 117: /* Deskew */ + { + geometry_info.rho=QuantumRange/2.0; + if (attribute_flag[0] != 0) + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if (attribute_flag[1] != 0) + geometry_info.rho=StringToDoubleInterval( + argument_list[1].string_reference,(double) QuantumRange+1.0); + image=DeskewImage(image,geometry_info.rho,exception); + break; + } + case 118: /* Remap */ + { + QuantizeInfo + *quantize_info; + + if (attribute_flag[0] == 0) + { + ThrowPerlException(exception,OptionError,"RemapImageRequired", + PackageName); + goto PerlException; + } + quantize_info=AcquireQuantizeInfo(info->image_info); + if (attribute_flag[1] != 0) + quantize_info->dither=(MagickBooleanType) + argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + quantize_info->dither_method=(DitherMethod) + argument_list[2].integer_reference; + (void) RemapImages(quantize_info,image, + argument_list[0].image_reference); + quantize_info=DestroyQuantizeInfo(quantize_info); + break; + } + case 119: /* SparseColor */ + { + AV + *av; + + double + *coordinates; + + SparseColorMethod + method; + + size_t + number_coordinates; + + VirtualPixelMethod + virtual_pixel; + + if (attribute_flag[0] == 0) + break; + method=UndefinedColorInterpolate; + if (attribute_flag[1] != 0) + method=(SparseColorMethod) argument_list[1].integer_reference; + av=(AV *) argument_list[0].array_reference; + number_coordinates=(size_t) av_len(av)+1; + coordinates=(double *) AcquireQuantumMemory(number_coordinates, + sizeof(*coordinates)); + if (coordinates == (double *) NULL) + { + ThrowPerlException(exception,ResourceLimitFatalError, + "MemoryAllocationFailed",PackageName); + goto PerlException; + } + for (j=0; j < (ssize_t) number_coordinates; j++) + coordinates[j]=(double) SvNV(*(av_fetch(av,j,0))); + virtual_pixel=UndefinedVirtualPixelMethod; + if (attribute_flag[2] != 0) + virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod) + argument_list[2].integer_reference); + if (attribute_flag[3] != 0) + channel=(ChannelType) argument_list[3].integer_reference; + image=SparseColorImage(image,channel,method,number_coordinates, + coordinates,exception); + if ((attribute_flag[2] != 0) && (image != (Image *) NULL)) + virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel); + coordinates=(double *) RelinquishMagickMemory(coordinates); + break; + } + case 120: /* Function */ + { + AV + *av; + + double + *parameters; + + MagickFunction + function; + + size_t + number_parameters; + + VirtualPixelMethod + virtual_pixel; + + if (attribute_flag[0] == 0) + break; + function=UndefinedFunction; + if (attribute_flag[1] != 0) + function=(MagickFunction) argument_list[1].integer_reference; + av=(AV *) argument_list[0].array_reference; + number_parameters=(size_t) av_len(av)+1; + parameters=(double *) AcquireQuantumMemory(number_parameters, + sizeof(*parameters)); + if (parameters == (double *) NULL) + { + ThrowPerlException(exception,ResourceLimitFatalError, + "MemoryAllocationFailed",PackageName); + goto PerlException; + } + for (j=0; j < (ssize_t) number_parameters; j++) + parameters[j]=(double) SvNV(*(av_fetch(av,j,0))); + virtual_pixel=UndefinedVirtualPixelMethod; + if (attribute_flag[2] != 0) + virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod) + argument_list[2].integer_reference); + (void) FunctionImage(image,function,number_parameters,parameters, + exception); + if ((attribute_flag[2] != 0) && (image != (Image *) NULL)) + virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel); + parameters=(double *) RelinquishMagickMemory(parameters); + break; + } + case 121: /* SelectiveBlur */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=1.0; + if ((flags & PercentValue) != 0) + geometry_info.xi=QuantumRange*geometry_info.xi/100.0; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + geometry_info.xi=argument_list[3].integer_reference;; + if (attribute_flag[4] != 0) + channel=(ChannelType) argument_list[4].integer_reference; + image=SelectiveBlurImageChannel(image,channel,geometry_info.rho, + geometry_info.sigma,geometry_info.xi,exception); + break; + } + case 122: /* HaldClut */ + { + if (attribute_flag[0] == 0) + { + ThrowPerlException(exception,OptionError,"ClutImageRequired", + PackageName); + goto PerlException; + } + if (attribute_flag[1] != 0) + channel=(ChannelType) argument_list[1].integer_reference; + (void) HaldClutImageChannel(image,channel, + argument_list[0].image_reference); + break; + } + case 123: /* BlueShift */ + { + if (attribute_flag[0] != 0) + (void) ParseGeometry(argument_list[0].string_reference, + &geometry_info); + image=BlueShiftImage(image,geometry_info.rho,exception); + break; + } + case 124: /* ForwardFourierTransformImage */ + { + image=ForwardFourierTransformImage(image, + argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse, + exception); + break; + } + case 125: /* InverseFourierTransformImage */ + { + image=InverseFourierTransformImage(image,image->next, + argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse, + exception); + break; + } + case 126: /* ColorDecisionList */ + { + if (attribute_flag[0] == 0) + argument_list[0].string_reference=(char *) NULL; + (void) ColorDecisionListImage(image, + argument_list[0].string_reference); + break; + } + case 127: /* AutoGamma */ + { + if (attribute_flag[0] != 0) + channel=(ChannelType) argument_list[0].integer_reference; + (void) AutoGammaImageChannel(image,channel); + break; + } + case 128: /* AutoLevel */ + { + if (attribute_flag[0] != 0) + channel=(ChannelType) argument_list[0].integer_reference; + (void) AutoLevelImageChannel(image,channel); + break; + } + case 129: /* LevelColors */ + { + MagickPixelPacket + black_point, + white_point; + + (void) QueryMagickColor("#000000",&black_point,exception); + (void) QueryMagickColor("#ffffff",&white_point,exception); + if (attribute_flag[1] != 0) + (void) QueryMagickColor(argument_list[1].string_reference, + &black_point,exception); + if (attribute_flag[2] != 0) + (void) QueryMagickColor(argument_list[2].string_reference, + &white_point,exception); + if (attribute_flag[3] != 0) + channel=(ChannelType) argument_list[3].integer_reference; + (void) LevelColorsImageChannel(image,channel,&black_point, + &white_point,argument_list[0].integer_reference != 0 ? MagickTrue : + MagickFalse); + break; + } + case 130: /* Clamp */ + { + if (attribute_flag[0] != 0) + channel=(ChannelType) argument_list[0].integer_reference; + (void) ClampImageChannel(image,channel); + break; + } + case 131: /* Filter */ + { + KernelInfo + *kernel; + + if (attribute_flag[0] == 0) + break; + kernel=AcquireKernelInfo(argument_list[0].string_reference); + if (kernel == (KernelInfo *) NULL) + break; + if (attribute_flag[1] != 0) + channel=(ChannelType) argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + image->bias=StringToDoubleInterval( + argument_list[2].string_reference,(double) QuantumRange+1.0); + image=FilterImageChannel(image,channel,kernel,exception); + kernel=DestroyKernelInfo(kernel); + break; + } + case 132: /* BrightnessContrast */ + { + double + brightness, + contrast; + + brightness=0.0; + contrast=0.0; + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + brightness=geometry_info.rho; + if ((flags & SigmaValue) == 0) + contrast=geometry_info.sigma; + } + if (attribute_flag[1] != 0) + brightness=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + contrast=argument_list[2].real_reference; + if (attribute_flag[4] != 0) + channel=(ChannelType) argument_list[4].integer_reference; + (void) BrightnessContrastImageChannel(image,channel,brightness, + contrast); + break; + } + case 133: /* Morphology */ + { + KernelInfo + *kernel; + + MorphologyMethod + method; + + ssize_t + iterations; + + if (attribute_flag[0] == 0) + break; + kernel=AcquireKernelInfo(argument_list[0].string_reference); + if (kernel == (KernelInfo *) NULL) + break; + if (attribute_flag[1] != 0) + channel=(ChannelType) argument_list[1].integer_reference; + method=UndefinedMorphology; + if (attribute_flag[2] != 0) + method=argument_list[2].integer_reference; + iterations=1; + if (attribute_flag[3] != 0) + iterations=argument_list[3].integer_reference; + image=MorphologyImageChannel(image,channel,method,iterations,kernel, + exception); + kernel=DestroyKernelInfo(kernel); + break; + } + case 108: /* Recolor */ + case 134: /* ColorMatrix */ + { + AV + *av; + + double + *color_matrix; + + KernelInfo + *kernel_info; + + size_t + order; + + if (attribute_flag[0] == 0) + break; + av=(AV *) argument_list[0].array_reference; + order=(size_t) sqrt(av_len(av)+1); + color_matrix=(double *) AcquireQuantumMemory(order,order* + sizeof(*color_matrix)); + if (color_matrix == (double *) NULL) + { + ThrowPerlException(exception,ResourceLimitFatalError, + "MemoryAllocationFailed",PackageName); + goto PerlException; + } + for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++) + color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0))); + for ( ; j < (ssize_t) (order*order); j++) + color_matrix[j]=0.0; + kernel_info=AcquireKernelInfo("1"); + if (kernel_info == (KernelInfo *) NULL) + break; + kernel_info->width=order; + kernel_info->height=order; + kernel_info->values=color_matrix; + image=ColorMatrixImage(image,kernel_info,exception); + kernel_info->values=(double *) NULL; + kernel_info=DestroyKernelInfo(kernel_info); + color_matrix=(double *) RelinquishMagickMemory(color_matrix); + break; + } + case 135: /* Color */ + { + MagickPixelPacket + color; + + (void) QueryMagickColor("none",&color,exception); + if (attribute_flag[0] != 0) + (void) QueryMagickColor(argument_list[0].string_reference, + &color,exception); + (void) SetImageColor(image,&color); + break; + } + case 136: /* Mode */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=1.0; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + channel=(ChannelType) argument_list[3].integer_reference; + image=StatisticImageChannel(image,channel,ModeStatistic, + (size_t) geometry_info.rho,(size_t) geometry_info.sigma,exception); + break; + } + case 137: /* Statistic */ + { + StatisticType + statistic; + + statistic=UndefinedStatistic; + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=1.0; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + channel=(ChannelType) argument_list[3].integer_reference; + if (attribute_flag[4] != 0) + statistic=(StatisticType) argument_list[4].integer_reference; + image=StatisticImageChannel(image,channel,statistic, + (size_t) geometry_info.rho,(size_t) geometry_info.sigma,exception); + break; + } + case 138: /* Perceptible */ + { + double + epsilon; + + epsilon=MagickEpsilon; + if (attribute_flag[0] != 0) + epsilon=argument_list[0].real_reference; + if (attribute_flag[1] != 0) + channel=(ChannelType) argument_list[1].integer_reference; + (void) PerceptibleImageChannel(image,channel,epsilon); + break; + } + case 139: /* Poly */ + { + AV + *av; + + double + *terms; + + size_t + number_terms; + + if (attribute_flag[0] == 0) + break; + if (attribute_flag[1] != 0) + channel=(ChannelType) argument_list[1].integer_reference; + av=(AV *) argument_list[0].array_reference; + number_terms=(size_t) av_len(av); + terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms)); + if (terms == (double *) NULL) + { + ThrowPerlException(exception,ResourceLimitFatalError, + "MemoryAllocationFailed",PackageName); + goto PerlException; + } + for (j=0; j < av_len(av); j++) + terms[j]=(double) SvNV(*(av_fetch(av,j,0))); + image=PolynomialImageChannel(image,channel,number_terms >> 1,terms, + exception); + terms=(double *) RelinquishMagickMemory(terms); + break; + } + case 140: /* Grayscale */ + { + PixelIntensityMethod + method; + + method=UndefinedPixelIntensityMethod; + if (attribute_flag[0] != 0) + method=(PixelIntensityMethod) argument_list[0].integer_reference; + (void) GrayscaleImage(image,method); + break; + } + case 141: /* CannyEdge */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=1.0; + if ((flags & XiValue) == 0) + geometry_info.xi=0.10; + if ((flags & PsiValue) == 0) + geometry_info.psi=0.30; + if ((flags & PercentValue) != 0) + { + geometry_info.xi/=100.0; + geometry_info.psi/=100.0; + } + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + geometry_info.xi=argument_list[3].real_reference; + if (attribute_flag[4] != 0) + geometry_info.psi=argument_list[4].real_reference; + image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma, + geometry_info.xi,geometry_info.psi,exception); + break; + } + case 142: /* HoughLine */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=geometry_info.rho; + if ((flags & XiValue) == 0) + geometry_info.xi=40; + } + if (attribute_flag[1] != 0) + geometry_info.rho=(double) argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=(double) argument_list[2].integer_reference; + if (attribute_flag[3] != 0) + geometry_info.xi=(double) argument_list[3].integer_reference; + image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t) + geometry_info.sigma,(size_t) geometry_info.xi,exception); + break; + } + case 143: /* MeanShift */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=geometry_info.rho; + if ((flags & XiValue) == 0) + geometry_info.xi=0.10*QuantumRange; + if ((flags & PercentValue) != 0) + geometry_info.xi=QuantumRange*geometry_info.xi/100.0; + } + if (attribute_flag[1] != 0) + geometry_info.rho=(double) argument_list[1].integer_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=(double) argument_list[2].integer_reference; + if (attribute_flag[3] != 0) + geometry_info.xi=(double) argument_list[3].real_reference; + image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t) + geometry_info.sigma,geometry_info.xi,exception); + break; + } + case 144: /* Kuwahara */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & SigmaValue) == 0) + geometry_info.sigma=geometry_info.rho-0.5; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + if (attribute_flag[3] != 0) + channel=(ChannelType) argument_list[3].integer_reference; + image=KuwaharaImageChannel(image,channel,geometry_info.rho, + geometry_info.sigma,exception); + break; + } + case 145: /* ConnectedComponent */ + { + size_t + connectivity; + + connectivity=4; + if (attribute_flag[0] != 0) + connectivity=argument_list[0].integer_reference; + image=ConnectedComponentsImage(image,connectivity,exception); + break; + } + case 146: /* Copy */ + { + Image + *source_image; + + OffsetInfo + offset; + + RectangleInfo + offset_geometry; + + source_image=image; + if (attribute_flag[0] != 0) + source_image=argument_list[0].image_reference; + SetGeometry(source_image,&geometry); + if (attribute_flag[1] != 0) + flags=ParseGravityGeometry(source_image, + argument_list[1].string_reference,&geometry,exception); + if (attribute_flag[2] != 0) + geometry.width=argument_list[2].integer_reference; + if (attribute_flag[3] != 0) + geometry.height=argument_list[3].integer_reference; + if (attribute_flag[4] != 0) + geometry.x=argument_list[4].integer_reference; + if (attribute_flag[5] != 0) + geometry.y=argument_list[5].integer_reference; + if (attribute_flag[6] != 0) + image->gravity=(GravityType) argument_list[6].integer_reference; + SetGeometry(image,&offset_geometry); + if (attribute_flag[7] != 0) + flags=ParseGravityGeometry(image,argument_list[7].string_reference, + &offset_geometry,exception); + offset.x=offset_geometry.x; + offset.y=offset_geometry.y; + if (attribute_flag[8] != 0) + offset.x=argument_list[8].integer_reference; + if (attribute_flag[9] != 0) + offset.y=argument_list[9].integer_reference; + (void) CopyImagePixels(image,source_image,&geometry,&offset, + exception); + break; + } + case 147: /* WaveletDenoise */ + { + if (attribute_flag[0] != 0) + { + flags=ParseGeometry(argument_list[0].string_reference, + &geometry_info); + if ((flags & PercentValue) != 0) + { + geometry_info.rho=QuantumRange*geometry_info.rho/100.0; + geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0; + } + if ((flags & SigmaValue) == 0) + geometry_info.sigma=0.0; + } + if (attribute_flag[1] != 0) + geometry_info.rho=argument_list[1].real_reference; + if (attribute_flag[2] != 0) + geometry_info.sigma=argument_list[2].real_reference; + image=WaveletDenoiseImage(image,geometry_info.rho,geometry_info.sigma, + exception); + break; + } + } + if (next != (Image *) NULL) + (void) CatchImageException(next); + if (region_image != (Image *) NULL) + { + /* + Composite region. + */ + status=CompositeImage(region_image,CopyCompositeOp,image, + region_info.x,region_info.y); + (void) status; + (void) CatchImageException(region_image); + image=DestroyImage(image); + image=region_image; + } + if (image != (Image *) NULL) + { + number_images++; + if (next && (next != image)) + { + image->next=next->next; + if (image->next != (Image *) NULL) + image->next->previous=image; + DeleteImageFromRegistry(*pv,next); + } + sv_setiv(*pv,PTR2IV(image)); + next=image; + } + if (*pv) + pv++; + } + + PerlException: + if (reference_vector) + reference_vector=(SV **) RelinquishMagickMemory(reference_vector); + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) number_images); + SvPOK_on(perl_exception); + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# M o n t a g e # +# # +# # +# # +############################################################################### +# +# +void +Montage(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + MontageImage = 1 + montage = 2 + montageimage = 3 + PPCODE: + { + AV + *av; + + char + *attribute; + + ExceptionInfo + *exception; + + HV + *hv; + + Image + *image, + *next; + + MagickPixelPacket + transparent_color; + + MontageInfo + *montage_info; + + register ssize_t + i; + + ssize_t + sp; + + struct PackageInfo + *info; + + SV + *av_reference, + *perl_exception, + *reference, + *rv, + *sv; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + sv=NULL; + attribute=NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + hv=SvSTASH(reference); + av=newAV(); + av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv)); + SvREFCNT_dec(av); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + /* + Get options. + */ + info=GetPackageInfo(aTHX_ (void *) av,info,exception); + montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL); + (void) QueryMagickColor("none",&transparent_color,exception); + for (i=2; i < items; i+=2) + { + attribute=(char *) SvPV(ST(i-1),na); + switch (*attribute) + { + case 'B': + case 'b': + { + if (LocaleCompare(attribute,"background") == 0) + { + (void) QueryColorDatabase(SvPV(ST(i),na), + &montage_info->background_color,exception); + for (next=image; next; next=next->next) + next->background_color=montage_info->background_color; + break; + } + if (LocaleCompare(attribute,"border") == 0) + { + montage_info->border_width=SvIV(ST(i)); + break; + } + if (LocaleCompare(attribute,"bordercolor") == 0) + { + (void) QueryColorDatabase(SvPV(ST(i),na), + &montage_info->border_color,exception); + for (next=image; next; next=next->next) + next->border_color=montage_info->border_color; + break; + } + if (LocaleCompare(attribute,"borderwidth") == 0) + { + montage_info->border_width=SvIV(ST(i)); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'C': + case 'c': + { + if (LocaleCompare(attribute,"compose") == 0) + { + sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption( + MagickComposeOptions,MagickFalse,SvPV(ST(i),na)); + if (sp < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(ST(i),na)); + break; + } + for (next=image; next; next=next->next) + next->compose=(CompositeOperator) sp; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'F': + case 'f': + { + if (LocaleCompare(attribute,"fill") == 0) + { + (void) QueryColorDatabase(SvPV(ST(i),na),&montage_info->fill, + exception); + break; + } + if (LocaleCompare(attribute,"font") == 0) + { + (void) CloneString(&montage_info->font,SvPV(ST(i),na)); + break; + } + if (LocaleCompare(attribute,"frame") == 0) + { + char + *p; + + p=SvPV(ST(i),na); + if (IsGeometry(p) == MagickFalse) + { + ThrowPerlException(exception,OptionError,"MissingGeometry", + p); + break; + } + (void) CloneString(&montage_info->frame,p); + if (*p == '\0') + montage_info->frame=(char *) NULL; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'G': + case 'g': + { + if (LocaleCompare(attribute,"geometry") == 0) + { + char + *p; + + p=SvPV(ST(i),na); + if (IsGeometry(p) == MagickFalse) + { + ThrowPerlException(exception,OptionError,"MissingGeometry", + p); + break; + } + (void) CloneString(&montage_info->geometry,p); + if (*p == '\0') + montage_info->geometry=(char *) NULL; + break; + } + if (LocaleCompare(attribute,"gravity") == 0) + { + ssize_t + in; + + in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption( + MagickGravityOptions,MagickFalse,SvPV(ST(i),na)); + if (in < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(ST(i),na)); + return; + } + montage_info->gravity=(GravityType) in; + for (next=image; next; next=next->next) + next->gravity=(GravityType) in; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'L': + case 'l': + { + if (LocaleCompare(attribute,"label") == 0) + { + for (next=image; next; next=next->next) + (void) SetImageProperty(next,"label",InterpretImageProperties( + info ? info->image_info : (ImageInfo *) NULL,next, + SvPV(ST(i),na))); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'M': + case 'm': + { + if (LocaleCompare(attribute,"mattecolor") == 0) + { + (void) QueryColorDatabase(SvPV(ST(i),na), + &montage_info->matte_color,exception); + for (next=image; next; next=next->next) + next->matte_color=montage_info->matte_color; + break; + } + if (LocaleCompare(attribute,"mode") == 0) + { + ssize_t + in; + + in=!SvPOK(ST(i)) ? SvIV(ST(i)) : + ParseCommandOption(MagickModeOptions,MagickFalse,SvPV(ST(i),na)); + switch (in) + { + default: + { + ThrowPerlException(exception,OptionError, + "UnrecognizedModeType",SvPV(ST(i),na)); + break; + } + case FrameMode: + { + (void) CloneString(&montage_info->frame,"15x15+3+3"); + montage_info->shadow=MagickTrue; + break; + } + case UnframeMode: + { + montage_info->frame=(char *) NULL; + montage_info->shadow=MagickFalse; + montage_info->border_width=0; + break; + } + case ConcatenateMode: + { + montage_info->frame=(char *) NULL; + montage_info->shadow=MagickFalse; + (void) CloneString(&montage_info->geometry,"+0+0"); + montage_info->border_width=0; + } + } + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'P': + case 'p': + { + if (LocaleCompare(attribute,"pointsize") == 0) + { + montage_info->pointsize=SvIV(ST(i)); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'S': + case 's': + { + if (LocaleCompare(attribute,"shadow") == 0) + { + sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption( + MagickBooleanOptions,MagickFalse,SvPV(ST(i),na)); + if (sp < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(ST(i),na)); + break; + } + montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse; + break; + } + if (LocaleCompare(attribute,"stroke") == 0) + { + (void) QueryColorDatabase(SvPV(ST(i),na),&montage_info->stroke, + exception); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'T': + case 't': + { + if (LocaleCompare(attribute,"texture") == 0) + { + (void) CloneString(&montage_info->texture,SvPV(ST(i),na)); + break; + } + if (LocaleCompare(attribute,"tile") == 0) + { + char *p=SvPV(ST(i),na); + if (IsGeometry(p) == MagickFalse) + { + ThrowPerlException(exception,OptionError,"MissingGeometry", + p); + break; + } + (void) CloneString(&montage_info->tile,p); + if (*p == '\0') + montage_info->tile=(char *) NULL; + break; + } + if (LocaleCompare(attribute,"title") == 0) + { + (void) CloneString(&montage_info->title,SvPV(ST(i),na)); + break; + } + if (LocaleCompare(attribute,"transparent") == 0) + { + MagickPixelPacket + transparent_color; + + QueryMagickColor(SvPV(ST(i),na),&transparent_color,exception); + for (next=image; next; next=next->next) + (void) TransparentPaintImage(next,&transparent_color, + TransparentOpacity,MagickFalse); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + default: + { + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + } + } + image=MontageImageList(info->image_info,montage_info,image,exception); + montage_info=DestroyMontageInfo(montage_info); + if (image == (Image *) NULL) + goto PerlException; + if (transparent_color.opacity != TransparentOpacity) + for (next=image; next; next=next->next) + (void) TransparentPaintImage(next,&transparent_color, + TransparentOpacity,MagickFalse); + for ( ; image; image=image->next) + { + AddImageToRegistry(sv,image); + rv=newRV(sv); + av_push(av,sv_bless(rv,hv)); + SvREFCNT_dec(sv); + } + exception=DestroyExceptionInfo(exception); + ST(0)=av_reference; + SvREFCNT_dec(perl_exception); + XSRETURN(1); + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0); + SvPOK_on(perl_exception); + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# M o r p h # +# # +# # +# # +############################################################################### +# +# +void +Morph(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + MorphImage = 1 + morph = 2 + morphimage = 3 + PPCODE: + { + AV + *av; + + char + *attribute; + + ExceptionInfo + *exception; + + HV + *hv; + + Image + *image; + + register ssize_t + i; + + ssize_t + number_frames; + + struct PackageInfo + *info; + + SV + *av_reference, + *perl_exception, + *reference, + *rv, + *sv; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + sv=NULL; + av=NULL; + attribute=NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + hv=SvSTASH(reference); + av=newAV(); + av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv)); + SvREFCNT_dec(av); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + info=GetPackageInfo(aTHX_ (void *) av,info,exception); + /* + Get attribute. + */ + number_frames=30; + for (i=2; i < items; i+=2) + { + attribute=(char *) SvPV(ST(i-1),na); + switch (*attribute) + { + case 'F': + case 'f': + { + if (LocaleCompare(attribute,"frames") == 0) + { + number_frames=SvIV(ST(i)); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + default: + { + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + } + } + image=MorphImages(image,number_frames,exception); + if (image == (Image *) NULL) + goto PerlException; + for ( ; image; image=image->next) + { + AddImageToRegistry(sv,image); + rv=newRV(sv); + av_push(av,sv_bless(rv,hv)); + SvREFCNT_dec(sv); + } + exception=DestroyExceptionInfo(exception); + ST(0)=av_reference; + SvREFCNT_dec(perl_exception); /* can't return warning messages */ + XSRETURN(1); + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0); + SvPOK_on(perl_exception); + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# M o s a i c # +# # +# # +# # +############################################################################### +# +# +void +Mosaic(ref) + Image::Magick ref = NO_INIT + ALIAS: + MosaicImage = 1 + mosaic = 2 + mosaicimage = 3 + PPCODE: + { + AV + *av; + + ExceptionInfo + *exception; + + HV + *hv; + + Image + *image; + + struct PackageInfo + *info; + + SV + *perl_exception, + *reference, + *rv, + *sv; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + sv=NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + hv=SvSTASH(reference); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + image=MergeImageLayers(image,MosaicLayer,exception); + /* + Create blessed Perl array for the returned image. + */ + av=newAV(); + ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv)); + SvREFCNT_dec(av); + AddImageToRegistry(sv,image); + rv=newRV(sv); + av_push(av,sv_bless(rv,hv)); + SvREFCNT_dec(sv); + (void) CopyMagickString(info->image_info->filename,image->filename, + MaxTextExtent); + SetImageInfo(info->image_info,0,&image->exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); + XSRETURN(1); + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0); + SvPOK_on(perl_exception); /* return messages in string context */ + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# P i n g # +# # +# # +# # +############################################################################### +# +# +void +Ping(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + PingImage = 1 + ping = 2 + pingimage = 3 + PPCODE: + { + AV + *av; + + char + **keep, + **list; + + ExceptionInfo + *exception; + + Image + *image, + *next; + + int + n; + + MagickBooleanType + status; + + register char + **p; + + register ssize_t + i; + + ssize_t + ac; + + STRLEN + *length; + + struct PackageInfo + *info, + *package_info; + + SV + *perl_exception, + *reference; + + size_t + count; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + package_info=(struct PackageInfo *) NULL; + ac=(items < 2) ? 1 : items-1; + list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list)); + keep=list; + length=(STRLEN *) NULL; + if (list == (char **) NULL) + { + ThrowPerlException(exception,ResourceLimitError, + "MemoryAllocationFailed",PackageName); + goto PerlException; + } + keep=list; + length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length)); + if (length == (STRLEN *) NULL) + { + ThrowPerlException(exception,ResourceLimitError, + "MemoryAllocationFailed",PackageName); + goto PerlException; + } + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + if (SvTYPE(reference) != SVt_PVAV) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + av=(AV *) reference; + info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL, + exception); + package_info=ClonePackageInfo(info,exception); + n=1; + if (items <= 1) + *list=(char *) (*package_info->image_info->filename ? + package_info->image_info->filename : "XC:black"); + else + for (n=0, i=0; i < ac; i++) + { + list[n]=(char *) SvPV(ST(i+1),length[n]); + if ((items >= 3) && strEQcase(list[n],"blob")) + { + void + *blob; + + i++; + blob=(void *) (SvPV(ST(i+1),length[n])); + SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]); + } + if ((items >= 3) && strEQcase(list[n],"filename")) + continue; + if ((items >= 3) && strEQcase(list[n],"file")) + { + FILE + *file; + + PerlIO + *io_info; + + i++; + io_info=IoIFP(sv_2io(ST(i+1))); + if (io_info == (PerlIO *) NULL) + { + ThrowPerlException(exception,BlobError,"UnableToOpenFile", + PackageName); + continue; + } + file=PerlIO_findFILE(io_info); + if (file == (FILE *) NULL) + { + ThrowPerlException(exception,BlobError,"UnableToOpenFile", + PackageName); + continue; + } + SetImageInfoFile(package_info->image_info,file); + } + if ((items >= 3) && strEQcase(list[n],"magick")) + continue; + n++; + } + list[n]=(char *) NULL; + keep=list; + status=ExpandFilenames(&n,&list); + if (status == MagickFalse) + { + ThrowPerlException(exception,ResourceLimitError, + "MemoryAllocationFailed",PackageName); + goto PerlException; + } + count=0; + for (i=0; i < n; i++) + { + (void) CopyMagickString(package_info->image_info->filename,list[i], + MaxTextExtent); + image=PingImage(package_info->image_info,exception); + if (image == (Image *) NULL) + break; + if ((package_info->image_info->file != (FILE *) NULL) || + (package_info->image_info->blob != (void *) NULL)) + DisassociateImageStream(image); + count+=GetImageListLength(image); + EXTEND(sp,4*count); + for (next=image; next; next=next->next) + { + PUSHs(sv_2mortal(newSViv(next->columns))); + PUSHs(sv_2mortal(newSViv(next->rows))); + PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next)))); + PUSHs(sv_2mortal(newSVpv(next->magick,0))); + } + image=DestroyImageList(image); + } + /* + Free resources. + */ + for (i=0; i < n; i++) + if (list[i] != (char *) NULL) + for (p=keep; list[i] != *p++; ) + if (*p == NULL) + { + list[i]=(char *) RelinquishMagickMemory(list[i]); + break; + } + + PerlException: + if (package_info != (struct PackageInfo *) NULL) + DestroyPackageInfo(package_info); + if (list && (list != keep)) + list=(char **) RelinquishMagickMemory(list); + if (keep) + keep=(char **) RelinquishMagickMemory(keep); + if (length) + length=(STRLEN *) RelinquishMagickMemory(length); + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); /* throw away all errors */ + } + +# +############################################################################### +# # +# # +# # +# P r e v i e w # +# # +# # +# # +############################################################################### +# +# +void +Preview(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + PreviewImage = 1 + preview = 2 + previewimage = 3 + PPCODE: + { + AV + *av; + + ExceptionInfo + *exception; + + HV + *hv; + + Image + *image, + *preview_image; + + PreviewType + preview_type; + + struct PackageInfo + *info; + + SV + *av_reference, + *perl_exception, + *reference, + *rv, + *sv; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + sv=NULL; + av=NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + hv=SvSTASH(reference); + av=newAV(); + av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv)); + SvREFCNT_dec(av); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + info=GetPackageInfo(aTHX_ (void *) av,info,exception); + preview_type=GammaPreview; + if (items > 1) + preview_type=(PreviewType) + ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na)); + for ( ; image; image=image->next) + { + preview_image=PreviewImage(image,preview_type,exception); + if (preview_image == (Image *) NULL) + goto PerlException; + AddImageToRegistry(sv,preview_image); + rv=newRV(sv); + av_push(av,sv_bless(rv,hv)); + SvREFCNT_dec(sv); + } + exception=DestroyExceptionInfo(exception); + ST(0)=av_reference; + SvREFCNT_dec(perl_exception); /* can't return warning messages */ + XSRETURN(1); + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0); + SvPOK_on(perl_exception); + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# Q u e r y C o l o r # +# # +# # +# # +############################################################################### +# +# +void +QueryColor(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + querycolor = 1 + PPCODE: + { + char + *name; + + ExceptionInfo + *exception; + + MagickPixelPacket + color; + + register ssize_t + i; + + SV + *perl_exception; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + if (items == 1) + { + const ColorInfo + **colorlist; + + size_t + colors; + + colorlist=GetColorInfoList("*",&colors,exception); + EXTEND(sp,colors); + for (i=0; i < (ssize_t) colors; i++) + { + PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0))); + } + colorlist=(const ColorInfo **) + RelinquishMagickMemory((ColorInfo **) colorlist); + goto PerlException; + } + EXTEND(sp,5*items); + for (i=1; i < items; i++) + { + name=(char *) SvPV(ST(i),na); + if (QueryMagickColor(name,&color,exception) == MagickFalse) + { + PUSHs(&sv_undef); + continue; + } + PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5)))); + PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5)))); + PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5)))); + if (color.matte != MagickFalse) + PUSHs(sv_2mortal(newSViv((size_t) floor(color.opacity+0.5)))); + if (color.colorspace == CMYKColorspace) + PUSHs(sv_2mortal(newSViv((size_t) floor(color.index+0.5)))); + } + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); + } + +# +############################################################################### +# # +# # +# # +# Q u e r y C o l o r N a m e # +# # +# # +# # +############################################################################### +# +# +void +QueryColorname(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + querycolorname = 1 + PPCODE: + { + AV + *av; + + char + message[MaxTextExtent]; + + ExceptionInfo + *exception; + + Image + *image; + + PixelPacket + target_color; + + register ssize_t + i; + + struct PackageInfo + *info; + + SV + *perl_exception, + *reference; /* reference is the SV* of ref=SvIV(reference) */ + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + reference=SvRV(ST(0)); + av=(AV *) reference; + info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL, + exception); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + EXTEND(sp,items); + for (i=1; i < items; i++) + { + (void) QueryColorDatabase(SvPV(ST(i),na),&target_color,exception); + (void) QueryColorname(image,&target_color,SVGCompliance,message, + exception); + PUSHs(sv_2mortal(newSVpv(message,0))); + } + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); + } + +# +############################################################################### +# # +# # +# # +# Q u e r y F o n t # +# # +# # +# # +############################################################################### +# +# +void +QueryFont(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + queryfont = 1 + PPCODE: + { + char + *name, + message[MaxTextExtent]; + + ExceptionInfo + *exception; + + register ssize_t + i; + + SV + *perl_exception; + + volatile const TypeInfo + *type_info; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + if (items == 1) + { + const TypeInfo + **typelist; + + size_t + types; + + typelist=GetTypeInfoList("*",&types,exception); + EXTEND(sp,types); + for (i=0; i < (ssize_t) types; i++) + { + PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0))); + } + typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **) + typelist); + goto PerlException; + } + EXTEND(sp,10*items); + for (i=1; i < items; i++) + { + name=(char *) SvPV(ST(i),na); + type_info=GetTypeInfo(name,exception); + if (type_info == (TypeInfo *) NULL) + { + PUSHs(&sv_undef); + continue; + } + if (type_info->name == (char *) NULL) + PUSHs(&sv_undef); + else + PUSHs(sv_2mortal(newSVpv(type_info->name,0))); + if (type_info->description == (char *) NULL) + PUSHs(&sv_undef); + else + PUSHs(sv_2mortal(newSVpv(type_info->description,0))); + if (type_info->family == (char *) NULL) + PUSHs(&sv_undef); + else + PUSHs(sv_2mortal(newSVpv(type_info->family,0))); + if (type_info->style == UndefinedStyle) + PUSHs(&sv_undef); + else + PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions, + type_info->style),0))); + if (type_info->stretch == UndefinedStretch) + PUSHs(&sv_undef); + else + PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions, + type_info->stretch),0))); + (void) FormatLocaleString(message,MaxTextExtent,"%.20g",(double) + type_info->weight); + PUSHs(sv_2mortal(newSVpv(message,0))); + if (type_info->encoding == (char *) NULL) + PUSHs(&sv_undef); + else + PUSHs(sv_2mortal(newSVpv(type_info->encoding,0))); + if (type_info->foundry == (char *) NULL) + PUSHs(&sv_undef); + else + PUSHs(sv_2mortal(newSVpv(type_info->foundry,0))); + if (type_info->format == (char *) NULL) + PUSHs(&sv_undef); + else + PUSHs(sv_2mortal(newSVpv(type_info->format,0))); + if (type_info->metrics == (char *) NULL) + PUSHs(&sv_undef); + else + PUSHs(sv_2mortal(newSVpv(type_info->metrics,0))); + if (type_info->glyphs == (char *) NULL) + PUSHs(&sv_undef); + else + PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0))); + } + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); + } + +# +############################################################################### +# # +# # +# # +# Q u e r y F o n t M e t r i c s # +# # +# # +# # +############################################################################### +# +# +void +QueryFontMetrics(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + queryfontmetrics = 1 + PPCODE: + { + AffineMatrix + affine, + current; + + AV + *av; + + char + *attribute; + + double + x, + y; + + DrawInfo + *draw_info; + + ExceptionInfo + *exception; + + GeometryInfo + geometry_info; + + Image + *image; + + MagickBooleanType + status; + + MagickStatusType + flags; + + register ssize_t + i; + + ssize_t + type; + + struct PackageInfo + *info, + *package_info; + + SV + *perl_exception, + *reference; /* reference is the SV* of ref=SvIV(reference) */ + + TypeMetric + metrics; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + package_info=(struct PackageInfo *) NULL; + perl_exception=newSVpv("",0); + reference=SvRV(ST(0)); + av=(AV *) reference; + info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL, + exception); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + package_info=ClonePackageInfo(info,exception); + draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL); + CloneString(&draw_info->text,""); + current=draw_info->affine; + GetAffineMatrix(&affine); + x=0.0; + y=0.0; + EXTEND(sp,7*items); + for (i=2; i < items; i+=2) + { + attribute=(char *) SvPV(ST(i-1),na); + switch (*attribute) + { + case 'A': + case 'a': + { + if (LocaleCompare(attribute,"antialias") == 0) + { + type=ParseCommandOption(MagickBooleanOptions,MagickFalse, + SvPV(ST(i),na)); + if (type < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(ST(i),na)); + break; + } + draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'd': + case 'D': + { + if (LocaleCompare(attribute,"density") == 0) + { + CloneString(&draw_info->density,SvPV(ST(i),na)); + break; + } + if (LocaleCompare(attribute,"direction") == 0) + { + draw_info->direction=(DirectionType) ParseCommandOption( + MagickDirectionOptions,MagickFalse,SvPV(ST(i),na)); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'e': + case 'E': + { + if (LocaleCompare(attribute,"encoding") == 0) + { + CloneString(&draw_info->encoding,SvPV(ST(i),na)); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'f': + case 'F': + { + if (LocaleCompare(attribute,"family") == 0) + { + CloneString(&draw_info->family,SvPV(ST(i),na)); + break; + } + if (LocaleCompare(attribute,"fill") == 0) + { + if (info) + (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->fill, + &image->exception); + break; + } + if (LocaleCompare(attribute,"font") == 0) + { + CloneString(&draw_info->font,SvPV(ST(i),na)); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'g': + case 'G': + { + if (LocaleCompare(attribute,"geometry") == 0) + { + CloneString(&draw_info->geometry,SvPV(ST(i),na)); + break; + } + if (LocaleCompare(attribute,"gravity") == 0) + { + draw_info->gravity=(GravityType) ParseCommandOption( + MagickGravityOptions,MagickFalse,SvPV(ST(i),na)); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'i': + case 'I': + { + if (LocaleCompare(attribute,"interline-spacing") == 0) + { + flags=ParseGeometry(SvPV(ST(i),na),&geometry_info); + draw_info->interline_spacing=geometry_info.rho; + break; + } + if (LocaleCompare(attribute,"interword-spacing") == 0) + { + flags=ParseGeometry(SvPV(ST(i),na),&geometry_info); + draw_info->interword_spacing=geometry_info.rho; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'k': + case 'K': + { + if (LocaleCompare(attribute,"kerning") == 0) + { + flags=ParseGeometry(SvPV(ST(i),na),&geometry_info); + draw_info->kerning=geometry_info.rho; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'p': + case 'P': + { + if (LocaleCompare(attribute,"pointsize") == 0) + { + flags=ParseGeometry(SvPV(ST(i),na),&geometry_info); + draw_info->pointsize=geometry_info.rho; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'r': + case 'R': + { + if (LocaleCompare(attribute,"rotate") == 0) + { + flags=ParseGeometry(SvPV(ST(i),na),&geometry_info); + affine.rx=geometry_info.rho; + affine.ry=geometry_info.sigma; + if ((flags & SigmaValue) == 0) + affine.ry=affine.rx; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 's': + case 'S': + { + if (LocaleCompare(attribute,"scale") == 0) + { + flags=ParseGeometry(SvPV(ST(i),na),&geometry_info); + affine.sx=geometry_info.rho; + affine.sy=geometry_info.sigma; + if ((flags & SigmaValue) == 0) + affine.sy=affine.sx; + break; + } + if (LocaleCompare(attribute,"skew") == 0) + { + double + x_angle, + y_angle; + + flags=ParseGeometry(SvPV(ST(i),na),&geometry_info); + x_angle=geometry_info.rho; + y_angle=geometry_info.sigma; + if ((flags & SigmaValue) == 0) + y_angle=x_angle; + affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0))); + affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0))); + break; + } + if (LocaleCompare(attribute,"stroke") == 0) + { + if (info) + (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->stroke, + &image->exception); + break; + } + if (LocaleCompare(attribute,"style") == 0) + { + type=ParseCommandOption(MagickStyleOptions,MagickFalse, + SvPV(ST(i),na)); + if (type < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(ST(i),na)); + break; + } + draw_info->style=(StyleType) type; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 't': + case 'T': + { + if (LocaleCompare(attribute,"text") == 0) + { + CloneString(&draw_info->text,SvPV(ST(i),na)); + break; + } + if (LocaleCompare(attribute,"translate") == 0) + { + flags=ParseGeometry(SvPV(ST(i),na),&geometry_info); + affine.tx=geometry_info.rho; + affine.ty=geometry_info.sigma; + if ((flags & SigmaValue) == 0) + affine.ty=affine.tx; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'w': + case 'W': + { + if (LocaleCompare(attribute,"weight") == 0) + { + flags=ParseGeometry(SvPV(ST(i),na),&geometry_info); + draw_info->weight=(size_t) geometry_info.rho; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'x': + case 'X': + { + if (LocaleCompare(attribute,"x") == 0) + { + flags=ParseGeometry(SvPV(ST(i),na),&geometry_info); + x=geometry_info.rho; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'y': + case 'Y': + { + if (LocaleCompare(attribute,"y") == 0) + { + flags=ParseGeometry(SvPV(ST(i),na),&geometry_info); + y=geometry_info.rho; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + default: + { + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + } + } + draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx; + draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx; + draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy; + draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy; + draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx; + draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty; + if (draw_info->geometry == (char *) NULL) + { + draw_info->geometry=AcquireString((char *) NULL); + (void) FormatLocaleString(draw_info->geometry,MaxTextExtent, + "%.15g,%.15g",x,y); + } + status=GetTypeMetrics(image,draw_info,&metrics); + (void) CatchImageException(image); + if (status == MagickFalse) + PUSHs(&sv_undef); + else + { + PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x))); + PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y))); + PUSHs(sv_2mortal(newSVnv(metrics.ascent))); + PUSHs(sv_2mortal(newSVnv(metrics.descent))); + PUSHs(sv_2mortal(newSVnv(metrics.width))); + PUSHs(sv_2mortal(newSVnv(metrics.height))); + PUSHs(sv_2mortal(newSVnv(metrics.max_advance))); + PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1))); + PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1))); + PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2))); + PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2))); + PUSHs(sv_2mortal(newSVnv(metrics.origin.x))); + PUSHs(sv_2mortal(newSVnv(metrics.origin.y))); + } + draw_info=DestroyDrawInfo(draw_info); + + PerlException: + if (package_info != (struct PackageInfo *) NULL) + DestroyPackageInfo(package_info); + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); /* can't return warning messages */ + } + +# +############################################################################### +# # +# # +# # +# Q u e r y M u l t i l i n e F o n t M e t r i c s # +# # +# # +# # +############################################################################### +# +# +void +QueryMultilineFontMetrics(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + querymultilinefontmetrics = 1 + PPCODE: + { + AffineMatrix + affine, + current; + + AV + *av; + + char + *attribute; + + double + x, + y; + + DrawInfo + *draw_info; + + ExceptionInfo + *exception; + + GeometryInfo + geometry_info; + + Image + *image; + + MagickBooleanType + status; + + MagickStatusType + flags; + + register ssize_t + i; + + ssize_t + type; + + struct PackageInfo + *info, + *package_info; + + SV + *perl_exception, + *reference; /* reference is the SV* of ref=SvIV(reference) */ + + TypeMetric + metrics; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + package_info=(struct PackageInfo *) NULL; + perl_exception=newSVpv("",0); + reference=SvRV(ST(0)); + av=(AV *) reference; + info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL, + exception); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + package_info=ClonePackageInfo(info,exception); + draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL); + CloneString(&draw_info->text,""); + current=draw_info->affine; + GetAffineMatrix(&affine); + x=0.0; + y=0.0; + EXTEND(sp,7*items); + for (i=2; i < items; i+=2) + { + attribute=(char *) SvPV(ST(i-1),na); + switch (*attribute) + { + case 'A': + case 'a': + { + if (LocaleCompare(attribute,"antialias") == 0) + { + type=ParseCommandOption(MagickBooleanOptions,MagickFalse, + SvPV(ST(i),na)); + if (type < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(ST(i),na)); + break; + } + draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'd': + case 'D': + { + if (LocaleCompare(attribute,"density") == 0) + { + CloneString(&draw_info->density,SvPV(ST(i),na)); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'e': + case 'E': + { + if (LocaleCompare(attribute,"encoding") == 0) + { + CloneString(&draw_info->encoding,SvPV(ST(i),na)); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'f': + case 'F': + { + if (LocaleCompare(attribute,"family") == 0) + { + CloneString(&draw_info->family,SvPV(ST(i),na)); + break; + } + if (LocaleCompare(attribute,"fill") == 0) + { + if (info) + (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->fill, + &image->exception); + break; + } + if (LocaleCompare(attribute,"font") == 0) + { + CloneString(&draw_info->font,SvPV(ST(i),na)); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'g': + case 'G': + { + if (LocaleCompare(attribute,"geometry") == 0) + { + CloneString(&draw_info->geometry,SvPV(ST(i),na)); + break; + } + if (LocaleCompare(attribute,"gravity") == 0) + { + draw_info->gravity=(GravityType) ParseCommandOption( + MagickGravityOptions,MagickFalse,SvPV(ST(i),na)); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'p': + case 'P': + { + if (LocaleCompare(attribute,"pointsize") == 0) + { + flags=ParseGeometry(SvPV(ST(i),na),&geometry_info); + draw_info->pointsize=geometry_info.rho; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'r': + case 'R': + { + if (LocaleCompare(attribute,"rotate") == 0) + { + flags=ParseGeometry(SvPV(ST(i),na),&geometry_info); + affine.rx=geometry_info.rho; + affine.ry=geometry_info.sigma; + if ((flags & SigmaValue) == 0) + affine.ry=affine.rx; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 's': + case 'S': + { + if (LocaleCompare(attribute,"scale") == 0) + { + flags=ParseGeometry(SvPV(ST(i),na),&geometry_info); + affine.sx=geometry_info.rho; + affine.sy=geometry_info.sigma; + if ((flags & SigmaValue) == 0) + affine.sy=affine.sx; + break; + } + if (LocaleCompare(attribute,"skew") == 0) + { + double + x_angle, + y_angle; + + flags=ParseGeometry(SvPV(ST(i),na),&geometry_info); + x_angle=geometry_info.rho; + y_angle=geometry_info.sigma; + if ((flags & SigmaValue) == 0) + y_angle=x_angle; + affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0))); + affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0))); + break; + } + if (LocaleCompare(attribute,"stroke") == 0) + { + if (info) + (void) QueryColorDatabase(SvPV(ST(i),na),&draw_info->stroke, + &image->exception); + break; + } + if (LocaleCompare(attribute,"style") == 0) + { + type=ParseCommandOption(MagickStyleOptions,MagickFalse, + SvPV(ST(i),na)); + if (type < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(ST(i),na)); + break; + } + draw_info->style=(StyleType) type; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 't': + case 'T': + { + if (LocaleCompare(attribute,"text") == 0) + { + CloneString(&draw_info->text,SvPV(ST(i),na)); + break; + } + if (LocaleCompare(attribute,"translate") == 0) + { + flags=ParseGeometry(SvPV(ST(i),na),&geometry_info); + affine.tx=geometry_info.rho; + affine.ty=geometry_info.sigma; + if ((flags & SigmaValue) == 0) + affine.ty=affine.tx; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'w': + case 'W': + { + if (LocaleCompare(attribute,"weight") == 0) + { + flags=ParseGeometry(SvPV(ST(i),na),&geometry_info); + draw_info->weight=(size_t) geometry_info.rho; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'x': + case 'X': + { + if (LocaleCompare(attribute,"x") == 0) + { + flags=ParseGeometry(SvPV(ST(i),na),&geometry_info); + x=geometry_info.rho; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'y': + case 'Y': + { + if (LocaleCompare(attribute,"y") == 0) + { + flags=ParseGeometry(SvPV(ST(i),na),&geometry_info); + y=geometry_info.rho; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + default: + { + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + } + } + draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx; + draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx; + draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy; + draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy; + draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx; + draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty; + if (draw_info->geometry == (char *) NULL) + { + draw_info->geometry=AcquireString((char *) NULL); + (void) FormatLocaleString(draw_info->geometry,MaxTextExtent, + "%.15g,%.15g",x,y); + } + status=GetMultilineTypeMetrics(image,draw_info,&metrics); + (void) CatchImageException(image); + if (status == MagickFalse) + PUSHs(&sv_undef); + else + { + PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x))); + PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y))); + PUSHs(sv_2mortal(newSVnv(metrics.ascent))); + PUSHs(sv_2mortal(newSVnv(metrics.descent))); + PUSHs(sv_2mortal(newSVnv(metrics.width))); + PUSHs(sv_2mortal(newSVnv(metrics.height))); + PUSHs(sv_2mortal(newSVnv(metrics.max_advance))); + PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1))); + PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1))); + PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2))); + PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2))); + PUSHs(sv_2mortal(newSVnv(metrics.origin.x))); + PUSHs(sv_2mortal(newSVnv(metrics.origin.y))); + } + draw_info=DestroyDrawInfo(draw_info); + + PerlException: + if (package_info != (struct PackageInfo *) NULL) + DestroyPackageInfo(package_info); + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); /* can't return warning messages */ + } + +# +############################################################################### +# # +# # +# # +# Q u e r y F o r m a t # +# # +# # +# # +############################################################################### +# +# +void +QueryFormat(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + queryformat = 1 + PPCODE: + { + char + *name; + + ExceptionInfo + *exception; + + register ssize_t + i; + + SV + *perl_exception; + + volatile const MagickInfo + *magick_info; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + if (items == 1) + { + char + format[MaxTextExtent]; + + const MagickInfo + **format_list; + + size_t + types; + + format_list=GetMagickInfoList("*",&types,exception); + EXTEND(sp,types); + for (i=0; i < (ssize_t) types; i++) + { + (void) CopyMagickString(format,format_list[i]->name,MaxTextExtent); + LocaleLower(format); + PUSHs(sv_2mortal(newSVpv(format,0))); + } + format_list=(const MagickInfo **) + RelinquishMagickMemory((MagickInfo *) format_list); + goto PerlException; + } + EXTEND(sp,8*items); + for (i=1; i < items; i++) + { + name=(char *) SvPV(ST(i),na); + magick_info=GetMagickInfo(name,exception); + if (magick_info == (const MagickInfo *) NULL) + { + PUSHs(&sv_undef); + continue; + } + PUSHs(sv_2mortal(newSViv(magick_info->adjoin))); + PUSHs(sv_2mortal(newSViv(magick_info->blob_support))); + PUSHs(sv_2mortal(newSViv(magick_info->raw))); + PUSHs(sv_2mortal(newSViv((long) magick_info->decoder))); + PUSHs(sv_2mortal(newSViv((long) magick_info->encoder))); + if (magick_info->description == (char *) NULL) + PUSHs(&sv_undef); + else + PUSHs(sv_2mortal(newSVpv(magick_info->description,0))); + if (magick_info->module == (char *) NULL) + PUSHs(&sv_undef); + else + PUSHs(sv_2mortal(newSVpv(magick_info->module,0))); + } + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); + } + +# +############################################################################### +# # +# # +# # +# Q u e r y O p t i o n # +# # +# # +# # +############################################################################### +# +# +void +QueryOption(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + queryoption = 1 + PPCODE: + { + char + **options; + + ExceptionInfo + *exception; + + register ssize_t + i; + + ssize_t + j, + option; + + SV + *perl_exception; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + EXTEND(sp,8*items); + for (i=1; i < items; i++) + { + option=ParseCommandOption(MagickListOptions,MagickFalse,(char *) + SvPV(ST(i),na)); + options=GetCommandOptions((CommandOption) option); + if (options == (char **) NULL) + PUSHs(&sv_undef); + else + { + for (j=0; options[j] != (char *) NULL; j++) + PUSHs(sv_2mortal(newSVpv(options[j],0))); + options=DestroyStringList(options); + } + } + + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); + } + +# +############################################################################### +# # +# # +# # +# R e a d # +# # +# # +# # +############################################################################### +# +# +void +Read(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + ReadImage = 1 + read = 2 + readimage = 3 + PPCODE: + { + AV + *av; + + char + **keep, + **list; + + ExceptionInfo + *exception; + + HV + *hv; + + Image + *image; + + int + n; + + MagickBooleanType + status; + + register char + **p; + + register ssize_t + i; + + ssize_t + ac, + number_images; + + STRLEN + *length; + + struct PackageInfo + *info, + *package_info; + + SV + *perl_exception, /* Perl variable for storing messages */ + *reference, + *rv, + *sv; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + sv=NULL; + package_info=(struct PackageInfo *) NULL; + number_images=0; + ac=(items < 2) ? 1 : items-1; + list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list)); + keep=list; + length=(STRLEN *) NULL; + if (list == (char **) NULL) + { + ThrowPerlException(exception,ResourceLimitError, + "MemoryAllocationFailed",PackageName); + goto PerlException; + } + length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length)); + if (length == (STRLEN *) NULL) + { + ThrowPerlException(exception,ResourceLimitError, + "MemoryAllocationFailed",PackageName); + goto PerlException; + } + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + hv=SvSTASH(reference); + if (SvTYPE(reference) != SVt_PVAV) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + av=(AV *) reference; + info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL, + exception); + package_info=ClonePackageInfo(info,exception); + n=1; + if (items <= 1) + *list=(char *) (*package_info->image_info->filename ? + package_info->image_info->filename : "XC:black"); + else + for (n=0, i=0; i < ac; i++) + { + list[n]=(char *) SvPV(ST(i+1),length[n]); + if ((items >= 3) && strEQcase(list[n],"blob")) + { + void + *blob; + + i++; + blob=(void *) (SvPV(ST(i+1),length[n])); + SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]); + } + if ((items >= 3) && strEQcase(list[n],"filename")) + continue; + if ((items >= 3) && strEQcase(list[n],"file")) + { + FILE + *file; + + PerlIO + *io_info; + + i++; + io_info=IoIFP(sv_2io(ST(i+1))); + if (io_info == (PerlIO *) NULL) + { + ThrowPerlException(exception,BlobError,"UnableToOpenFile", + PackageName); + continue; + } + file=PerlIO_findFILE(io_info); + if (file == (FILE *) NULL) + { + ThrowPerlException(exception,BlobError,"UnableToOpenFile", + PackageName); + continue; + } + SetImageInfoFile(package_info->image_info,file); + } + if ((items >= 3) && strEQcase(list[n],"magick")) + continue; + n++; + } + list[n]=(char *) NULL; + keep=list; + status=ExpandFilenames(&n,&list); + if (status == MagickFalse) + { + ThrowPerlException(exception,ResourceLimitError, + "MemoryAllocationFailed",PackageName); + goto PerlException; + } + number_images=0; + for (i=0; i < n; i++) + { + if ((package_info->image_info->file != (FILE *) NULL) || + (package_info->image_info->blob != (void *) NULL)) + { + image=ReadImages(package_info->image_info,exception); + if (image != (Image *) NULL) + DisassociateImageStream(image); + } + else + { + (void) CopyMagickString(package_info->image_info->filename,list[i], + MaxTextExtent); + image=ReadImages(package_info->image_info,exception); + } + if (image == (Image *) NULL) + break; + for ( ; image; image=image->next) + { + AddImageToRegistry(sv,image); + rv=newRV(sv); + av_push(av,sv_bless(rv,hv)); + SvREFCNT_dec(sv); + number_images++; + } + } + /* + Free resources. + */ + for (i=0; i < n; i++) + if (list[i] != (char *) NULL) + for (p=keep; list[i] != *p++; ) + if (*p == (char *) NULL) + { + list[i]=(char *) RelinquishMagickMemory(list[i]); + break; + } + + PerlException: + if (package_info != (struct PackageInfo *) NULL) + DestroyPackageInfo(package_info); + if (list && (list != keep)) + list=(char **) RelinquishMagickMemory(list); + if (keep) + keep=(char **) RelinquishMagickMemory(keep); + if (length) + length=(STRLEN *) RelinquishMagickMemory(length); + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) number_images); + SvPOK_on(perl_exception); + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# R e m o t e # +# # +# # +# # +############################################################################### +# +# +void +Remote(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + RemoteCommand = 1 + remote = 2 + remoteCommand = 3 + PPCODE: + { + AV + *av; + + ExceptionInfo + *exception; + + register ssize_t + i; + + SV + *perl_exception, + *reference; + + struct PackageInfo + *info; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + reference=SvRV(ST(0)); + av=(AV *) reference; + info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL, + exception); + for (i=1; i < items; i++) + (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *) + SvPV(ST(i),na),exception); + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); /* throw away all errors */ + } + +# +############################################################################### +# # +# # +# # +# S e t # +# # +# # +# # +############################################################################### +# +# +void +Set(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + SetAttributes = 1 + SetAttribute = 2 + set = 3 + setattributes = 4 + setattribute = 5 + PPCODE: + { + ExceptionInfo + *exception; + + Image + *image; + + register ssize_t + i; + + struct PackageInfo + *info; + + SV + *perl_exception, + *reference; /* reference is the SV* of ref=SvIV(reference) */ + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (items == 2) + SetAttribute(aTHX_ info,image,"size",ST(1),exception); + else + for (i=2; i < items; i+=2) + SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception); + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0)); + SvPOK_on(perl_exception); + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# S e t P i x e l # +# # +# # +# # +############################################################################### +# +# +void +SetPixel(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + setpixel = 1 + setPixel = 2 + PPCODE: + { + AV + *av; + + char + *attribute; + + ChannelType + channel; + + ExceptionInfo + *exception; + + Image + *image; + + MagickBooleanType + normalize; + + RectangleInfo + region; + + register IndexPacket + *indexes; + + register ssize_t + i; + + register PixelPacket + *q; + + ssize_t + option; + + struct PackageInfo + *info; + + SV + *perl_exception, + *reference; /* reference is the SV* of ref=SvIV(reference) */ + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + reference=SvRV(ST(0)); + av=(AV *) reference; + info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL, + exception); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + av=(AV *) NULL; + channel=DefaultChannels; + normalize=MagickTrue; + region.x=0; + region.y=0; + region.width=image->columns; + region.height=1; + if (items == 1) + (void) ParseAbsoluteGeometry(SvPV(ST(1),na),®ion); + for (i=2; i < items; i+=2) + { + attribute=(char *) SvPV(ST(i-1),na); + switch (*attribute) + { + case 'C': + case 'c': + { + if (LocaleCompare(attribute,"channel") == 0) + { + ssize_t + option; + + option=ParseChannelOption(SvPV(ST(i),na)); + if (option < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(ST(i),na)); + return; + } + channel=(ChannelType) option; + break; + } + if (LocaleCompare(attribute,"color") == 0) + { + if (SvTYPE(ST(i)) != SVt_RV) + { + char + message[MaxTextExtent]; + + (void) FormatLocaleString(message,MaxTextExtent, + "invalid %.60s value",attribute); + ThrowPerlException(exception,OptionError,message, + SvPV(ST(i),na)); + } + av=(AV *) SvRV(ST(i)); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'g': + case 'G': + { + if (LocaleCompare(attribute,"geometry") == 0) + { + (void) ParseAbsoluteGeometry(SvPV(ST(i),na),®ion); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'N': + case 'n': + { + if (LocaleCompare(attribute,"normalize") == 0) + { + option=ParseCommandOption(MagickBooleanOptions,MagickFalse, + SvPV(ST(i),na)); + if (option < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(ST(i),na)); + break; + } + normalize=option != 0 ? MagickTrue : MagickFalse; + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'x': + case 'X': + { + if (LocaleCompare(attribute,"x") == 0) + { + region.x=SvIV(ST(i)); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'y': + case 'Y': + { + if (LocaleCompare(attribute,"y") == 0) + { + region.y=SvIV(ST(i)); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + default: + { + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + } + } + (void) SetImageStorageClass(image,DirectClass); + q=GetAuthenticPixels(image,region.x,region.y,1,1,exception); + if ((q == (PixelPacket *) NULL) || (av == (AV *) NULL) || + (SvTYPE(av) != SVt_PVAV)) + PUSHs(&sv_undef); + else + { + double + scale; + + register ssize_t + i; + + i=0; + indexes=GetAuthenticIndexQueue(image); + scale=1.0; + if (normalize != MagickFalse) + scale=QuantumRange; + if (((channel & RedChannel) != 0) && (i <= av_len(av))) + { + SetPixelRed(q,ClampToQuantum(scale*SvNV(*( + av_fetch(av,i,0))))); + i++; + } + if (((channel & GreenChannel) != 0) && (i <= av_len(av))) + { + SetPixelGreen(q,ClampToQuantum(scale*SvNV(*( + av_fetch(av,i,0))))); + i++; + } + if (((channel & BlueChannel) != 0) && (i <= av_len(av))) + { + SetPixelBlue(q,ClampToQuantum(scale*SvNV(*( + av_fetch(av,i,0))))); + i++; + } + if ((((channel & IndexChannel) != 0) && + (image->colorspace == CMYKColorspace)) && (i <= av_len(av))) + { + SetPixelIndex(indexes,ClampToQuantum(scale* + SvNV(*(av_fetch(av,i,0))))); + i++; + } + if (((channel & OpacityChannel) != 0) && (i <= av_len(av))) + { + SetPixelOpacity(q,ClampToQuantum(scale* + SvNV(*(av_fetch(av,i,0))))); + i++; + } + (void) SyncAuthenticPixels(image,exception); + } + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); + } + +# +############################################################################### +# # +# # +# # +# S m u s h # +# # +# # +# # +############################################################################### +# +# +void +Smush(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + SmushImage = 1 + smush = 2 + smushimage = 3 + PPCODE: + { + AV + *av; + + char + *attribute; + + ExceptionInfo + *exception; + + HV + *hv; + + Image + *image; + + register ssize_t + i; + + ssize_t + offset, + stack; + + struct PackageInfo + *info; + + SV + *av_reference, + *perl_exception, + *reference, + *rv, + *sv; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + sv=NULL; + attribute=NULL; + av=NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + hv=SvSTASH(reference); + av=newAV(); + av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv)); + SvREFCNT_dec(av); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + info=GetPackageInfo(aTHX_ (void *) av,info,exception); + /* + Get options. + */ + offset=0; + stack=MagickTrue; + for (i=2; i < items; i+=2) + { + attribute=(char *) SvPV(ST(i-1),na); + switch (*attribute) + { + case 'O': + case 'o': + { + if (LocaleCompare(attribute,"offset") == 0) + { + offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na)); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'S': + case 's': + { + if (LocaleCompare(attribute,"stack") == 0) + { + stack=ParseCommandOption(MagickBooleanOptions,MagickFalse, + SvPV(ST(i),na)); + if (stack < 0) + { + ThrowPerlException(exception,OptionError,"UnrecognizedType", + SvPV(ST(i),na)); + return; + } + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + default: + { + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + } + } + image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset, + exception); + if (image == (Image *) NULL) + goto PerlException; + for ( ; image; image=image->next) + { + AddImageToRegistry(sv,image); + rv=newRV(sv); + av_push(av,sv_bless(rv,hv)); + SvREFCNT_dec(sv); + } + exception=DestroyExceptionInfo(exception); + ST(0)=av_reference; + SvREFCNT_dec(perl_exception); + XSRETURN(1); + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0); + SvPOK_on(perl_exception); + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# S t a t i s t i c s # +# # +# # +# # +############################################################################### +# +# +void +Statistics(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + StatisticsImage = 1 + statistics = 2 + statisticsimage = 3 + PPCODE: + { +#define ChannelStatistics(channel) \ +{ \ + (void) FormatLocaleString(message,MaxTextExtent,"%.20g", \ + (double) channel_statistics[channel].depth); \ + PUSHs(sv_2mortal(newSVpv(message,0))); \ + (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \ + channel_statistics[channel].minima/scale); \ + PUSHs(sv_2mortal(newSVpv(message,0))); \ + (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \ + channel_statistics[channel].maxima/scale); \ + PUSHs(sv_2mortal(newSVpv(message,0))); \ + (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \ + channel_statistics[channel].mean/scale); \ + PUSHs(sv_2mortal(newSVpv(message,0))); \ + (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \ + channel_statistics[channel].standard_deviation/scale); \ + PUSHs(sv_2mortal(newSVpv(message,0))); \ + (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \ + channel_statistics[channel].kurtosis); \ + PUSHs(sv_2mortal(newSVpv(message,0))); \ + (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \ + channel_statistics[channel].skewness); \ + PUSHs(sv_2mortal(newSVpv(message,0))); \ + (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \ + channel_statistics[channel].entropy); \ + PUSHs(sv_2mortal(newSVpv(message,0))); \ +} + + AV + *av; + + char + message[MaxTextExtent]; + + ChannelStatistics + *channel_statistics; + + double + scale; + + ExceptionInfo + *exception; + + Image + *image; + + ssize_t + count; + + struct PackageInfo + *info; + + SV + *perl_exception, + *reference; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + av=NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + av=newAV(); + SvREFCNT_dec(av); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + count=0; + for ( ; image; image=image->next) + { + channel_statistics=GetImageChannelStatistics(image,&image->exception); + if (channel_statistics == (ChannelStatistics *) NULL) + continue; + count++; + EXTEND(sp,35*count); + scale=(double) QuantumRange; + ChannelStatistics(RedChannel); + ChannelStatistics(GreenChannel); + ChannelStatistics(BlueChannel); + if (image->colorspace == CMYKColorspace) + ChannelStatistics(IndexChannel); + if (image->matte != MagickFalse) + ChannelStatistics(OpacityChannel); + channel_statistics=(ChannelStatistics *) + RelinquishMagickMemory(channel_statistics); + } + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); + } + +# +############################################################################### +# # +# # +# # +# S y n c A u t h e n t i c P i x e l s # +# # +# # +# # +############################################################################### +# +# +void +SyncAuthenticPixels(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + Syncauthenticpixels = 1 + SyncImagePixels = 2 + syncimagepixels = 3 + CODE: + { + ExceptionInfo + *exception; + + Image + *image; + + MagickBooleanType + status; + + struct PackageInfo + *info; + + SV + *perl_exception, + *reference; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + + reference=SvRV(ST(0)); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + + status=SyncAuthenticPixels(image,exception); + if (status != MagickFalse) + return; + InheritException(exception,&image->exception); + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + SvREFCNT_dec(perl_exception); /* throw away all errors */ + } + +# +############################################################################### +# # +# # +# # +# T r a n s f o r m # +# # +# # +# # +############################################################################### +# +# +void +Transform(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + TransformImage = 1 + transform = 2 + transformimage = 3 + PPCODE: + { + AV + *av; + + char + *attribute, + *crop_geometry, + *geometry; + + ExceptionInfo + *exception; + + HV + *hv; + + Image + *clone, + *image; + + register ssize_t + i; + + struct PackageInfo + *info; + + SV + *av_reference, + *perl_exception, + *reference, + *rv, + *sv; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + sv=NULL; + av=NULL; + attribute=NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + hv=SvSTASH(reference); + av=newAV(); + av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv)); + SvREFCNT_dec(av); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + info=GetPackageInfo(aTHX_ (void *) av,info,exception); + /* + Get attribute. + */ + crop_geometry=(char *) NULL; + geometry=(char *) NULL; + for (i=2; i < items; i+=2) + { + attribute=(char *) SvPV(ST(i-1),na); + switch (*attribute) + { + case 'c': + case 'C': + { + if (LocaleCompare(attribute,"crop") == 0) + { + crop_geometry=SvPV(ST(i),na); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + case 'g': + case 'G': + { + if (LocaleCompare(attribute,"geometry") == 0) + { + geometry=SvPV(ST(i),na); + break; + } + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + default: + { + ThrowPerlException(exception,OptionError,"UnrecognizedAttribute", + attribute); + break; + } + } + } + for ( ; image; image=image->next) + { + clone=CloneImage(image,0,0,MagickTrue,exception); + if (clone == (Image *) NULL) + goto PerlException; + TransformImage(&clone,crop_geometry,geometry); + for ( ; clone; clone=clone->next) + { + AddImageToRegistry(sv,clone); + rv=newRV(sv); + av_push(av,sv_bless(rv,hv)); + SvREFCNT_dec(sv); + } + } + exception=DestroyExceptionInfo(exception); + ST(0)=av_reference; + SvREFCNT_dec(perl_exception); /* can't return warning messages */ + XSRETURN(1); + + PerlException: + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0); + SvPOK_on(perl_exception); + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + } + +# +############################################################################### +# # +# # +# # +# W r i t e # +# # +# # +# # +############################################################################### +# +# +void +Write(ref,...) + Image::Magick ref = NO_INIT + ALIAS: + WriteImage = 1 + write = 2 + writeimage = 3 + PPCODE: + { + char + filename[MaxTextExtent]; + + ExceptionInfo + *exception; + + Image + *image, + *next; + + register ssize_t + i; + + ssize_t + number_images, + scene; + + struct PackageInfo + *info, + *package_info; + + SV + *perl_exception, + *reference; + + PERL_UNUSED_VAR(ref); + PERL_UNUSED_VAR(ix); + exception=AcquireExceptionInfo(); + perl_exception=newSVpv("",0); + number_images=0; + package_info=(struct PackageInfo *) NULL; + if (sv_isobject(ST(0)) == 0) + { + ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType", + PackageName); + goto PerlException; + } + reference=SvRV(ST(0)); + image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception); + if (image == (Image *) NULL) + { + ThrowPerlException(exception,OptionError,"NoImagesDefined", + PackageName); + goto PerlException; + } + package_info=ClonePackageInfo(info,exception); + if (items == 2) + SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception); + else + if (items > 2) + for (i=2; i < items; i+=2) + SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i), + exception); + (void) CopyMagickString(filename,package_info->image_info->filename, + MaxTextExtent); + scene=0; + for (next=image; next; next=next->next) + { + (void) CopyMagickString(next->filename,filename,MaxTextExtent); + next->scene=scene++; + } + *package_info->image_info->magick='\0'; + SetImageInfo(package_info->image_info,(unsigned int) + GetImageListLength(image),&image->exception); + for (next=image; next; next=next->next) + { + (void) WriteImage(package_info->image_info,next); + if (next->exception.severity >= ErrorException) + InheritException(exception,&next->exception); + GetImageException(next,exception); + number_images++; + if (package_info->image_info->adjoin) + break; + } + + PerlException: + if (package_info != (struct PackageInfo *) NULL) + DestroyPackageInfo(package_info); + InheritPerlException(exception,perl_exception); + exception=DestroyExceptionInfo(exception); + sv_setiv(perl_exception,(IV) number_images); + SvPOK_on(perl_exception); + ST(0)=sv_2mortal(perl_exception); + XSRETURN(1); + }