• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                         PPPP   EEEEE  RRRR   L                              %
6 %                         P   P  E      R   R  L                              %
7 %                         PPPP   EEE    RRRR   L                              %
8 %                         P      E      R  R   L                              %
9 %                         P      EEEEE  R   R  LLLLL                          %
10 %                                                                             %
11 %                  M   M   AAA    GGGG  IIIII   CCCC  K   K                   %
12 %                  MM MM  A   A  G        I    C      K  K                    %
13 %                  M M M  AAAAA  G GGG    I    C      KKK                     %
14 %                  M   M  A   A  G   G    I    C      K  K                    %
15 %                  M   M  A   A   GGGG  IIIII   CCCC  K   K                   %
16 %                                                                             %
17 %                                                                             %
18 %                Object-oriented Perl interface to ImageMagick                %
19 %                                                                             %
20 %                            Software Design                                  %
21 %                              Kyle Shorter                                   %
22 %                                 Cristy                                      %
23 %                             February 1997                                   %
24 %                                                                             %
25 %                                                                             %
26 %  Copyright 1999-2020 ImageMagick Studio LLC, a non-profit organization      %
27 %  dedicated to making software imaging solutions freely available.           %
28 %                                                                             %
29 %  You may not use this file except in compliance with the License.  You may  %
30 %  obtain a copy of the License at                                            %
31 %                                                                             %
32 %    https://imagemagick.org/script/license.php                               %
33 %                                                                             %
34 %  Unless required by applicable law or agreed to in writing, software        %
35 %  distributed under the License is distributed on an "AS IS" BASIS,          %
36 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
37 %  See the License for the specific language governing permissions and        %
38 %  limitations under the License.                                             %
39 %                                                                             %
40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41 %
42 %  PerlMagick is an objected-oriented Perl interface to ImageMagick.  Use
43 %  the module to read, manipulate, or write an image or image sequence from
44 %  within a Perl script.  This makes PerlMagick suitable for Web CGI scripts.
45 %
46 */
47 
48 /*
49   Include declarations.
50 */
51 #if defined(__cplusplus) || defined(c_plusplus)
52 extern "C" {
53 #endif
54 
55 #define PERL_NO_GET_CONTEXT
56 #include <MagickCore/MagickCore.h>
57 #include "EXTERN.h"
58 #include "perl.h"
59 #include "XSUB.h"
60 #include <math.h>
61 #undef tainted
62 
63 #if defined(__cplusplus) || defined(c_plusplus)
64 }
65 #endif
66 
67 /*
68   Define declarations.
69 */
70 #ifndef aTHX_
71 #define aTHX_
72 #define pTHX_
73 #define dTHX
74 #endif
75 #define DegreesToRadians(x)  (MagickPI*(x)/180.0)
76 #define EndOf(array)  (&array[NumberOf(array)])
77 #define MagickPI  3.14159265358979323846264338327950288419716939937510
78 #define MaxArguments  34
79 #ifndef na
80 #define na  PL_na
81 #endif
82 #define NumberOf(array)  (sizeof(array)/sizeof(*array))
83 #define PackageName   "Image::Magick"
84 #if PERL_VERSION <= 6
85 #define PerlIO  FILE
86 #define PerlIO_importFILE(f, fl)  (f)
87 #define PerlIO_findFILE(f)  NULL
88 #endif
89 #ifndef sv_undef
90 #define sv_undef  PL_sv_undef
91 #endif
92 
93 #define AddImageToRegistry(sv,image) \
94 { \
95   if (magick_registry != (SplayTreeInfo *) NULL) \
96     { \
97       (void) AddValueToSplayTree(magick_registry,image,image); \
98       (sv)=newSViv(PTR2IV(image)); \
99     } \
100 }
101 
102 #define DeleteImageFromRegistry(reference,image) \
103 { \
104   if (magick_registry != (SplayTreeInfo *) NULL) \
105     { \
106       if (GetImageReferenceCount(image) == 1) \
107        (void) DeleteNodeByValueFromSplayTree(magick_registry,image); \
108       image=DestroyImage(image); \
109       sv_setiv(reference,0); \
110     } \
111 }
112 
113 #define InheritPerlException(exception,perl_exception) \
114 { \
115   char \
116     message[MagickPathExtent]; \
117  \
118   if ((exception)->severity != UndefinedException) \
119     { \
120       (void) FormatLocaleString(message,MagickPathExtent,"Exception %d: %s%s%s%s",\
121         (exception)->severity, (exception)->reason ? \
122         GetLocaleExceptionMessage((exception)->severity,(exception)->reason) : \
123         "Unknown", (exception)->description ? " (" : "", \
124         (exception)->description ? GetLocaleExceptionMessage( \
125         (exception)->severity,(exception)->description) : "", \
126         (exception)->description ? ")" : ""); \
127       if ((perl_exception) != (SV *) NULL) \
128         { \
129           if (SvCUR(perl_exception)) \
130             sv_catpv(perl_exception,"\n"); \
131           sv_catpv(perl_exception,message); \
132         } \
133     } \
134 }
135 
136 #define ThrowPerlException(exception,severity,tag,reason) \
137   (void) ThrowMagickException(exception,GetMagickModule(),severity, \
138     tag,"`%s'",reason); \
139 
140 /*
141   Typedef and structure declarations.
142 */
143 typedef enum
144 {
145   NullReference = 0,
146   ArrayReference = (~0),
147   RealReference = (~0)-1,
148   FileReference = (~0)-2,
149   ImageReference = (~0)-3,
150   IntegerReference = (~0)-4,
151   StringReference = (~0)-5
152 } MagickReference;
153 
154 typedef struct _Arguments
155 {
156   const char
157     *method;
158 
159   ssize_t
160     type;
161 } Arguments;
162 
163 struct ArgumentList
164 {
165   ssize_t
166     integer_reference;
167 
168   double
169     real_reference;
170 
171   const char
172     *string_reference;
173 
174   Image
175     *image_reference;
176 
177   SV
178     *array_reference;
179 
180   FILE
181     *file_reference;
182 
183   size_t
184     length;
185 };
186 
187 struct PackageInfo
188 {
189   ImageInfo
190     *image_info;
191 };
192 
193 typedef void
194   *Image__Magick;  /* data type for the Image::Magick package */
195 
196 /*
197   Static declarations.
198 */
199 static struct
200   Methods
201   {
202     const char
203       *name;
204 
205     Arguments
206       arguments[MaxArguments];
207   } Methods[] =
208   {
209     { "Comment", { {"comment", StringReference} } },
210     { "Label", { {"label", StringReference} } },
211     { "AddNoise", { {"noise", MagickNoiseOptions}, {"attenuate", RealReference},
212       {"channel", MagickChannelOptions} } },
213     { "Colorize", { {"fill", StringReference}, {"blend", StringReference} } },
214     { "Border", { {"geometry", StringReference}, {"width", IntegerReference},
215       {"height", IntegerReference}, {"fill", StringReference},
216       {"bordercolor", StringReference}, {"color", StringReference},
217       {"compose", MagickComposeOptions} } },
218     { "Blur", { {"geometry", StringReference}, {"radius", RealReference},
219       {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
220     { "Chop", { {"geometry", StringReference}, {"width", IntegerReference},
221       {"height", IntegerReference}, {"x", IntegerReference},
222       {"y", IntegerReference}, {"gravity", MagickGravityOptions} } },
223     { "Crop", { {"geometry", StringReference}, {"width", IntegerReference},
224       {"height", IntegerReference}, {"x", IntegerReference},
225       {"y", IntegerReference}, {"fuzz", StringReference},
226       {"gravity", MagickGravityOptions} } },
227     { "Despeckle", { { (const char *) NULL, NullReference } } },
228     { "Edge", { {"radius", RealReference} } },
229     { "Emboss", { {"geometry", StringReference}, {"radius", RealReference},
230       {"sigma", RealReference} } },
231     { "Enhance", { { (const char *) NULL, NullReference } } },
232     { "Flip", { { (const char *) NULL, NullReference } } },
233     { "Flop", { { (const char *) NULL, NullReference } } },
234     { "Frame", { {"geometry", StringReference}, {"width", IntegerReference},
235       {"height", IntegerReference}, {"inner", IntegerReference},
236       {"outer", IntegerReference}, {"fill", StringReference},
237       {"color", StringReference}, {"compose", MagickComposeOptions} } },
238     { "Implode", { {"amount", RealReference},
239       {"interpolate", MagickInterpolateOptions} } },
240     { "Magnify", { { (const char *) NULL, NullReference } } },
241     { "MedianFilter", { {"geometry", StringReference},
242       {"width", IntegerReference}, {"height", IntegerReference},
243       {"channel", MagickChannelOptions} } },
244     { "Minify", { { (const char *) NULL, NullReference } } },
245     { "OilPaint", { {"radius", RealReference}, {"sigma", RealReference} } },
246     { "ReduceNoise", { {"geometry", StringReference},
247       {"width", IntegerReference},{"height", IntegerReference},
248       {"channel", MagickChannelOptions} } },
249     { "Roll", { {"geometry", StringReference}, {"x", IntegerReference},
250       {"y", IntegerReference} } },
251     { "Rotate", { {"degrees", RealReference},
252       {"background", StringReference} } },
253     { "Sample", { {"geometry", StringReference}, {"width", IntegerReference},
254       {"height", IntegerReference} } },
255     { "Scale", { {"geometry", StringReference}, {"width", IntegerReference},
256       {"height", IntegerReference} } },
257     { "Shade", { {"geometry", StringReference}, {"azimuth", RealReference},
258       {"elevation", RealReference}, {"gray", MagickBooleanOptions} } },
259     { "Sharpen", { {"geometry", StringReference}, {"radius", RealReference},
260       {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
261     { "Shear", { {"geometry", StringReference}, {"x", RealReference},
262       {"y", RealReference}, { "fill", StringReference},
263       {"color", StringReference} } },
264     { "Spread", { {"radius", RealReference},
265       {"interpolate", MagickInterpolateOptions} } },
266     { "Swirl", { {"degrees", RealReference},
267       {"interpolate", MagickInterpolateOptions} } },
268     { "Resize", { {"geometry", StringReference}, {"width", IntegerReference},
269       {"height", IntegerReference}, {"filter", MagickFilterOptions},
270       {"support", StringReference } } },
271     { "Zoom", { {"geometry", StringReference}, {"width", IntegerReference},
272       {"height", IntegerReference}, {"filter", MagickFilterOptions},
273       {"support", RealReference } } },
274     { "Annotate", { {"text", StringReference}, {"font", StringReference},
275       {"pointsize", RealReference}, {"density", StringReference},
276       {"undercolor", StringReference}, {"stroke", StringReference},
277       {"fill", StringReference}, {"geometry", StringReference},
278       {"sans", StringReference}, {"x", RealReference},
279       {"y", RealReference}, {"gravity", MagickGravityOptions},
280       {"translate", StringReference}, {"scale", StringReference},
281       {"rotate", RealReference}, {"skewX", RealReference},
282       {"skewY", RealReference}, {"strokewidth", RealReference},
283       {"antialias", MagickBooleanOptions}, {"family", StringReference},
284       {"style", MagickStyleOptions}, {"stretch", MagickStretchOptions},
285       {"weight", IntegerReference}, {"align", MagickAlignOptions},
286       {"encoding", StringReference}, {"affine", ArrayReference},
287       {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
288       {"tile", ImageReference}, {"kerning", RealReference},
289       {"interline-spacing", RealReference},
290       {"interword-spacing", RealReference},
291       {"direction", MagickDirectionOptions},
292       {"decorate", MagickDecorateOptions} } },
293     { "ColorFloodfill", { {"geometry", StringReference},
294       {"x", IntegerReference}, {"y", IntegerReference},
295       {"fill", StringReference}, {"bordercolor", StringReference},
296       {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
297     { "Composite", { {"image", ImageReference},
298       {"compose", MagickComposeOptions}, {"geometry", StringReference},
299       {"x", IntegerReference}, {"y", IntegerReference},
300       {"gravity", MagickGravityOptions}, {"opacity", StringReference},
301       {"tile", MagickBooleanOptions}, {"rotate", RealReference},
302       {"color", StringReference}, {"mask", ImageReference},
303       {"channel", MagickChannelOptions},
304       {"interpolate", MagickInterpolateOptions}, {"args", StringReference},
305       {"blend", StringReference}, {"clip-to-self", MagickBooleanOptions} } },
306     { "Contrast", { {"sharpen", MagickBooleanOptions} } },
307     { "CycleColormap", { {"display", IntegerReference} } },
308     { "Draw", { {"primitive", MagickPrimitiveOptions},
309       {"points", StringReference}, {"method", MagickMethodOptions},
310       {"stroke", StringReference}, {"fill", StringReference},
311       {"strokewidth", RealReference}, {"font", StringReference},
312       {"bordercolor", StringReference}, {"x", RealReference},
313       {"y", RealReference}, {"translate", StringReference},
314       {"scale", StringReference}, {"rotate", RealReference},
315       {"skewX", RealReference}, {"skewY", RealReference},
316       {"tile", ImageReference}, {"pointsize", RealReference},
317       {"antialias", MagickBooleanOptions}, {"density", StringReference},
318       {"linewidth", RealReference}, {"affine", ArrayReference},
319       {"stroke-dashoffset", RealReference},
320       {"stroke-dasharray", ArrayReference},
321       {"interpolate", MagickInterpolateOptions},
322       {"origin", StringReference}, {"text", StringReference},
323       {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
324       {"vector-graphics", StringReference}, {"kerning", RealReference},
325       {"interline-spacing", RealReference},
326       {"interword-spacing", RealReference},
327       {"direction", MagickDirectionOptions} } },
328     { "Equalize", { {"channel", MagickChannelOptions} } },
329     { "Gamma", { {"gamma", StringReference}, {"channel", MagickChannelOptions},
330       {"red", RealReference}, {"green", RealReference},
331       {"blue", RealReference} } },
332     { "Map", { {"image", ImageReference},
333       {"dither-method", MagickDitherOptions} } },
334     { "MatteFloodfill", { {"geometry", StringReference},
335       {"x", IntegerReference}, {"y", IntegerReference},
336       {"opacity", StringReference}, {"bordercolor", StringReference},
337       {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
338     { "Modulate", { {"factor", StringReference}, {"hue", RealReference},
339       {"saturation", RealReference}, {"whiteness", RealReference},
340       {"brightness", RealReference}, {"lightness", RealReference},
341       {"blackness", RealReference} } },
342     { "Negate", { {"gray", MagickBooleanOptions},
343       {"channel", MagickChannelOptions} } },
344     { "Normalize", { {"channel", MagickChannelOptions} } },
345     { "NumberColors", { { (const char *) NULL, NullReference } } },
346     { "Opaque", { {"color", StringReference}, {"fill", StringReference},
347       {"fuzz", StringReference}, {"channel", MagickChannelOptions},
348       {"invert", MagickBooleanOptions} } },
349     { "Quantize", { {"colors", IntegerReference},
350       {"treedepth", IntegerReference}, {"colorspace", MagickColorspaceOptions},
351       {"dither", MagickDitherOptions}, {"measure", MagickBooleanOptions},
352       {"global", MagickBooleanOptions}, {"transparent-color", StringReference},
353       {"dither-method", MagickDitherOptions} } },
354     { "Raise", { {"geometry", StringReference}, {"width", IntegerReference},
355       {"height", IntegerReference}, {"raise", MagickBooleanOptions} } },
356     { "Segment", { {"geometry", StringReference},
357       {"cluster-threshold", RealReference},
358       {"smoothing-threshold", RealReference},
359       {"colorspace", MagickColorspaceOptions},
360       {"verbose", MagickBooleanOptions} } },
361     { "Signature", { { (const char *) NULL, NullReference } } },
362     { "Solarize", { {"geometry", StringReference},
363       {"threshold", StringReference} } },
364     { "Sync", { { (const char *) NULL, NullReference } } },
365     { "Texture", { {"texture", ImageReference} } },
366     { "Evaluate", { {"value", RealReference},
367       {"operator", MagickEvaluateOptions},
368       {"channel", MagickChannelOptions} } },
369     { "Transparent", { {"color", StringReference}, {"opacity", StringReference},
370       {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
371     { "Threshold", { {"threshold", StringReference},
372       {"channel", MagickChannelOptions} } },
373     { "Charcoal", { {"geometry", StringReference}, {"radius", RealReference},
374       {"sigma", RealReference} } },
375     { "Trim", { {"fuzz", StringReference} } },
376     { "Wave", { {"geometry", StringReference}, {"amplitude", RealReference},
377       {"wavelength", RealReference},
378       {"interpolate", MagickInterpolateOptions} } },
379     { "Separate", { {"channel", MagickChannelOptions} } },
380     { "Condense", { { (const char *) NULL, NullReference } } },
381     { "Stereo", { {"image", ImageReference}, {"x", IntegerReference},
382       {"y", IntegerReference} } },
383     { "Stegano", { {"image", ImageReference}, {"offset", IntegerReference} } },
384     { "Deconstruct", { { (const char *) NULL, NullReference } } },
385     { "GaussianBlur", { {"geometry", StringReference},
386       {"radius", RealReference}, {"sigma", RealReference},
387       {"channel", MagickChannelOptions} } },
388     { "Convolve", { {"coefficients", ArrayReference},
389       {"channel", MagickChannelOptions}, {"bias", StringReference},
390       {"kernel", StringReference} } },
391     { "Profile", { {"name", StringReference}, {"profile", StringReference},
392       { "rendering-intent", MagickIntentOptions},
393       { "black-point-compensation", MagickBooleanOptions} } },
394     { "UnsharpMask", { {"geometry", StringReference},
395       {"radius", RealReference}, {"sigma", RealReference},
396       {"gain", RealReference}, {"threshold", RealReference},
397       {"channel", MagickChannelOptions} } },
398     { "MotionBlur", { {"geometry", StringReference},
399       {"radius", RealReference}, {"sigma", RealReference},
400       {"angle", RealReference}, {"channel", MagickChannelOptions} } },
401     { "OrderedDither", { {"threshold", StringReference},
402       {"channel", MagickChannelOptions} } },
403     { "Shave", { {"geometry", StringReference}, {"width", IntegerReference},
404       {"height", IntegerReference} } },
405     { "Level", { {"levels", StringReference}, {"black-point", RealReference},
406       {"white-point", RealReference}, {"gamma", RealReference},
407       {"channel", MagickChannelOptions}, {"level", StringReference} } },
408     { "Clip", { {"id", StringReference}, {"inside", MagickBooleanOptions} } },
409     { "AffineTransform", { {"affine", ArrayReference},
410       {"translate", StringReference}, {"scale", StringReference},
411       {"rotate", RealReference}, {"skewX", RealReference},
412       {"skewY", RealReference}, {"interpolate", MagickInterpolateOptions},
413       {"background", StringReference} } },
414     { "Difference", { {"image", ImageReference}, {"fuzz", StringReference} } },
415     { "AdaptiveThreshold", { {"geometry", StringReference},
416       {"width", IntegerReference}, {"height", IntegerReference},
417       {"bias", RealReference} } },
418     { "Resample", { {"density", StringReference}, {"x", RealReference},
419       {"y", RealReference}, {"filter", MagickFilterOptions},
420       {"support", RealReference } } },
421     { "Describe", { {"file", FileReference} } },
422     { "BlackThreshold", { {"threshold", StringReference},
423       {"channel", MagickChannelOptions} } },
424     { "WhiteThreshold", { {"threshold", StringReference},
425       {"channel", MagickChannelOptions} } },
426     { "RotationalBlur", { {"geometry", StringReference},
427       {"angle", RealReference}, {"channel", MagickChannelOptions} } },
428     { "Thumbnail", { {"geometry", StringReference}, {"width", IntegerReference},
429       {"height", IntegerReference} } },
430     { "Strip", { { (const char *) NULL, NullReference } } },
431     { "Tint", { {"fill", StringReference}, {"blend", StringReference} } },
432     { "Channel", { {"channel", MagickChannelOptions} } },
433     { "Splice", { {"geometry", StringReference}, {"width", IntegerReference},
434       {"height", IntegerReference}, {"x", IntegerReference},
435       {"y", IntegerReference}, {"fuzz", StringReference},
436       {"background", StringReference}, {"gravity", MagickGravityOptions} } },
437     { "Posterize", { {"levels", IntegerReference},
438       {"dither", MagickBooleanOptions} } },
439     { "Shadow", { {"geometry", StringReference}, {"alpha", RealReference},
440       {"sigma", RealReference}, {"x", IntegerReference},
441       {"y", IntegerReference} } },
442     { "Identify", { {"file", FileReference}, {"features", StringReference},
443       {"unique", MagickBooleanOptions} } },
444     { "SepiaTone", { {"threshold", RealReference} } },
445     { "SigmoidalContrast", { {"geometry", StringReference},
446       {"contrast", RealReference}, {"mid-point", RealReference},
447       {"channel", MagickChannelOptions}, {"sharpen", MagickBooleanOptions} } },
448     { "Extent", { {"geometry", StringReference}, {"width", IntegerReference},
449       {"height", IntegerReference}, {"x", IntegerReference},
450       {"y", IntegerReference}, {"fuzz", StringReference},
451       {"background", StringReference}, {"gravity", MagickGravityOptions} } },
452     { "Vignette", { {"geometry", StringReference}, {"radius", RealReference},
453       {"sigma", RealReference}, {"x", IntegerReference},
454       {"y", IntegerReference}, {"background", StringReference} } },
455     { "ContrastStretch", { {"levels", StringReference},
456       {"black-point", RealReference},{"white-point", RealReference},
457       {"channel", MagickChannelOptions} } },
458     { "Sans0", { { (const char *) NULL, NullReference } } },
459     { "Sans1", { { (const char *) NULL, NullReference } } },
460     { "AdaptiveSharpen", { {"geometry", StringReference},
461       {"radius", RealReference}, {"sigma", RealReference},
462       {"bias", RealReference}, {"channel", MagickChannelOptions} } },
463     { "Transpose", { { (const char *) NULL, NullReference } } },
464     { "Transverse", { { (const char *) NULL, NullReference } } },
465     { "AutoOrient", { { (const char *) NULL, NullReference } } },
466     { "AdaptiveBlur", { {"geometry", StringReference},
467       {"radius", RealReference}, {"sigma", RealReference},
468       {"channel", MagickChannelOptions} } },
469     { "Sketch", { {"geometry", StringReference},
470       {"radius", RealReference}, {"sigma", RealReference},
471       {"angle", RealReference} } },
472     { "UniqueColors", { { (const char *) NULL, NullReference } } },
473     { "AdaptiveResize", { {"geometry", StringReference},
474       {"width", IntegerReference}, {"height", IntegerReference},
475       {"filter", MagickFilterOptions}, {"support", StringReference },
476       {"blur", RealReference } } },
477     { "ClipMask", { {"mask", ImageReference} } },
478     { "LinearStretch", { {"levels", StringReference},
479       {"black-point", RealReference},{"white-point", RealReference} } },
480     { "ColorMatrix", { {"matrix", ArrayReference} } },
481     { "Mask", { {"mask", ImageReference} } },
482     { "Polaroid", { {"caption", StringReference}, {"angle", RealReference},
483       {"font", StringReference}, {"stroke", StringReference},
484       {"fill", StringReference}, {"strokewidth", RealReference},
485       {"pointsize", RealReference}, {"gravity", MagickGravityOptions},
486       {"background", StringReference},
487       {"interpolate", MagickInterpolateOptions} } },
488     { "FloodfillPaint", { {"geometry", StringReference},
489       {"x", IntegerReference}, {"y", IntegerReference},
490       {"fill", StringReference}, {"bordercolor", StringReference},
491       {"fuzz", StringReference}, {"channel", MagickChannelOptions},
492       {"invert", MagickBooleanOptions} } },
493     { "Distort", { {"points", ArrayReference}, {"method", MagickDistortOptions},
494       {"virtual-pixel", MagickVirtualPixelOptions},
495       {"best-fit", MagickBooleanOptions} } },
496     { "Clut", { {"image", ImageReference},
497       {"interpolate", MagickInterpolateOptions},
498       {"channel", MagickChannelOptions} } },
499     { "LiquidRescale", { {"geometry", StringReference},
500       {"width", IntegerReference}, {"height", IntegerReference},
501       {"delta-x", RealReference}, {"rigidity", RealReference } } },
502     { "Encipher", { {"passphrase", StringReference} } },
503     { "Decipher", { {"passphrase", StringReference} } },
504     { "Deskew", { {"geometry", StringReference},
505       {"threshold", StringReference} } },
506     { "Remap", { {"image", ImageReference},
507       {"dither-method", MagickDitherOptions} } },
508     { "SparseColor", { {"points", ArrayReference},
509       {"method", MagickSparseColorOptions},
510       {"virtual-pixel", MagickVirtualPixelOptions},
511       {"channel", MagickChannelOptions} } },
512     { "Function", { {"parameters", ArrayReference},
513       {"function", MagickFunctionOptions},
514       {"virtual-pixel", MagickVirtualPixelOptions} } },
515     { "SelectiveBlur", { {"geometry", StringReference},
516       {"radius", RealReference}, {"sigma", RealReference},
517       {"threshold", RealReference}, {"channel", MagickChannelOptions} } },
518     { "HaldClut", { {"image", ImageReference},
519       {"channel", MagickChannelOptions} } },
520     { "BlueShift", { {"factor", StringReference} } },
521     { "ForwardFourierTransform", { {"magnitude", MagickBooleanOptions} } },
522     { "InverseFourierTransform", { {"magnitude", MagickBooleanOptions} } },
523     { "ColorDecisionList", {
524       {"color-correction-collection", StringReference} } },
525     { "AutoGamma", { {"channel", MagickChannelOptions} } },
526     { "AutoLevel", { {"channel", MagickChannelOptions} } },
527     { "LevelColors", { {"invert", MagickBooleanOptions},
528       {"black-point", StringReference}, {"white-point", StringReference},
529       {"channel", MagickChannelOptions}, {"invert", MagickBooleanOptions} } },
530     { "Clamp", { {"channel", MagickChannelOptions} } },
531     { "BrightnessContrast", { {"levels", StringReference},
532       {"brightness", RealReference},{"contrast", RealReference},
533       {"channel", MagickChannelOptions} } },
534     { "Morphology", { {"kernel", StringReference},
535       {"channel", MagickChannelOptions}, {"method", MagickMorphologyOptions},
536       {"iterations", IntegerReference} } },
537     { "Mode", { {"geometry", StringReference},
538       {"width", IntegerReference},{"height", IntegerReference},
539       {"channel", MagickChannelOptions} } },
540     { "Statistic", { {"geometry", StringReference},
541       {"width", IntegerReference},{"height", IntegerReference},
542       {"channel", MagickChannelOptions}, {"type", MagickStatisticOptions} } },
543     { "Perceptible", { {"epsilon", RealReference},
544       {"channel", MagickChannelOptions} } },
545     { "Poly", { {"terms", ArrayReference},
546       {"channel", MagickChannelOptions} } },
547     { "Grayscale", { {"method", MagickNoiseOptions} } },
548     { "CannyEdge", { {"geometry", StringReference},
549       {"radius", RealReference}, {"sigma", RealReference},
550       {"lower-percent", RealReference}, {"upper-percent", RealReference} } },
551     { "HoughLine", { {"geometry", StringReference},
552       {"width", IntegerReference}, {"height", IntegerReference},
553       {"threshold", IntegerReference} } },
554     { "MeanShift", { {"geometry", StringReference},
555       {"width", IntegerReference}, {"height", IntegerReference},
556       {"distance", RealReference} } },
557     { "Kuwahara", { {"geometry", StringReference}, {"radius", RealReference},
558       {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
559     { "ConnectedComponents", { {"connectivity", IntegerReference} } },
560     { "CopyPixels", { {"image", ImageReference}, {"geometry", StringReference},
561       {"width", IntegerReference}, {"height", IntegerReference},
562       {"x", IntegerReference}, {"y", IntegerReference},
563       {"gravity", MagickGravityOptions}, {"offset", StringReference},
564       {"dx", IntegerReference}, {"dy", IntegerReference} } },
565     { "Color", { {"color", StringReference} } },
566     { "WaveletDenoise", {  {"geometry", StringReference},
567       {"threshold", RealReference}, {"softness", RealReference},
568       {"channel", MagickChannelOptions} } },
569     { "Colorspace", { {"colorspace", MagickColorspaceOptions} } },
570     { "AutoThreshold", { {"method", MagickAutoThresholdOptions} } },
571     { "RangeThreshold", { {"geometry", StringReference},
572       {"low-black", RealReference}, {"low-white", RealReference},
573       {"high-white", RealReference}, {"high-black", RealReference},
574       {"channel", MagickChannelOptions} } },
575     { "CLAHE", { {"geometry", StringReference}, {"width", IntegerReference},
576       {"height", IntegerReference}, {"number-bins", IntegerReference},
577       {"clip-limit", RealReference} } },
578     { "Kmeans", { {"geometry", StringReference}, {"colors", IntegerReference},
579       {"iterations", IntegerReference}, {"tolerance", RealReference} } },
580   };
581 
582 static SplayTreeInfo
583   *magick_registry = (SplayTreeInfo *) NULL;
584 
585 /*
586   Forward declarations.
587 */
588 static Image
589   *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
590 
591 static ssize_t
592   strEQcase(const char *,const char *);
593 
594 /*
595 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
596 %                                                                             %
597 %                                                                             %
598 %                                                                             %
599 %   C l o n e P a c k a g e I n f o                                           %
600 %                                                                             %
601 %                                                                             %
602 %                                                                             %
603 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
604 %
605 %  ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
606 %  a new one.
607 %
608 %  The format of the ClonePackageInfo routine is:
609 %
610 %      struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
611 %        exception)
612 %
613 %  A description of each parameter follows:
614 %
615 %    o info: a structure of type info.
616 %
617 %    o exception: Return any errors or warnings in this structure.
618 %
619 */
ClonePackageInfo(struct PackageInfo * info,ExceptionInfo * exception)620 static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
621   ExceptionInfo *exception)
622 {
623   struct PackageInfo
624     *clone_info;
625 
626   clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
627   if (clone_info == (struct PackageInfo *) NULL)
628     {
629       ThrowPerlException(exception,ResourceLimitError,
630         "UnableToClonePackageInfo",PackageName);
631       return((struct PackageInfo *) NULL);
632     }
633   if (info == (struct PackageInfo *) NULL)
634     {
635       clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
636       return(clone_info);
637     }
638   *clone_info=(*info);
639   clone_info->image_info=CloneImageInfo(info->image_info);
640   return(clone_info);
641 }
642 
643 /*
644 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
645 %                                                                             %
646 %                                                                             %
647 %                                                                             %
648 %   c o n s t a n t                                                           %
649 %                                                                             %
650 %                                                                             %
651 %                                                                             %
652 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
653 %
654 %  constant() returns a double value for the specified name.
655 %
656 %  The format of the constant routine is:
657 %
658 %      double constant(char *name,ssize_t sans)
659 %
660 %  A description of each parameter follows:
661 %
662 %    o value: Method constant returns a double value for the specified name.
663 %
664 %    o name: The name of the constant.
665 %
666 %    o sans: This integer value is not used.
667 %
668 */
constant(char * name,ssize_t sans)669 static double constant(char *name,ssize_t sans)
670 {
671   (void) sans;
672   errno=0;
673   switch (*name)
674   {
675     case 'B':
676     {
677       if (strEQ(name,"BlobError"))
678         return(BlobError);
679       if (strEQ(name,"BlobWarning"))
680         return(BlobWarning);
681       break;
682     }
683     case 'C':
684     {
685       if (strEQ(name,"CacheError"))
686         return(CacheError);
687       if (strEQ(name,"CacheWarning"))
688         return(CacheWarning);
689       if (strEQ(name,"CoderError"))
690         return(CoderError);
691       if (strEQ(name,"CoderWarning"))
692         return(CoderWarning);
693       if (strEQ(name,"ConfigureError"))
694         return(ConfigureError);
695       if (strEQ(name,"ConfigureWarning"))
696         return(ConfigureWarning);
697       if (strEQ(name,"CorruptImageError"))
698         return(CorruptImageError);
699       if (strEQ(name,"CorruptImageWarning"))
700         return(CorruptImageWarning);
701       break;
702     }
703     case 'D':
704     {
705       if (strEQ(name,"DelegateError"))
706         return(DelegateError);
707       if (strEQ(name,"DelegateWarning"))
708         return(DelegateWarning);
709       if (strEQ(name,"DrawError"))
710         return(DrawError);
711       if (strEQ(name,"DrawWarning"))
712         return(DrawWarning);
713       break;
714     }
715     case 'E':
716     {
717       if (strEQ(name,"ErrorException"))
718         return(ErrorException);
719       if (strEQ(name,"ExceptionError"))
720         return(CoderError);
721       if (strEQ(name,"ExceptionWarning"))
722         return(CoderWarning);
723       break;
724     }
725     case 'F':
726     {
727       if (strEQ(name,"FatalErrorException"))
728         return(FatalErrorException);
729       if (strEQ(name,"FileOpenError"))
730         return(FileOpenError);
731       if (strEQ(name,"FileOpenWarning"))
732         return(FileOpenWarning);
733       break;
734     }
735     case 'I':
736     {
737       if (strEQ(name,"ImageError"))
738         return(ImageError);
739       if (strEQ(name,"ImageWarning"))
740         return(ImageWarning);
741       break;
742     }
743     case 'M':
744     {
745       if (strEQ(name,"MaxRGB"))
746         return(QuantumRange);
747       if (strEQ(name,"MissingDelegateError"))
748         return(MissingDelegateError);
749       if (strEQ(name,"MissingDelegateWarning"))
750         return(MissingDelegateWarning);
751       if (strEQ(name,"ModuleError"))
752         return(ModuleError);
753       if (strEQ(name,"ModuleWarning"))
754         return(ModuleWarning);
755       break;
756     }
757     case 'O':
758     {
759       if (strEQ(name,"Opaque"))
760         return(OpaqueAlpha);
761       if (strEQ(name,"OptionError"))
762         return(OptionError);
763       if (strEQ(name,"OptionWarning"))
764         return(OptionWarning);
765       break;
766     }
767     case 'Q':
768     {
769       if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
770         return(MAGICKCORE_QUANTUM_DEPTH);
771       if (strEQ(name,"QuantumDepth"))
772         return(MAGICKCORE_QUANTUM_DEPTH);
773       if (strEQ(name,"QuantumRange"))
774         return(QuantumRange);
775       break;
776     }
777     case 'R':
778     {
779       if (strEQ(name,"ResourceLimitError"))
780         return(ResourceLimitError);
781       if (strEQ(name,"ResourceLimitWarning"))
782         return(ResourceLimitWarning);
783       if (strEQ(name,"RegistryError"))
784         return(RegistryError);
785       if (strEQ(name,"RegistryWarning"))
786         return(RegistryWarning);
787       break;
788     }
789     case 'S':
790     {
791       if (strEQ(name,"StreamError"))
792         return(StreamError);
793       if (strEQ(name,"StreamWarning"))
794         return(StreamWarning);
795       if (strEQ(name,"Success"))
796         return(0);
797       break;
798     }
799     case 'T':
800     {
801       if (strEQ(name,"Transparent"))
802         return(TransparentAlpha);
803       if (strEQ(name,"TypeError"))
804         return(TypeError);
805       if (strEQ(name,"TypeWarning"))
806         return(TypeWarning);
807       break;
808     }
809     case 'W':
810     {
811       if (strEQ(name,"WarningException"))
812         return(WarningException);
813       break;
814     }
815     case 'X':
816     {
817       if (strEQ(name,"XServerError"))
818         return(XServerError);
819       if (strEQ(name,"XServerWarning"))
820         return(XServerWarning);
821       break;
822     }
823   }
824   errno=EINVAL;
825   return(0);
826 }
827 
828 /*
829 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
830 %                                                                             %
831 %                                                                             %
832 %                                                                             %
833 %   D e s t r o y P a c k a g e I n f o                                       %
834 %                                                                             %
835 %                                                                             %
836 %                                                                             %
837 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
838 %
839 %  Method DestroyPackageInfo frees a previously created info structure.
840 %
841 %  The format of the DestroyPackageInfo routine is:
842 %
843 %      DestroyPackageInfo(struct PackageInfo *info)
844 %
845 %  A description of each parameter follows:
846 %
847 %    o info: a structure of type info.
848 %
849 */
DestroyPackageInfo(struct PackageInfo * info)850 static void DestroyPackageInfo(struct PackageInfo *info)
851 {
852   info->image_info=DestroyImageInfo(info->image_info);
853   info=(struct PackageInfo *) RelinquishMagickMemory(info);
854 }
855 
856 /*
857 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
858 %                                                                             %
859 %                                                                             %
860 %                                                                             %
861 %   G e t L i s t                                                             %
862 %                                                                             %
863 %                                                                             %
864 %                                                                             %
865 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
866 %
867 %  Method GetList is recursively called by SetupList to traverse the
868 %  Image__Magick reference.  If building an reference_vector (see SetupList),
869 %  *current is the current position in *reference_vector and *last is the final
870 %  entry in *reference_vector.
871 %
872 %  The format of the GetList routine is:
873 %
874 %      GetList(info)
875 %
876 %  A description of each parameter follows:
877 %
878 %    o info: a structure of type info.
879 %
880 */
GetList(pTHX_ SV * reference,SV *** reference_vector,ssize_t * current,ssize_t * last,ExceptionInfo * exception)881 static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
882   ssize_t *current,ssize_t *last,ExceptionInfo *exception)
883 {
884   Image
885     *image;
886 
887   if (reference == (SV *) NULL)
888     return(NULL);
889   switch (SvTYPE(reference))
890   {
891     case SVt_PVAV:
892     {
893       AV
894         *av;
895 
896       Image
897         *head,
898         *previous;
899 
900       register ssize_t
901         i;
902 
903       ssize_t
904         n;
905 
906       /*
907         Array of images.
908       */
909       previous=(Image *) NULL;
910       head=(Image *) NULL;
911       av=(AV *) reference;
912       n=av_len(av);
913       for (i=0; i <= n; i++)
914       {
915         SV
916           **rv;
917 
918         rv=av_fetch(av,i,0);
919         if (rv && *rv && sv_isobject(*rv))
920           {
921             image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
922               exception);
923             if (image == (Image *) NULL)
924               continue;
925             if (image == previous)
926               {
927                 image=CloneImage(image,0,0,MagickTrue,exception);
928                 if (image == (Image *) NULL)
929                   return(NULL);
930               }
931             image->previous=previous;
932             *(previous ? &previous->next : &head)=image;
933             for (previous=image; previous->next; previous=previous->next) ;
934           }
935       }
936       return(head);
937     }
938     case SVt_PVMG:
939     {
940       /*
941         Blessed scalar, one image.
942       */
943       image=INT2PTR(Image *,SvIV(reference));
944       if (image == (Image *) NULL)
945         return(NULL);
946       image->previous=(Image *) NULL;
947       image->next=(Image *) NULL;
948       if (reference_vector)
949         {
950           if (*current == *last)
951             {
952               *last+=256;
953               if (*reference_vector == (SV **) NULL)
954                 *reference_vector=(SV **) AcquireQuantumMemory(*last,
955                   sizeof(*reference_vector));
956               else
957                 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
958                   *last,sizeof(*reference_vector));
959             }
960           if (*reference_vector == (SV **) NULL)
961             {
962               ThrowPerlException(exception,ResourceLimitError,
963                 "MemoryAllocationFailed",PackageName);
964               return((Image *) NULL);
965             }
966           (*reference_vector)[*current]=reference;
967           (*reference_vector)[++(*current)]=NULL;
968         }
969       return(image);
970     }
971     default:
972       break;
973   }
974   (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
975     (double) SvTYPE(reference));
976   return((Image *) NULL);
977 }
978 
979 /*
980 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
981 %                                                                             %
982 %                                                                             %
983 %                                                                             %
984 %   G e t P a c k a g e I n f o                                               %
985 %                                                                             %
986 %                                                                             %
987 %                                                                             %
988 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
989 %
990 %  Method GetPackageInfo looks up or creates an info structure for the given
991 %  Image__Magick reference.  If it does create a new one, the information in
992 %  package_info is used to initialize it.
993 %
994 %  The format of the GetPackageInfo routine is:
995 %
996 %      struct PackageInfo *GetPackageInfo(void *reference,
997 %        struct PackageInfo *package_info,ExceptionInfo *exception)
998 %
999 %  A description of each parameter follows:
1000 %
1001 %    o info: a structure of type info.
1002 %
1003 %    o exception: Return any errors or warnings in this structure.
1004 %
1005 */
GetPackageInfo(pTHX_ void * reference,struct PackageInfo * package_info,ExceptionInfo * exception)1006 static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
1007   struct PackageInfo *package_info,ExceptionInfo *exception)
1008 {
1009   char
1010     message[MagickPathExtent];
1011 
1012   struct PackageInfo
1013     *clone_info;
1014 
1015   SV
1016     *sv;
1017 
1018   (void) FormatLocaleString(message,MagickPathExtent,"%s::package%s%p",
1019     PackageName,XS_VERSION,reference);
1020   sv=perl_get_sv(message,(TRUE | 0x02));
1021   if (sv == (SV *) NULL)
1022     {
1023       ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
1024         message);
1025       return(package_info);
1026     }
1027   if (SvREFCNT(sv) == 0)
1028     (void) SvREFCNT_inc(sv);
1029   if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
1030     return(clone_info);
1031   clone_info=ClonePackageInfo(package_info,exception);
1032   sv_setiv(sv,PTR2IV(clone_info));
1033   return(clone_info);
1034 }
1035 
1036 /*
1037 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1038 %                                                                             %
1039 %                                                                             %
1040 %                                                                             %
1041 %   S e t A t t r i b u t e                                                   %
1042 %                                                                             %
1043 %                                                                             %
1044 %                                                                             %
1045 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1046 %
1047 %  SetAttribute() sets the attribute to the value in sval.  This can change
1048 %  either or both of image or info.
1049 %
1050 %  The format of the SetAttribute routine is:
1051 %
1052 %      SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1053 %        SV *sval,ExceptionInfo *exception)
1054 %
1055 %  A description of each parameter follows:
1056 %
1057 %    o list: a list of strings.
1058 %
1059 %    o string: a character string.
1060 %
1061 */
1062 
SiPrefixToDoubleInterval(const char * string,const double interval)1063 static double SiPrefixToDoubleInterval(const char *string,const double interval)
1064 {
1065   char
1066     *q;
1067 
1068   double
1069     value;
1070 
1071   value=InterpretSiPrefixValue(string,&q);
1072   if (*q == '%')
1073     value*=interval/100.0;
1074   return(value);
1075 }
1076 
StringToDouble(const char * string,char ** sentinal)1077 static inline double StringToDouble(const char *string,char **sentinal)
1078 {
1079   return(InterpretLocaleValue(string,sentinal));
1080 }
1081 
StringToDoubleInterval(const char * string,const double interval)1082 static double StringToDoubleInterval(const char *string,const double interval)
1083 {
1084   char
1085     *q;
1086 
1087   double
1088     value;
1089 
1090   value=InterpretLocaleValue(string,&q);
1091   if (*q == '%')
1092     value*=interval/100.0;
1093   return(value);
1094 }
1095 
StringToLong(const char * value)1096 static inline ssize_t StringToLong(const char *value)
1097 {
1098   return(strtol(value,(char **) NULL,10));
1099 }
1100 
SetAttribute(pTHX_ struct PackageInfo * info,Image * image,const char * attribute,SV * sval,ExceptionInfo * exception)1101 static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1102   const char *attribute,SV *sval,ExceptionInfo *exception)
1103 {
1104   GeometryInfo
1105     geometry_info;
1106 
1107   long
1108     x,
1109     y;
1110 
1111   PixelInfo
1112     pixel;
1113 
1114   MagickStatusType
1115     flags;
1116 
1117   PixelInfo
1118     *color,
1119     target_color;
1120 
1121   ssize_t
1122     sp;
1123 
1124   switch (*attribute)
1125   {
1126     case 'A':
1127     case 'a':
1128     {
1129       if (LocaleCompare(attribute,"adjoin") == 0)
1130         {
1131           sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1132             SvPV(sval,na)) : SvIV(sval);
1133           if (sp < 0)
1134             {
1135               ThrowPerlException(exception,OptionError,"UnrecognizedType",
1136                 SvPV(sval,na));
1137               break;
1138             }
1139           if (info)
1140             info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1141           break;
1142         }
1143       if (LocaleCompare(attribute,"alpha") == 0)
1144         {
1145           sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1146             MagickFalse,SvPV(sval,na)) : SvIV(sval);
1147           if (sp < 0)
1148             {
1149               ThrowPerlException(exception,OptionError,"UnrecognizedType",
1150                 SvPV(sval,na));
1151               break;
1152             }
1153           for ( ; image; image=image->next)
1154             (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1155               exception);
1156           break;
1157         }
1158       if (LocaleCompare(attribute,"antialias") == 0)
1159         {
1160           sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1161             SvPV(sval,na)) : SvIV(sval);
1162           if (sp < 0)
1163             {
1164               ThrowPerlException(exception,OptionError,"UnrecognizedType",
1165                 SvPV(sval,na));
1166               break;
1167             }
1168           if (info)
1169             info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1170           break;
1171         }
1172       if (LocaleCompare(attribute,"area-limit") == 0)
1173         {
1174           MagickSizeType
1175             limit;
1176 
1177           limit=MagickResourceInfinity;
1178           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1179             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1180               100.0);
1181           (void) SetMagickResourceLimit(AreaResource,limit);
1182           break;
1183         }
1184       if (LocaleCompare(attribute,"attenuate") == 0)
1185         {
1186           if (info)
1187             (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1188           break;
1189         }
1190       if (LocaleCompare(attribute,"authenticate") == 0)
1191         {
1192           if (info)
1193             SetImageOption(info->image_info,attribute,SvPV(sval,na));
1194           break;
1195         }
1196       if (info)
1197         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1198       for ( ; image; image=image->next)
1199       {
1200         (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1201         (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1202       }
1203       break;
1204     }
1205     case 'B':
1206     case 'b':
1207     {
1208       if (LocaleCompare(attribute,"background") == 0)
1209         {
1210           (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1211             exception);
1212           if (info)
1213             info->image_info->background_color=target_color;
1214           for ( ; image; image=image->next)
1215             image->background_color=target_color;
1216           break;
1217         }
1218       if (LocaleCompare(attribute,"blue-primary") == 0)
1219         {
1220           for ( ; image; image=image->next)
1221           {
1222             flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1223             image->chromaticity.blue_primary.x=geometry_info.rho;
1224             image->chromaticity.blue_primary.y=geometry_info.sigma;
1225             if ((flags & SigmaValue) == 0)
1226               image->chromaticity.blue_primary.y=
1227                 image->chromaticity.blue_primary.x;
1228           }
1229           break;
1230         }
1231       if (LocaleCompare(attribute,"bordercolor") == 0)
1232         {
1233           (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1234             exception);
1235           if (info)
1236             info->image_info->border_color=target_color;
1237           for ( ; image; image=image->next)
1238             image->border_color=target_color;
1239           break;
1240         }
1241       if (info)
1242         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1243       for ( ; image; image=image->next)
1244       {
1245         (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1246         (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1247       }
1248       break;
1249     }
1250     case 'C':
1251     case 'c':
1252     {
1253       if (LocaleCompare(attribute,"cache-threshold") == 0)
1254         {
1255           (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1256             SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1257           (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1258             (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1259           break;
1260         }
1261       if (LocaleCompare(attribute,"clip-mask") == 0)
1262         {
1263           Image
1264             *clip_mask;
1265 
1266           clip_mask=(Image *) NULL;
1267           if (SvPOK(sval))
1268             clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1269           for ( ; image; image=image->next)
1270             SetImageMask(image,ReadPixelMask,clip_mask,exception);
1271           break;
1272         }
1273       if (LocaleNCompare(attribute,"colormap",8) == 0)
1274         {
1275           for ( ; image; image=image->next)
1276           {
1277             int
1278               items;
1279 
1280             long
1281               i;
1282 
1283             if (image->storage_class == DirectClass)
1284               continue;
1285             i=0;
1286             items=sscanf(attribute,"%*[^[][%ld",&i);
1287             (void) items;
1288             if (i > (ssize_t) image->colors)
1289               i%=image->colors;
1290             if ((strchr(SvPV(sval,na),',') == 0) ||
1291                 (strchr(SvPV(sval,na),')') != 0))
1292               QueryColorCompliance(SvPV(sval,na),AllCompliance,
1293                 image->colormap+i,exception);
1294             else
1295               {
1296                 color=image->colormap+i;
1297                 pixel.red=color->red;
1298                 pixel.green=color->green;
1299                 pixel.blue=color->blue;
1300                 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1301                 pixel.red=geometry_info.rho;
1302                 pixel.green=geometry_info.sigma;
1303                 pixel.blue=geometry_info.xi;
1304                 color->red=ClampToQuantum(pixel.red);
1305                 color->green=ClampToQuantum(pixel.green);
1306                 color->blue=ClampToQuantum(pixel.blue);
1307               }
1308           }
1309           break;
1310         }
1311       if (LocaleCompare(attribute,"colorspace") == 0)
1312         {
1313           sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1314             MagickFalse,SvPV(sval,na)) : SvIV(sval);
1315           if (sp < 0)
1316             {
1317               ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1318                 SvPV(sval,na));
1319               break;
1320             }
1321           for ( ; image; image=image->next)
1322             (void) SetImageColorspace(image,(ColorspaceType) sp,exception);
1323           break;
1324         }
1325       if (LocaleCompare(attribute,"comment") == 0)
1326         {
1327           for ( ; image; image=image->next)
1328             (void) SetImageProperty(image,"Comment",InterpretImageProperties(
1329               info ? info->image_info : (ImageInfo *) NULL,image,
1330               SvPV(sval,na),exception),exception);
1331           break;
1332         }
1333       if (LocaleCompare(attribute,"compression") == 0)
1334         {
1335           sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1336             MagickFalse,SvPV(sval,na)) : SvIV(sval);
1337           if (sp < 0)
1338             {
1339               ThrowPerlException(exception,OptionError,
1340                 "UnrecognizedImageCompression",SvPV(sval,na));
1341               break;
1342             }
1343           if (info)
1344             info->image_info->compression=(CompressionType) sp;
1345           for ( ; image; image=image->next)
1346             image->compression=(CompressionType) sp;
1347           break;
1348         }
1349       if (info)
1350         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1351       for ( ; image; image=image->next)
1352       {
1353         (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1354         (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1355       }
1356       break;
1357     }
1358     case 'D':
1359     case 'd':
1360     {
1361       if (LocaleCompare(attribute,"debug") == 0)
1362         {
1363           SetLogEventMask(SvPV(sval,na));
1364           break;
1365         }
1366       if (LocaleCompare(attribute,"delay") == 0)
1367         {
1368           flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1369           for ( ; image; image=image->next)
1370           {
1371             image->delay=(size_t) floor(geometry_info.rho+0.5);
1372             if ((flags & SigmaValue) != 0)
1373               image->ticks_per_second=(ssize_t)
1374                 floor(geometry_info.sigma+0.5);
1375           }
1376           break;
1377         }
1378       if (LocaleCompare(attribute,"disk-limit") == 0)
1379         {
1380           MagickSizeType
1381             limit;
1382 
1383           limit=MagickResourceInfinity;
1384           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1385             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1386               100.0);
1387           (void) SetMagickResourceLimit(DiskResource,limit);
1388           break;
1389         }
1390       if (LocaleCompare(attribute,"density") == 0)
1391         {
1392           if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1393             {
1394               ThrowPerlException(exception,OptionError,"MissingGeometry",
1395                 SvPV(sval,na));
1396               break;
1397             }
1398           if (info)
1399             (void) CloneString(&info->image_info->density,SvPV(sval,na));
1400           for ( ; image; image=image->next)
1401           {
1402             flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1403             image->resolution.x=geometry_info.rho;
1404             image->resolution.y=geometry_info.sigma;
1405             if ((flags & SigmaValue) == 0)
1406               image->resolution.y=image->resolution.x;
1407           }
1408           break;
1409         }
1410       if (LocaleCompare(attribute,"depth") == 0)
1411         {
1412           if (info)
1413             info->image_info->depth=SvIV(sval);
1414           for ( ; image; image=image->next)
1415             (void) SetImageDepth(image,SvIV(sval),exception);
1416           break;
1417         }
1418       if (LocaleCompare(attribute,"dispose") == 0)
1419         {
1420           sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1421             SvPV(sval,na)) : SvIV(sval);
1422           if (sp < 0)
1423             {
1424               ThrowPerlException(exception,OptionError,
1425                 "UnrecognizedDisposeMethod",SvPV(sval,na));
1426               break;
1427             }
1428           for ( ; image; image=image->next)
1429             image->dispose=(DisposeType) sp;
1430           break;
1431         }
1432       if (LocaleCompare(attribute,"dither") == 0)
1433         {
1434           if (info)
1435             {
1436               sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1437                 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1438               if (sp < 0)
1439                 {
1440                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
1441                     SvPV(sval,na));
1442                   break;
1443                 }
1444               info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1445             }
1446           break;
1447         }
1448       if (LocaleCompare(attribute,"display") == 0)
1449         {
1450           display:
1451           if (info)
1452             (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1453           break;
1454         }
1455       if (info)
1456         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1457       for ( ; image; image=image->next)
1458       {
1459         (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1460         (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1461       }
1462       break;
1463     }
1464     case 'E':
1465     case 'e':
1466     {
1467       if (LocaleCompare(attribute,"endian") == 0)
1468         {
1469           sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1470             SvPV(sval,na)) : SvIV(sval);
1471           if (sp < 0)
1472             {
1473               ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1474                 SvPV(sval,na));
1475               break;
1476             }
1477           if (info)
1478             info->image_info->endian=(EndianType) sp;
1479           for ( ; image; image=image->next)
1480             image->endian=(EndianType) sp;
1481           break;
1482         }
1483       if (LocaleCompare(attribute,"extract") == 0)
1484         {
1485           /*
1486             Set image extract geometry.
1487           */
1488           (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1489           break;
1490         }
1491       if (info)
1492         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1493       for ( ; image; image=image->next)
1494       {
1495         (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1496         (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1497       }
1498       break;
1499     }
1500     case 'F':
1501     case 'f':
1502     {
1503       if (LocaleCompare(attribute,"filename") == 0)
1504         {
1505           if (info)
1506             (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
1507               MagickPathExtent);
1508           for ( ; image; image=image->next)
1509             (void) CopyMagickString(image->filename,SvPV(sval,na),
1510               MagickPathExtent);
1511           break;
1512         }
1513       if (LocaleCompare(attribute,"file") == 0)
1514         {
1515           FILE
1516             *file;
1517 
1518           PerlIO
1519             *io_info;
1520 
1521           if (info == (struct PackageInfo *) NULL)
1522             break;
1523           io_info=IoIFP(sv_2io(sval));
1524           if (io_info == (PerlIO *) NULL)
1525             {
1526               ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1527                 PackageName);
1528               break;
1529             }
1530           file=PerlIO_findFILE(io_info);
1531           if (file == (FILE *) NULL)
1532             {
1533               ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1534                 PackageName);
1535               break;
1536             }
1537           SetImageInfoFile(info->image_info,file);
1538           break;
1539         }
1540       if (LocaleCompare(attribute,"fill") == 0)
1541         {
1542           if (info)
1543             (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1544           break;
1545         }
1546       if (LocaleCompare(attribute,"font") == 0)
1547         {
1548           if (info)
1549             (void) CloneString(&info->image_info->font,SvPV(sval,na));
1550           break;
1551         }
1552       if (LocaleCompare(attribute,"foreground") == 0)
1553         break;
1554       if (LocaleCompare(attribute,"fuzz") == 0)
1555         {
1556           if (info)
1557             info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1558               QuantumRange+1.0);
1559           for ( ; image; image=image->next)
1560             image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1561               QuantumRange+1.0);
1562           break;
1563         }
1564       if (info)
1565         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1566       for ( ; image; image=image->next)
1567       {
1568         (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1569         (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1570       }
1571       break;
1572     }
1573     case 'G':
1574     case 'g':
1575     {
1576       if (LocaleCompare(attribute,"gamma") == 0)
1577         {
1578           for ( ; image; image=image->next)
1579             image->gamma=SvNV(sval);
1580           break;
1581         }
1582       if (LocaleCompare(attribute,"gravity") == 0)
1583         {
1584           sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1585             SvPV(sval,na)) : SvIV(sval);
1586           if (sp < 0)
1587             {
1588               ThrowPerlException(exception,OptionError,
1589                 "UnrecognizedGravityType",SvPV(sval,na));
1590               break;
1591             }
1592           if (info)
1593             SetImageOption(info->image_info,attribute,SvPV(sval,na));
1594           for ( ; image; image=image->next)
1595             image->gravity=(GravityType) sp;
1596           break;
1597         }
1598       if (LocaleCompare(attribute,"green-primary") == 0)
1599         {
1600           for ( ; image; image=image->next)
1601           {
1602             flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1603             image->chromaticity.green_primary.x=geometry_info.rho;
1604             image->chromaticity.green_primary.y=geometry_info.sigma;
1605             if ((flags & SigmaValue) == 0)
1606               image->chromaticity.green_primary.y=
1607                 image->chromaticity.green_primary.x;
1608           }
1609           break;
1610         }
1611       if (info)
1612         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1613       for ( ; image; image=image->next)
1614       {
1615         (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1616         (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1617       }
1618       break;
1619     }
1620     case 'I':
1621     case 'i':
1622     {
1623       if (LocaleNCompare(attribute,"index",5) == 0)
1624         {
1625           int
1626             items;
1627 
1628           long
1629             index;
1630 
1631           register Quantum
1632             *q;
1633 
1634           CacheView
1635             *image_view;
1636 
1637           for ( ; image; image=image->next)
1638           {
1639             if (image->storage_class != PseudoClass)
1640               continue;
1641             x=0;
1642             y=0;
1643             items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1644             (void) items;
1645             image_view=AcquireAuthenticCacheView(image,exception);
1646             q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1647             if (q != (Quantum *) NULL)
1648               {
1649                 items=sscanf(SvPV(sval,na),"%ld",&index);
1650                 if ((index >= 0) && (index < (ssize_t) image->colors))
1651                   SetPixelIndex(image,index,q);
1652                 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1653               }
1654             image_view=DestroyCacheView(image_view);
1655           }
1656           break;
1657         }
1658       if (LocaleCompare(attribute,"iterations") == 0)
1659         {
1660   iterations:
1661           for ( ; image; image=image->next)
1662             image->iterations=SvIV(sval);
1663           break;
1664         }
1665       if (LocaleCompare(attribute,"interlace") == 0)
1666         {
1667           sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1668             MagickFalse,SvPV(sval,na)) : SvIV(sval);
1669           if (sp < 0)
1670             {
1671               ThrowPerlException(exception,OptionError,
1672                 "UnrecognizedInterlaceType",SvPV(sval,na));
1673               break;
1674             }
1675           if (info)
1676             info->image_info->interlace=(InterlaceType) sp;
1677           for ( ; image; image=image->next)
1678             image->interlace=(InterlaceType) sp;
1679           break;
1680         }
1681       if (info)
1682         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1683       for ( ; image; image=image->next)
1684       {
1685         (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1686         (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1687       }
1688       break;
1689     }
1690     case 'L':
1691     case 'l':
1692     {
1693       if (LocaleCompare(attribute,"label") == 0)
1694         {
1695           for ( ; image; image=image->next)
1696             (void) SetImageProperty(image,"label",InterpretImageProperties(
1697               info ? info->image_info : (ImageInfo *) NULL,image,
1698               SvPV(sval,na),exception),exception);
1699           break;
1700         }
1701       if (LocaleCompare(attribute,"loop") == 0)
1702         goto iterations;
1703       if (info)
1704         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1705       for ( ; image; image=image->next)
1706       {
1707         (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1708         (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1709       }
1710       break;
1711     }
1712     case 'M':
1713     case 'm':
1714     {
1715       if (LocaleCompare(attribute,"magick") == 0)
1716         {
1717           if (info)
1718             (void) FormatLocaleString(info->image_info->filename,
1719               MagickPathExtent,"%s:",SvPV(sval,na));
1720           for ( ; image; image=image->next)
1721             (void) CopyMagickString(image->magick,SvPV(sval,na),
1722               MagickPathExtent);
1723           break;
1724         }
1725       if (LocaleCompare(attribute,"map-limit") == 0)
1726         {
1727           MagickSizeType
1728             limit;
1729 
1730           limit=MagickResourceInfinity;
1731           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1732             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1733               100.0);
1734           (void) SetMagickResourceLimit(MapResource,limit);
1735           break;
1736         }
1737       if (LocaleCompare(attribute,"mask") == 0)
1738         {
1739           Image
1740             *mask;
1741 
1742           mask=(Image *) NULL;
1743           if (SvPOK(sval))
1744             mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1745           for ( ; image; image=image->next)
1746             SetImageMask(image,ReadPixelMask,mask,exception);
1747           break;
1748         }
1749       if (LocaleCompare(attribute,"mattecolor") == 0)
1750         {
1751           (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1752             exception);
1753           if (info)
1754             info->image_info->alpha_color=target_color;
1755           for ( ; image; image=image->next)
1756             image->alpha_color=target_color;
1757           break;
1758         }
1759       if (LocaleCompare(attribute,"matte") == 0)
1760         {
1761           sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1762             SvPV(sval,na)) : SvIV(sval);
1763           if (sp < 0)
1764             {
1765               ThrowPerlException(exception,OptionError,"UnrecognizedType",
1766                 SvPV(sval,na));
1767               break;
1768             }
1769           for ( ; image; image=image->next)
1770             image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1771           break;
1772         }
1773       if (LocaleCompare(attribute,"memory-limit") == 0)
1774         {
1775           MagickSizeType
1776             limit;
1777 
1778           limit=MagickResourceInfinity;
1779           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1780             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1781               100.0);
1782           (void) SetMagickResourceLimit(MemoryResource,limit);
1783           break;
1784         }
1785       if (LocaleCompare(attribute,"monochrome") == 0)
1786         {
1787           sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1788             SvPV(sval,na)) : SvIV(sval);
1789           if (sp < 0)
1790             {
1791               ThrowPerlException(exception,OptionError,"UnrecognizedType",
1792                 SvPV(sval,na));
1793               break;
1794             }
1795           if (info)
1796             info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1797           for ( ; image; image=image->next)
1798             (void) SetImageType(image,BilevelType,exception);
1799           break;
1800         }
1801       if (info)
1802         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1803       for ( ; image; image=image->next)
1804       {
1805         (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1806         (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1807       }
1808       break;
1809     }
1810     case 'O':
1811     case 'o':
1812     {
1813       if (LocaleCompare(attribute,"option") == 0)
1814         {
1815           if (info)
1816             DefineImageOption(info->image_info,SvPV(sval,na));
1817           break;
1818         }
1819       if (LocaleCompare(attribute,"orientation") == 0)
1820         {
1821           sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1822             MagickFalse,SvPV(sval,na)) : SvIV(sval);
1823           if (sp < 0)
1824             {
1825               ThrowPerlException(exception,OptionError,
1826                 "UnrecognizedOrientationType",SvPV(sval,na));
1827               break;
1828             }
1829           if (info)
1830             info->image_info->orientation=(OrientationType) sp;
1831           for ( ; image; image=image->next)
1832             image->orientation=(OrientationType) sp;
1833           break;
1834         }
1835       if (info)
1836         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1837       for ( ; image; image=image->next)
1838       {
1839         (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1840         (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1841       }
1842       break;
1843     }
1844     case 'P':
1845     case 'p':
1846     {
1847       if (LocaleCompare(attribute,"page") == 0)
1848         {
1849           char
1850             *geometry;
1851 
1852           geometry=GetPageGeometry(SvPV(sval,na));
1853           if (info)
1854             (void) CloneString(&info->image_info->page,geometry);
1855           for ( ; image; image=image->next)
1856             (void) ParsePageGeometry(image,geometry,&image->page,exception);
1857           geometry=(char *) RelinquishMagickMemory(geometry);
1858           break;
1859         }
1860       if (LocaleNCompare(attribute,"pixel",5) == 0)
1861         {
1862           int
1863             items;
1864 
1865           PixelInfo
1866             pixel;
1867 
1868           register Quantum
1869             *q;
1870 
1871           CacheView
1872             *image_view;
1873 
1874           for ( ; image; image=image->next)
1875           {
1876             if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1877               break;
1878             x=0;
1879             y=0;
1880             items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1881             (void) items;
1882             image_view=AcquireVirtualCacheView(image,exception);
1883             q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1884             if (q != (Quantum *) NULL)
1885               {
1886                 if ((strchr(SvPV(sval,na),',') == 0) ||
1887                     (strchr(SvPV(sval,na),')') != 0))
1888                   QueryColorCompliance(SvPV(sval,na),AllCompliance,
1889                     &pixel,exception);
1890                 else
1891                   {
1892                     GetPixelInfo(image,&pixel);
1893                     flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1894                     pixel.red=geometry_info.rho;
1895                     if ((flags & SigmaValue) != 0)
1896                       pixel.green=geometry_info.sigma;
1897                     if ((flags & XiValue) != 0)
1898                       pixel.blue=geometry_info.xi;
1899                     if ((flags & PsiValue) != 0)
1900                       pixel.alpha=geometry_info.psi;
1901                     if ((flags & ChiValue) != 0)
1902                       pixel.black=geometry_info.chi;
1903                   }
1904                 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1905                 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1906                 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1907                 if (image->colorspace == CMYKColorspace)
1908                   SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1909                 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1910                 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1911               }
1912             image_view=DestroyCacheView(image_view);
1913           }
1914           break;
1915         }
1916       if (LocaleCompare(attribute,"pointsize") == 0)
1917         {
1918           if (info)
1919             {
1920               (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1921               info->image_info->pointsize=geometry_info.rho;
1922             }
1923           break;
1924         }
1925       if (info)
1926         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1927       for ( ; image; image=image->next)
1928       {
1929         (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1930         (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1931       }
1932       break;
1933     }
1934     case 'Q':
1935     case 'q':
1936     {
1937       if (LocaleCompare(attribute,"quality") == 0)
1938         {
1939           if (info)
1940             info->image_info->quality=SvIV(sval);
1941           for ( ; image; image=image->next)
1942             image->quality=SvIV(sval);
1943           break;
1944         }
1945       if (info)
1946         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1947       for ( ; image; image=image->next)
1948       {
1949         (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
1950         (void) SetImageArtifact(image,attribute,SvPV(sval,na));
1951       }
1952       break;
1953     }
1954     case 'R':
1955     case 'r':
1956     {
1957       if (LocaleCompare(attribute,"read-mask") == 0)
1958         {
1959           Image
1960             *mask;
1961 
1962           mask=(Image *) NULL;
1963           if (SvPOK(sval))
1964             mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1965           for ( ; image; image=image->next)
1966             SetImageMask(image,ReadPixelMask,mask,exception);
1967           break;
1968         }
1969       if (LocaleCompare(attribute,"red-primary") == 0)
1970         {
1971           for ( ; image; image=image->next)
1972           {
1973             flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1974             image->chromaticity.red_primary.x=geometry_info.rho;
1975             image->chromaticity.red_primary.y=geometry_info.sigma;
1976             if ((flags & SigmaValue) == 0)
1977               image->chromaticity.red_primary.y=
1978                 image->chromaticity.red_primary.x;
1979           }
1980           break;
1981         }
1982       if (LocaleCompare(attribute,"render") == 0)
1983         {
1984           sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1985             SvPV(sval,na)) : SvIV(sval);
1986           if (sp < 0)
1987             {
1988               ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1989                 SvPV(sval,na));
1990               break;
1991             }
1992          for ( ; image; image=image->next)
1993            image->rendering_intent=(RenderingIntent) sp;
1994          break;
1995        }
1996       if (LocaleCompare(attribute,"repage") == 0)
1997         {
1998           RectangleInfo
1999             geometry;
2000 
2001           for ( ; image; image=image->next)
2002           {
2003             flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
2004             if ((flags & WidthValue) != 0)
2005               {
2006                 if ((flags & HeightValue) == 0)
2007                   geometry.height=geometry.width;
2008                 image->page.width=geometry.width;
2009                 image->page.height=geometry.height;
2010               }
2011             if ((flags & AspectValue) != 0)
2012               {
2013                 if ((flags & XValue) != 0)
2014                   image->page.x+=geometry.x;
2015                 if ((flags & YValue) != 0)
2016                   image->page.y+=geometry.y;
2017               }
2018             else
2019               {
2020                 if ((flags & XValue) != 0)
2021                   {
2022                     image->page.x=geometry.x;
2023                     if (((flags & WidthValue) != 0) && (geometry.x > 0))
2024                       image->page.width=image->columns+geometry.x;
2025                   }
2026                 if ((flags & YValue) != 0)
2027                   {
2028                     image->page.y=geometry.y;
2029                     if (((flags & HeightValue) != 0) && (geometry.y > 0))
2030                       image->page.height=image->rows+geometry.y;
2031                   }
2032               }
2033           }
2034           break;
2035         }
2036       if (info)
2037         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2038       for ( ; image; image=image->next)
2039       {
2040         (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
2041         (void) SetImageArtifact(image,attribute,SvPV(sval,na));
2042       }
2043       break;
2044     }
2045     case 'S':
2046     case 's':
2047     {
2048       if (LocaleCompare(attribute,"sampling-factor") == 0)
2049         {
2050           if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2051             {
2052               ThrowPerlException(exception,OptionError,"MissingGeometry",
2053                 SvPV(sval,na));
2054               break;
2055             }
2056           if (info)
2057             (void) CloneString(&info->image_info->sampling_factor,
2058               SvPV(sval,na));
2059           break;
2060         }
2061       if (LocaleCompare(attribute,"scene") == 0)
2062         {
2063           for ( ; image; image=image->next)
2064             image->scene=SvIV(sval);
2065           break;
2066         }
2067       if (LocaleCompare(attribute,"server") == 0)
2068         goto display;
2069       if (LocaleCompare(attribute,"size") == 0)
2070         {
2071           if (info)
2072             {
2073               if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2074                 {
2075                   ThrowPerlException(exception,OptionError,"MissingGeometry",
2076                     SvPV(sval,na));
2077                   break;
2078                 }
2079               (void) CloneString(&info->image_info->size,SvPV(sval,na));
2080             }
2081           break;
2082         }
2083       if (LocaleCompare(attribute,"stroke") == 0)
2084         {
2085           if (info)
2086             (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2087           break;
2088         }
2089       if (info)
2090         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2091       for ( ; image; image=image->next)
2092       {
2093         (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
2094         (void) SetImageArtifact(image,attribute,SvPV(sval,na));
2095       }
2096       break;
2097     }
2098     case 'T':
2099     case 't':
2100     {
2101       if (LocaleCompare(attribute,"texture") == 0)
2102         {
2103           if (info)
2104             (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2105           break;
2106         }
2107       if (LocaleCompare(attribute,"thread-limit") == 0)
2108         {
2109           MagickSizeType
2110             limit;
2111 
2112           limit=MagickResourceInfinity;
2113           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2114             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2115               100.0);
2116           (void) SetMagickResourceLimit(ThreadResource,limit);
2117           break;
2118         }
2119       if (LocaleCompare(attribute,"tile-offset") == 0)
2120         {
2121           char
2122             *geometry;
2123 
2124           geometry=GetPageGeometry(SvPV(sval,na));
2125           if (info)
2126             (void) CloneString(&info->image_info->page,geometry);
2127           for ( ; image; image=image->next)
2128             (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2129               exception);
2130           geometry=(char *) RelinquishMagickMemory(geometry);
2131           break;
2132         }
2133       if (LocaleCompare(attribute,"time-limit") == 0)
2134         {
2135           MagickSizeType
2136             limit;
2137 
2138           limit=MagickResourceInfinity;
2139           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2140             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2141               100.0);
2142           (void) SetMagickResourceLimit(TimeResource,limit);
2143           break;
2144         }
2145       if (LocaleCompare(attribute,"transparent-color") == 0)
2146         {
2147           (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2148             exception);
2149           if (info)
2150             info->image_info->transparent_color=target_color;
2151           for ( ; image; image=image->next)
2152             image->transparent_color=target_color;
2153           break;
2154         }
2155       if (LocaleCompare(attribute,"type") == 0)
2156         {
2157           sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2158             SvPV(sval,na)) : SvIV(sval);
2159           if (sp < 0)
2160             {
2161               ThrowPerlException(exception,OptionError,"UnrecognizedType",
2162                 SvPV(sval,na));
2163               break;
2164             }
2165           if (info)
2166             info->image_info->type=(ImageType) sp;
2167           for ( ; image; image=image->next)
2168             SetImageType(image,(ImageType) sp,exception);
2169           break;
2170         }
2171       if (info)
2172         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2173       for ( ; image; image=image->next)
2174       {
2175         (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
2176         (void) SetImageArtifact(image,attribute,SvPV(sval,na));
2177       }
2178       break;
2179     }
2180     case 'U':
2181     case 'u':
2182     {
2183       if (LocaleCompare(attribute,"units") == 0)
2184         {
2185           sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2186             MagickFalse,SvPV(sval,na)) : SvIV(sval);
2187           if (sp < 0)
2188             {
2189               ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2190                 SvPV(sval,na));
2191               break;
2192             }
2193           if (info)
2194             info->image_info->units=(ResolutionType) sp;
2195           for ( ; image; image=image->next)
2196           {
2197             ResolutionType
2198               units;
2199 
2200             units=(ResolutionType) sp;
2201             if (image->units != units)
2202               switch (image->units)
2203               {
2204                 case UndefinedResolution:
2205                 case PixelsPerInchResolution:
2206                 {
2207                   if (units == PixelsPerCentimeterResolution)
2208                     {
2209                       image->resolution.x*=2.54;
2210                       image->resolution.y*=2.54;
2211                     }
2212                   break;
2213                 }
2214                 case PixelsPerCentimeterResolution:
2215                 {
2216                   if (units == PixelsPerInchResolution)
2217                     {
2218                       image->resolution.x/=2.54;
2219                       image->resolution.y/=2.54;
2220                     }
2221                   break;
2222                 }
2223               }
2224             image->units=units;
2225           }
2226           break;
2227         }
2228       if (info)
2229         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2230       for ( ; image; image=image->next)
2231       {
2232         (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
2233         (void) SetImageArtifact(image,attribute,SvPV(sval,na));
2234       }
2235       break;
2236     }
2237     case 'V':
2238     case 'v':
2239     {
2240       if (LocaleCompare(attribute,"verbose") == 0)
2241         {
2242           sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2243             SvPV(sval,na)) : SvIV(sval);
2244           if (sp < 0)
2245             {
2246               ThrowPerlException(exception,OptionError,"UnrecognizedType",
2247                 SvPV(sval,na));
2248               break;
2249             }
2250           if (info)
2251             info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2252           break;
2253         }
2254       if (LocaleCompare(attribute,"virtual-pixel") == 0)
2255         {
2256           sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2257             MagickFalse,SvPV(sval,na)) : SvIV(sval);
2258           if (sp < 0)
2259             {
2260               ThrowPerlException(exception,OptionError,
2261                 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2262               break;
2263             }
2264           for ( ; image; image=image->next)
2265             SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2266           break;
2267         }
2268       if (info)
2269         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2270       for ( ; image; image=image->next)
2271       {
2272         (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
2273         (void) SetImageArtifact(image,attribute,SvPV(sval,na));
2274       }
2275       break;
2276     }
2277     case 'W':
2278     case 'w':
2279     {
2280       if (LocaleCompare(attribute,"white-point") == 0)
2281         {
2282           for ( ; image; image=image->next)
2283           {
2284             flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2285             image->chromaticity.white_point.x=geometry_info.rho;
2286             image->chromaticity.white_point.y=geometry_info.sigma;
2287             if ((flags & SigmaValue) == 0)
2288               image->chromaticity.white_point.y=
2289                 image->chromaticity.white_point.x;
2290           }
2291           break;
2292         }
2293       if (LocaleCompare(attribute,"write-mask") == 0)
2294         {
2295           Image
2296             *mask;
2297 
2298           mask=(Image *) NULL;
2299           if (SvPOK(sval))
2300             mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
2301           for ( ; image; image=image->next)
2302             SetImageMask(image,WritePixelMask,mask,exception);
2303           break;
2304         }
2305       if (info)
2306         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2307       for ( ; image; image=image->next)
2308       {
2309         (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
2310         (void) SetImageArtifact(image,attribute,SvPV(sval,na));
2311       }
2312       break;
2313     }
2314     default:
2315     {
2316       if (info)
2317         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2318       for ( ; image; image=image->next)
2319       {
2320         (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
2321         (void) SetImageArtifact(image,attribute,SvPV(sval,na));
2322       }
2323       break;
2324     }
2325   }
2326 }
2327 
2328 /*
2329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2330 %                                                                             %
2331 %                                                                             %
2332 %                                                                             %
2333 %   S e t u p L i s t                                                         %
2334 %                                                                             %
2335 %                                                                             %
2336 %                                                                             %
2337 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2338 %
2339 %  Method SetupList returns the list of all the images linked by their
2340 %  image->next and image->previous link lists for use with ImageMagick.  If
2341 %  info is non-NULL, an info structure is returned in *info.  If
2342 %  reference_vector is non-NULL,an array of SV* are returned in
2343 %  *reference_vector.  Reference_vector is used when the images are going to be
2344 %  replaced with new Image*'s.
2345 %
2346 %  The format of the SetupList routine is:
2347 %
2348 %      Image *SetupList(SV *reference,struct PackageInfo **info,
2349 %        SV ***reference_vector,ExceptionInfo *exception)
2350 %
2351 %  A description of each parameter follows:
2352 %
2353 %    o list: a list of strings.
2354 %
2355 %    o string: a character string.
2356 %
2357 %    o exception: Return any errors or warnings in this structure.
2358 %
2359 */
SetupList(pTHX_ SV * reference,struct PackageInfo ** info,SV *** reference_vector,ExceptionInfo * exception)2360 static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2361   SV ***reference_vector,ExceptionInfo *exception)
2362 {
2363   Image
2364     *image;
2365 
2366   ssize_t
2367     current,
2368     last;
2369 
2370   if (reference_vector)
2371     *reference_vector=NULL;
2372   if (info)
2373     *info=NULL;
2374   current=0;
2375   last=0;
2376   image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2377   if (info && (SvTYPE(reference) == SVt_PVAV))
2378     *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2379       exception);
2380   return(image);
2381 }
2382 
2383 /*
2384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2385 %                                                                             %
2386 %                                                                             %
2387 %                                                                             %
2388 %   s t r E Q c a s e                                                         %
2389 %                                                                             %
2390 %                                                                             %
2391 %                                                                             %
2392 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2393 %
2394 %  strEQcase() compares two strings and returns 0 if they are the
2395 %  same or if the second string runs out first.  The comparison is case
2396 %  insensitive.
2397 %
2398 %  The format of the strEQcase routine is:
2399 %
2400 %      ssize_t strEQcase(const char *p,const char *q)
2401 %
2402 %  A description of each parameter follows:
2403 %
2404 %    o p: a character string.
2405 %
2406 %    o q: a character string.
2407 %
2408 %
2409 */
strEQcase(const char * p,const char * q)2410 static ssize_t strEQcase(const char *p,const char *q)
2411 {
2412   char
2413     c;
2414 
2415   register ssize_t
2416     i;
2417 
2418   for (i=0 ; (c=(*q)) != 0; i++)
2419   {
2420     if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2421         (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2422       return(0);
2423     p++;
2424     q++;
2425   }
2426   return(((*q == 0) && (*p == 0)) ? i : 0);
2427 }
2428 
2429 /*
2430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2431 %                                                                             %
2432 %                                                                             %
2433 %                                                                             %
2434 %   I m a g e : : M a g i c k                                                 %
2435 %                                                                             %
2436 %                                                                             %
2437 %                                                                             %
2438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2439 %
2440 %
2441 */
2442 MODULE = Image::Magick PACKAGE = Image::Magick
2443 
2444 PROTOTYPES: ENABLE
2445 
2446 BOOT:
2447   MagickCoreGenesis("PerlMagick",MagickFalse);
2448   SetWarningHandler(NULL);
2449   SetErrorHandler(NULL);
2450   magick_registry=NewSplayTree((int (*)(const void *,const void *))
2451     NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2452 
2453 void
UNLOAD()2454 UNLOAD()
2455   PPCODE:
2456   {
2457     if (magick_registry != (SplayTreeInfo *) NULL)
2458       magick_registry=DestroySplayTree(magick_registry);
2459     MagickCoreTerminus();
2460   }
2461 
2462 double
constant(name,argument)2463 constant(name,argument)
2464   char *name
2465   ssize_t argument
2466 
2467 #
2468 ###############################################################################
2469 #                                                                             #
2470 #                                                                             #
2471 #                                                                             #
2472 #   A n i m a t e                                                             #
2473 #                                                                             #
2474 #                                                                             #
2475 #                                                                             #
2476 ###############################################################################
2477 #
2478 #
2479 void
2480 Animate(ref,...)
2481   Image::Magick ref=NO_INIT
2482   ALIAS:
2483     AnimateImage  = 1
2484     animate       = 2
2485     animateimage  = 3
2486   PPCODE:
2487   {
2488     ExceptionInfo
2489       *exception;
2490 
2491     Image
2492       *image;
2493 
2494     register ssize_t
2495       i;
2496 
2497     struct PackageInfo
2498       *info,
2499       *package_info;
2500 
2501     SV
2502       *perl_exception,
2503       *reference;
2504 
2505     PERL_UNUSED_VAR(ref);
2506     PERL_UNUSED_VAR(ix);
2507     exception=AcquireExceptionInfo();
2508     perl_exception=newSVpv("",0);
2509     package_info=(struct PackageInfo *) NULL;
2510     if (sv_isobject(ST(0)) == 0)
2511       {
2512         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2513           PackageName);
2514         goto PerlException;
2515       }
2516     reference=SvRV(ST(0));
2517     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2518     if (image == (Image *) NULL)
2519       {
2520         ThrowPerlException(exception,OptionError,"NoImagesDefined",
2521           PackageName);
2522         goto PerlException;
2523       }
2524     package_info=ClonePackageInfo(info,exception);
2525     if (items == 2)
2526       SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2527     else
2528       if (items > 2)
2529         for (i=2; i < items; i+=2)
2530           SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2531             exception);
2532     (void) AnimateImages(package_info->image_info,image,exception);
2533     (void) CatchImageException(image);
2534 
2535   PerlException:
2536     if (package_info != (struct PackageInfo *) NULL)
2537       DestroyPackageInfo(package_info);
2538     InheritPerlException(exception,perl_exception);
2539     exception=DestroyExceptionInfo(exception);
2540     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2541     SvPOK_on(perl_exception);
2542     ST(0)=sv_2mortal(perl_exception);
2543     XSRETURN(1);
2544   }
2545 
2546 #
2547 ###############################################################################
2548 #                                                                             #
2549 #                                                                             #
2550 #                                                                             #
2551 #   A p p e n d                                                               #
2552 #                                                                             #
2553 #                                                                             #
2554 #                                                                             #
2555 ###############################################################################
2556 #
2557 #
2558 void
Append(ref,...)2559 Append(ref,...)
2560   Image::Magick ref=NO_INIT
2561   ALIAS:
2562     AppendImage  = 1
2563     append       = 2
2564     appendimage  = 3
2565   PPCODE:
2566   {
2567     AV
2568       *av;
2569 
2570     char
2571       *attribute;
2572 
2573     ExceptionInfo
2574       *exception;
2575 
2576     HV
2577       *hv;
2578 
2579     Image
2580       *image;
2581 
2582     register ssize_t
2583       i;
2584 
2585     ssize_t
2586       stack;
2587 
2588     struct PackageInfo
2589       *info;
2590 
2591     SV
2592       *av_reference,
2593       *perl_exception,
2594       *reference,
2595       *rv,
2596       *sv;
2597 
2598     PERL_UNUSED_VAR(ref);
2599     PERL_UNUSED_VAR(ix);
2600     exception=AcquireExceptionInfo();
2601     perl_exception=newSVpv("",0);
2602     sv=NULL;
2603     attribute=NULL;
2604     av=NULL;
2605     if (sv_isobject(ST(0)) == 0)
2606       {
2607         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2608           PackageName);
2609         goto PerlException;
2610       }
2611     reference=SvRV(ST(0));
2612     hv=SvSTASH(reference);
2613     av=newAV();
2614     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2615     SvREFCNT_dec(av);
2616     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2617     if (image == (Image *) NULL)
2618       {
2619         ThrowPerlException(exception,OptionError,"NoImagesDefined",
2620           PackageName);
2621         goto PerlException;
2622       }
2623     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2624     /*
2625       Get options.
2626     */
2627     stack=MagickTrue;
2628     for (i=2; i < items; i+=2)
2629     {
2630       attribute=(char *) SvPV(ST(i-1),na);
2631       switch (*attribute)
2632       {
2633         case 'S':
2634         case 's':
2635         {
2636           if (LocaleCompare(attribute,"stack") == 0)
2637             {
2638               stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2639                 SvPV(ST(i),na));
2640               if (stack < 0)
2641                 {
2642                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
2643                     SvPV(ST(i),na));
2644                   return;
2645                 }
2646               break;
2647             }
2648           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2649             attribute);
2650           break;
2651         }
2652         default:
2653         {
2654           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2655             attribute);
2656           break;
2657         }
2658       }
2659     }
2660     image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2661     if (image == (Image *) NULL)
2662       goto PerlException;
2663     for ( ; image; image=image->next)
2664     {
2665       AddImageToRegistry(sv,image);
2666       rv=newRV(sv);
2667       av_push(av,sv_bless(rv,hv));
2668       SvREFCNT_dec(sv);
2669     }
2670     exception=DestroyExceptionInfo(exception);
2671     ST(0)=av_reference;
2672     SvREFCNT_dec(perl_exception);
2673     XSRETURN(1);
2674 
2675   PerlException:
2676     InheritPerlException(exception,perl_exception);
2677     exception=DestroyExceptionInfo(exception);
2678     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2679     SvPOK_on(perl_exception);
2680     ST(0)=sv_2mortal(perl_exception);
2681     XSRETURN(1);
2682   }
2683 
2684 #
2685 ###############################################################################
2686 #                                                                             #
2687 #                                                                             #
2688 #                                                                             #
2689 #   A v e r a g e                                                             #
2690 #                                                                             #
2691 #                                                                             #
2692 #                                                                             #
2693 ###############################################################################
2694 #
2695 #
2696 void
Average(ref)2697 Average(ref)
2698   Image::Magick ref=NO_INIT
2699   ALIAS:
2700     AverageImage   = 1
2701     average        = 2
2702     averageimage   = 3
2703   PPCODE:
2704   {
2705     AV
2706       *av;
2707 
2708     char
2709       *p;
2710 
2711     ExceptionInfo
2712       *exception;
2713 
2714     HV
2715       *hv;
2716 
2717     Image
2718       *image;
2719 
2720     struct PackageInfo
2721       *info;
2722 
2723     SV
2724       *perl_exception,
2725       *reference,
2726       *rv,
2727       *sv;
2728 
2729     PERL_UNUSED_VAR(ref);
2730     PERL_UNUSED_VAR(ix);
2731     exception=AcquireExceptionInfo();
2732     perl_exception=newSVpv("",0);
2733     sv=NULL;
2734     if (sv_isobject(ST(0)) == 0)
2735       {
2736         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2737           PackageName);
2738         goto PerlException;
2739       }
2740     reference=SvRV(ST(0));
2741     hv=SvSTASH(reference);
2742     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2743     if (image == (Image *) NULL)
2744       {
2745         ThrowPerlException(exception,OptionError,"NoImagesDefined",
2746           PackageName);
2747         goto PerlException;
2748       }
2749     image=EvaluateImages(image,MeanEvaluateOperator,exception);
2750     if (image == (Image *) NULL)
2751       goto PerlException;
2752     /*
2753       Create blessed Perl array for the returned image.
2754     */
2755     av=newAV();
2756     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2757     SvREFCNT_dec(av);
2758     AddImageToRegistry(sv,image);
2759     rv=newRV(sv);
2760     av_push(av,sv_bless(rv,hv));
2761     SvREFCNT_dec(sv);
2762     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2763     (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
2764       "average-%.*s",(int) (MagickPathExtent-9),
2765       ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2766     (void) CopyMagickString(image->filename,info->image_info->filename,
2767       MagickPathExtent);
2768     SetImageInfo(info->image_info,0,exception);
2769     exception=DestroyExceptionInfo(exception);
2770     SvREFCNT_dec(perl_exception);
2771     XSRETURN(1);
2772 
2773   PerlException:
2774     InheritPerlException(exception,perl_exception);
2775     exception=DestroyExceptionInfo(exception);
2776     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2777     SvPOK_on(perl_exception);
2778     ST(0)=sv_2mortal(perl_exception);
2779     XSRETURN(1);
2780   }
2781 
2782 #
2783 ###############################################################################
2784 #                                                                             #
2785 #                                                                             #
2786 #                                                                             #
2787 #   B l o b T o I m a g e                                                     #
2788 #                                                                             #
2789 #                                                                             #
2790 #                                                                             #
2791 ###############################################################################
2792 #
2793 #
2794 void
BlobToImage(ref,...)2795 BlobToImage(ref,...)
2796   Image::Magick ref=NO_INIT
2797   ALIAS:
2798     BlobToImage  = 1
2799     blobtoimage  = 2
2800     blobto       = 3
2801   PPCODE:
2802   {
2803     AV
2804       *av;
2805 
2806     char
2807       **keep,
2808       **list;
2809 
2810     ExceptionInfo
2811       *exception;
2812 
2813     HV
2814       *hv;
2815 
2816     Image
2817       *image;
2818 
2819     register char
2820       **p;
2821 
2822     register ssize_t
2823       i;
2824 
2825     ssize_t
2826       ac,
2827       n,
2828       number_images;
2829 
2830     STRLEN
2831       *length;
2832 
2833     struct PackageInfo
2834       *info;
2835 
2836     SV
2837       *perl_exception,
2838       *reference,
2839       *rv,
2840       *sv;
2841 
2842     PERL_UNUSED_VAR(ref);
2843     PERL_UNUSED_VAR(ix);
2844     exception=AcquireExceptionInfo();
2845     perl_exception=newSVpv("",0);
2846     sv=NULL;
2847     number_images=0;
2848     ac=(items < 2) ? 1 : items-1;
2849     length=(STRLEN *) NULL;
2850     list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2851     if (list == (char **) NULL)
2852       {
2853         ThrowPerlException(exception,ResourceLimitError,
2854           "MemoryAllocationFailed",PackageName);
2855         goto PerlException;
2856       }
2857     length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2858     if (length == (STRLEN *) NULL)
2859       {
2860         ThrowPerlException(exception,ResourceLimitError,
2861           "MemoryAllocationFailed",PackageName);
2862         goto PerlException;
2863       }
2864     if (sv_isobject(ST(0)) == 0)
2865       {
2866         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2867           PackageName);
2868         goto PerlException;
2869       }
2870     reference=SvRV(ST(0));
2871     hv=SvSTASH(reference);
2872     if (SvTYPE(reference) != SVt_PVAV)
2873       {
2874         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2875           PackageName);
2876         goto PerlException;
2877       }
2878     av=(AV *) reference;
2879     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2880       exception);
2881     n=1;
2882     if (items <= 1)
2883       {
2884         ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2885         goto PerlException;
2886       }
2887     for (n=0, i=0; i < ac; i++)
2888     {
2889       list[n]=(char *) (SvPV(ST(i+1),length[n]));
2890       if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2891         {
2892           list[n]=(char *) (SvPV(ST(i+2),length[n]));
2893           continue;
2894         }
2895       n++;
2896     }
2897     list[n]=(char *) NULL;
2898     keep=list;
2899     for (i=number_images=0; i < n; i++)
2900     {
2901       image=BlobToImage(info->image_info,list[i],length[i],exception);
2902       if (image == (Image *) NULL)
2903         break;
2904       for ( ; image; image=image->next)
2905       {
2906         AddImageToRegistry(sv,image);
2907         rv=newRV(sv);
2908         av_push(av,sv_bless(rv,hv));
2909         SvREFCNT_dec(sv);
2910         number_images++;
2911       }
2912     }
2913     /*
2914       Free resources.
2915     */
2916     for (i=0; i < n; i++)
2917       if (list[i] != (char *) NULL)
2918         for (p=keep; list[i] != *p++; )
2919           if (*p == (char *) NULL)
2920             {
2921               list[i]=(char *) RelinquishMagickMemory(list[i]);
2922               break;
2923             }
2924 
2925   PerlException:
2926     if (list)
2927       list=(char **) RelinquishMagickMemory(list);
2928     if (length)
2929       length=(STRLEN *) RelinquishMagickMemory(length);
2930     InheritPerlException(exception,perl_exception);
2931     exception=DestroyExceptionInfo(exception);
2932     sv_setiv(perl_exception,(IV) number_images);
2933     SvPOK_on(perl_exception);
2934     ST(0)=sv_2mortal(perl_exception);
2935     XSRETURN(1);
2936   }
2937 
2938 #
2939 ###############################################################################
2940 #                                                                             #
2941 #                                                                             #
2942 #                                                                             #
2943 #   C h a n n e l F x                                                         #
2944 #                                                                             #
2945 #                                                                             #
2946 #                                                                             #
2947 ###############################################################################
2948 #
2949 #
2950 void
ChannelFx(ref,...)2951 ChannelFx(ref,...)
2952   Image::Magick ref=NO_INIT
2953   ALIAS:
2954     ChannelFxImage  = 1
2955     channelfx       = 2
2956     channelfximage  = 3
2957   PPCODE:
2958   {
2959     AV
2960       *av;
2961 
2962     char
2963       *attribute,
2964       expression[MagickPathExtent];
2965 
2966     ChannelType
2967       channel,
2968       channel_mask;
2969 
2970     ExceptionInfo
2971       *exception;
2972 
2973     HV
2974       *hv;
2975 
2976     Image
2977       *image;
2978 
2979     register ssize_t
2980       i;
2981 
2982     struct PackageInfo
2983       *info;
2984 
2985     SV
2986       *av_reference,
2987       *perl_exception,
2988       *reference,
2989       *rv,
2990       *sv;
2991 
2992     PERL_UNUSED_VAR(ref);
2993     PERL_UNUSED_VAR(ix);
2994     exception=AcquireExceptionInfo();
2995     perl_exception=newSVpv("",0);
2996     sv=NULL;
2997     attribute=NULL;
2998     av=NULL;
2999     if (sv_isobject(ST(0)) == 0)
3000       {
3001         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3002           PackageName);
3003         goto PerlException;
3004       }
3005     reference=SvRV(ST(0));
3006     hv=SvSTASH(reference);
3007     av=newAV();
3008     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3009     SvREFCNT_dec(av);
3010     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3011     if (image == (Image *) NULL)
3012       {
3013         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3014           PackageName);
3015         goto PerlException;
3016       }
3017     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3018     /*
3019       Get options.
3020     */
3021     channel=DefaultChannels;
3022     (void) CopyMagickString(expression,"u",MagickPathExtent);
3023     if (items == 2)
3024       (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
3025     else
3026       for (i=2; i < items; i+=2)
3027       {
3028         attribute=(char *) SvPV(ST(i-1),na);
3029         switch (*attribute)
3030         {
3031           case 'C':
3032           case 'c':
3033           {
3034             if (LocaleCompare(attribute,"channel") == 0)
3035               {
3036                 ssize_t
3037                   option;
3038 
3039                 option=ParseChannelOption(SvPV(ST(i),na));
3040                 if (option < 0)
3041                   {
3042                     ThrowPerlException(exception,OptionError,
3043                       "UnrecognizedType",SvPV(ST(i),na));
3044                     return;
3045                   }
3046                 channel=(ChannelType) option;
3047                 break;
3048               }
3049             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3050               attribute);
3051             break;
3052           }
3053           case 'E':
3054           case 'e':
3055           {
3056             if (LocaleCompare(attribute,"expression") == 0)
3057               {
3058                 (void) CopyMagickString(expression,SvPV(ST(i),na),
3059                   MagickPathExtent);
3060                 break;
3061               }
3062             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3063               attribute);
3064             break;
3065           }
3066           default:
3067           {
3068             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3069               attribute);
3070             break;
3071           }
3072         }
3073       }
3074     channel_mask=SetImageChannelMask(image,channel);
3075     image=ChannelFxImage(image,expression,exception);
3076     if (image != (Image *) NULL)
3077       (void) SetImageChannelMask(image,channel_mask);
3078     if (image == (Image *) NULL)
3079       goto PerlException;
3080     for ( ; image; image=image->next)
3081     {
3082       AddImageToRegistry(sv,image);
3083       rv=newRV(sv);
3084       av_push(av,sv_bless(rv,hv));
3085       SvREFCNT_dec(sv);
3086     }
3087     exception=DestroyExceptionInfo(exception);
3088     ST(0)=av_reference;
3089     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
3090     XSRETURN(1);
3091 
3092   PerlException:
3093     InheritPerlException(exception,perl_exception);
3094     exception=DestroyExceptionInfo(exception);
3095     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3096     SvPOK_on(perl_exception);
3097     ST(0)=sv_2mortal(perl_exception);
3098     XSRETURN(1);
3099   }
3100 
3101 #
3102 ###############################################################################
3103 #                                                                             #
3104 #                                                                             #
3105 #                                                                             #
3106 #   C l o n e                                                                 #
3107 #                                                                             #
3108 #                                                                             #
3109 #                                                                             #
3110 ###############################################################################
3111 #
3112 #
3113 void
Clone(ref)3114 Clone(ref)
3115   Image::Magick ref=NO_INIT
3116   ALIAS:
3117     CopyImage   = 1
3118     copy        = 2
3119     copyimage   = 3
3120     CloneImage  = 4
3121     clone       = 5
3122     cloneimage  = 6
3123     Clone       = 7
3124   PPCODE:
3125   {
3126     AV
3127       *av;
3128 
3129     ExceptionInfo
3130       *exception;
3131 
3132     HV
3133       *hv;
3134 
3135     Image
3136       *clone,
3137       *image;
3138 
3139     struct PackageInfo
3140       *info;
3141 
3142     SV
3143       *perl_exception,
3144       *reference,
3145       *rv,
3146       *sv;
3147 
3148     PERL_UNUSED_VAR(ref);
3149     PERL_UNUSED_VAR(ix);
3150     exception=AcquireExceptionInfo();
3151     perl_exception=newSVpv("",0);
3152     sv=NULL;
3153     if (sv_isobject(ST(0)) == 0)
3154       {
3155         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3156           PackageName);
3157         goto PerlException;
3158       }
3159     reference=SvRV(ST(0));
3160     hv=SvSTASH(reference);
3161     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3162     if (image == (Image *) NULL)
3163       {
3164         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3165           PackageName);
3166         goto PerlException;
3167       }
3168     /*
3169       Create blessed Perl array for the returned image.
3170     */
3171     av=newAV();
3172     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3173     SvREFCNT_dec(av);
3174     for ( ; image; image=image->next)
3175     {
3176       clone=CloneImage(image,0,0,MagickTrue,exception);
3177       if (clone == (Image *) NULL)
3178         break;
3179       AddImageToRegistry(sv,clone);
3180       rv=newRV(sv);
3181       av_push(av,sv_bless(rv,hv));
3182       SvREFCNT_dec(sv);
3183     }
3184     exception=DestroyExceptionInfo(exception);
3185     SvREFCNT_dec(perl_exception);
3186     XSRETURN(1);
3187 
3188   PerlException:
3189     InheritPerlException(exception,perl_exception);
3190     exception=DestroyExceptionInfo(exception);
3191     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3192     SvPOK_on(perl_exception);
3193     ST(0)=sv_2mortal(perl_exception);
3194     XSRETURN(1);
3195   }
3196 
3197 #
3198 ###############################################################################
3199 #                                                                             #
3200 #                                                                             #
3201 #                                                                             #
3202 #   C L O N E                                                                 #
3203 #                                                                             #
3204 #                                                                             #
3205 #                                                                             #
3206 ###############################################################################
3207 #
3208 #
3209 void
CLONE(ref,...)3210 CLONE(ref,...)
3211   SV *ref;
3212   CODE:
3213   {
3214     PERL_UNUSED_VAR(ref);
3215     if (magick_registry != (SplayTreeInfo *) NULL)
3216       {
3217         register Image
3218           *p;
3219 
3220         ResetSplayTreeIterator(magick_registry);
3221         p=(Image *) GetNextKeyInSplayTree(magick_registry);
3222         while (p != (Image *) NULL)
3223         {
3224           ReferenceImage(p);
3225           p=(Image *) GetNextKeyInSplayTree(magick_registry);
3226         }
3227       }
3228   }
3229 
3230 #
3231 ###############################################################################
3232 #                                                                             #
3233 #                                                                             #
3234 #                                                                             #
3235 #   C o a l e s c e                                                           #
3236 #                                                                             #
3237 #                                                                             #
3238 #                                                                             #
3239 ###############################################################################
3240 #
3241 #
3242 void
Coalesce(ref)3243 Coalesce(ref)
3244   Image::Magick ref=NO_INIT
3245   ALIAS:
3246     CoalesceImage   = 1
3247     coalesce        = 2
3248     coalesceimage   = 3
3249   PPCODE:
3250   {
3251     AV
3252       *av;
3253 
3254     ExceptionInfo
3255       *exception;
3256 
3257     HV
3258       *hv;
3259 
3260     Image
3261       *image;
3262 
3263     struct PackageInfo
3264       *info;
3265 
3266     SV
3267       *av_reference,
3268       *perl_exception,
3269       *reference,
3270       *rv,
3271       *sv;
3272 
3273     PERL_UNUSED_VAR(ref);
3274     PERL_UNUSED_VAR(ix);
3275     exception=AcquireExceptionInfo();
3276     perl_exception=newSVpv("",0);
3277     sv=NULL;
3278     if (sv_isobject(ST(0)) == 0)
3279       {
3280         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3281           PackageName);
3282         goto PerlException;
3283       }
3284     reference=SvRV(ST(0));
3285     hv=SvSTASH(reference);
3286     av=newAV();
3287     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3288     SvREFCNT_dec(av);
3289     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3290     if (image == (Image *) NULL)
3291       {
3292         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3293           PackageName);
3294         goto PerlException;
3295       }
3296     image=CoalesceImages(image,exception);
3297     if (image == (Image *) NULL)
3298       goto PerlException;
3299     for ( ; image; image=image->next)
3300     {
3301       AddImageToRegistry(sv,image);
3302       rv=newRV(sv);
3303       av_push(av,sv_bless(rv,hv));
3304       SvREFCNT_dec(sv);
3305     }
3306     exception=DestroyExceptionInfo(exception);
3307     ST(0)=av_reference;
3308     SvREFCNT_dec(perl_exception);
3309     XSRETURN(1);
3310 
3311   PerlException:
3312     InheritPerlException(exception,perl_exception);
3313     exception=DestroyExceptionInfo(exception);
3314     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3315     SvPOK_on(perl_exception);
3316     ST(0)=sv_2mortal(perl_exception);
3317     XSRETURN(1);
3318   }
3319 
3320 #
3321 ###############################################################################
3322 #                                                                             #
3323 #                                                                             #
3324 #                                                                             #
3325 #   C o m p a r e                                                             #
3326 #                                                                             #
3327 #                                                                             #
3328 #                                                                             #
3329 ###############################################################################
3330 #
3331 #
3332 void
Compare(ref,...)3333 Compare(ref,...)
3334   Image::Magick ref=NO_INIT
3335   ALIAS:
3336     CompareImages = 1
3337     compare      = 2
3338     compareimage = 3
3339   PPCODE:
3340   {
3341     AV
3342       *av;
3343 
3344     char
3345       *attribute;
3346 
3347     double
3348       distortion;
3349 
3350     ExceptionInfo
3351       *exception;
3352 
3353     HV
3354       *hv;
3355 
3356     Image
3357       *difference_image,
3358       *image,
3359       *reconstruct_image;
3360 
3361     MetricType
3362       metric;
3363 
3364     register ssize_t
3365       i;
3366 
3367     ssize_t
3368       option;
3369 
3370     struct PackageInfo
3371       *info;
3372 
3373     SV
3374       *av_reference,
3375       *perl_exception,
3376       *reference,
3377       *rv,
3378       *sv;
3379 
3380     PERL_UNUSED_VAR(ref);
3381     PERL_UNUSED_VAR(ix);
3382     exception=AcquireExceptionInfo();
3383     perl_exception=newSVpv("",0);
3384     sv=NULL;
3385     av=NULL;
3386     attribute=NULL;
3387     if (sv_isobject(ST(0)) == 0)
3388       {
3389         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3390           PackageName);
3391         goto PerlException;
3392       }
3393     reference=SvRV(ST(0));
3394     hv=SvSTASH(reference);
3395     av=newAV();
3396     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3397     SvREFCNT_dec(av);
3398     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3399     if (image == (Image *) NULL)
3400       {
3401         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3402           PackageName);
3403         goto PerlException;
3404       }
3405     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3406     /*
3407       Get attribute.
3408     */
3409     reconstruct_image=image;
3410     metric=RootMeanSquaredErrorMetric;
3411     for (i=2; i < items; i+=2)
3412     {
3413       attribute=(char *) SvPV(ST(i-1),na);
3414       switch (*attribute)
3415       {
3416         case 'C':
3417         case 'c':
3418         {
3419           if (LocaleCompare(attribute,"channel") == 0)
3420             {
3421               ssize_t
3422                 option;
3423 
3424               option=ParseChannelOption(SvPV(ST(i),na));
3425               if (option < 0)
3426                 {
3427                   ThrowPerlException(exception,OptionError,
3428                     "UnrecognizedType",SvPV(ST(i),na));
3429                   return;
3430                 }
3431               (void) SetPixelChannelMask(image,(ChannelType) option);
3432               break;
3433             }
3434           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3435             attribute);
3436           break;
3437         }
3438         case 'F':
3439         case 'f':
3440         {
3441           if (LocaleCompare(attribute,"fuzz") == 0)
3442             {
3443               image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3444               break;
3445             }
3446           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3447             attribute);
3448           break;
3449         }
3450         case 'I':
3451         case 'i':
3452         {
3453           if (LocaleCompare(attribute,"image") == 0)
3454             {
3455               reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3456                 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3457               break;
3458             }
3459           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3460             attribute);
3461           break;
3462         }
3463         case 'M':
3464         case 'm':
3465         {
3466           if (LocaleCompare(attribute,"metric") == 0)
3467             {
3468               option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3469                 SvPV(ST(i),na));
3470               if (option < 0)
3471                 {
3472                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
3473                     SvPV(ST(i),na));
3474                   break;
3475                 }
3476               metric=(MetricType) option;
3477               break;
3478             }
3479           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3480             attribute);
3481           break;
3482         }
3483         default:
3484         {
3485           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3486             attribute);
3487           break;
3488         }
3489       }
3490     }
3491     difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3492       exception);
3493     if (difference_image != (Image *) NULL)
3494       {
3495         difference_image->error.mean_error_per_pixel=distortion;
3496         AddImageToRegistry(sv,difference_image);
3497         rv=newRV(sv);
3498         av_push(av,sv_bless(rv,hv));
3499         SvREFCNT_dec(sv);
3500       }
3501     exception=DestroyExceptionInfo(exception);
3502     ST(0)=av_reference;
3503     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
3504     XSRETURN(1);
3505 
3506   PerlException:
3507     InheritPerlException(exception,perl_exception);
3508     exception=DestroyExceptionInfo(exception);
3509     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3510     SvPOK_on(perl_exception);
3511     ST(0)=sv_2mortal(perl_exception);
3512     XSRETURN(1);
3513   }
3514 
3515 #
3516 ###############################################################################
3517 #                                                                             #
3518 #                                                                             #
3519 #                                                                             #
3520 #   C o m p l e x I m a g e s                                                 #
3521 #                                                                             #
3522 #                                                                             #
3523 #                                                                             #
3524 ###############################################################################
3525 #
3526 #
3527 void
ComplexImages(ref)3528 ComplexImages(ref)
3529   Image::Magick ref=NO_INIT
3530   ALIAS:
3531     ComplexImages   = 1
3532     compleximages   = 2
3533   PPCODE:
3534   {
3535     AV
3536       *av;
3537 
3538     char
3539       *attribute,
3540       *p;
3541 
3542     ComplexOperator
3543       op;
3544 
3545     ExceptionInfo
3546       *exception;
3547 
3548     HV
3549       *hv;
3550 
3551     Image
3552       *image;
3553 
3554     register ssize_t
3555       i;
3556 
3557     struct PackageInfo
3558       *info;
3559 
3560     SV
3561       *perl_exception,
3562       *reference,
3563       *rv,
3564       *sv;
3565 
3566     PERL_UNUSED_VAR(ref);
3567     PERL_UNUSED_VAR(ix);
3568     exception=AcquireExceptionInfo();
3569     perl_exception=newSVpv("",0);
3570     sv=NULL;
3571     if (sv_isobject(ST(0)) == 0)
3572       {
3573         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3574           PackageName);
3575         goto PerlException;
3576       }
3577     reference=SvRV(ST(0));
3578     hv=SvSTASH(reference);
3579     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3580     if (image == (Image *) NULL)
3581       {
3582         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3583           PackageName);
3584         goto PerlException;
3585       }
3586     op=UndefinedComplexOperator;
3587     if (items == 2)
3588       {
3589         ssize_t
3590           in;
3591 
3592         in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *)
3593           SvPV(ST(1),na));
3594         if (in < 0)
3595           {
3596             ThrowPerlException(exception,OptionError,"UnrecognizedType",
3597               SvPV(ST(1),na));
3598             return;
3599           }
3600         op=(ComplexOperator) in;
3601       }
3602     else
3603       for (i=2; i < items; i+=2)
3604       {
3605         attribute=(char *) SvPV(ST(i-1),na);
3606         switch (*attribute)
3607         {
3608           case 'O':
3609           case 'o':
3610           {
3611             if (LocaleCompare(attribute,"operator") == 0)
3612               {
3613                 ssize_t
3614                   in;
3615 
3616                 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3617                   MagickComplexOptions,MagickFalse,SvPV(ST(i),na));
3618                 if (in < 0)
3619                   {
3620                     ThrowPerlException(exception,OptionError,"UnrecognizedType",
3621                       SvPV(ST(i),na));
3622                     return;
3623                   }
3624                 op=(ComplexOperator) in;
3625                 break;
3626               }
3627             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3628               attribute);
3629             break;
3630           }
3631           default:
3632           {
3633             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3634               attribute);
3635             break;
3636           }
3637         }
3638       }
3639     image=ComplexImages(image,op,exception);
3640     if (image == (Image *) NULL)
3641       goto PerlException;
3642     /*
3643       Create blessed Perl array for the returned image.
3644     */
3645     av=newAV();
3646     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3647     SvREFCNT_dec(av);
3648     AddImageToRegistry(sv,image);
3649     rv=newRV(sv);
3650     av_push(av,sv_bless(rv,hv));
3651     SvREFCNT_dec(sv);
3652     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3653     (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
3654       "complex-%.*s",(int) (MagickPathExtent-9),
3655       ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3656     (void) CopyMagickString(image->filename,info->image_info->filename,
3657       MagickPathExtent);
3658     SetImageInfo(info->image_info,0,exception);
3659     exception=DestroyExceptionInfo(exception);
3660     SvREFCNT_dec(perl_exception);
3661     XSRETURN(1);
3662 
3663   PerlException:
3664     InheritPerlException(exception,perl_exception);
3665     exception=DestroyExceptionInfo(exception);
3666     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3667     SvPOK_on(perl_exception);
3668     ST(0)=sv_2mortal(perl_exception);
3669     XSRETURN(1);
3670   }
3671 
3672 #
3673 ###############################################################################
3674 #                                                                             #
3675 #                                                                             #
3676 #                                                                             #
3677 #   C o m p a r e L a y e r s                                                 #
3678 #                                                                             #
3679 #                                                                             #
3680 #                                                                             #
3681 ###############################################################################
3682 #
3683 #
3684 void
CompareLayers(ref)3685 CompareLayers(ref)
3686   Image::Magick ref=NO_INIT
3687   ALIAS:
3688     CompareImagesLayers   = 1
3689     comparelayers        = 2
3690     compareimagelayers   = 3
3691   PPCODE:
3692   {
3693     AV
3694       *av;
3695 
3696     char
3697       *attribute;
3698 
3699     ExceptionInfo
3700       *exception;
3701 
3702     HV
3703       *hv;
3704 
3705     Image
3706       *image;
3707 
3708     LayerMethod
3709       method;
3710 
3711     register ssize_t
3712       i;
3713 
3714     ssize_t
3715       option;
3716 
3717     struct PackageInfo
3718       *info;
3719 
3720     SV
3721       *av_reference,
3722       *perl_exception,
3723       *reference,
3724       *rv,
3725       *sv;
3726 
3727     PERL_UNUSED_VAR(ref);
3728     PERL_UNUSED_VAR(ix);
3729     exception=AcquireExceptionInfo();
3730     perl_exception=newSVpv("",0);
3731     sv=NULL;
3732     if (sv_isobject(ST(0)) == 0)
3733       {
3734         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3735           PackageName);
3736         goto PerlException;
3737       }
3738     reference=SvRV(ST(0));
3739     hv=SvSTASH(reference);
3740     av=newAV();
3741     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3742     SvREFCNT_dec(av);
3743     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3744     if (image == (Image *) NULL)
3745       {
3746         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3747           PackageName);
3748         goto PerlException;
3749       }
3750     method=CompareAnyLayer;
3751     for (i=2; i < items; i+=2)
3752     {
3753       attribute=(char *) SvPV(ST(i-1),na);
3754       switch (*attribute)
3755       {
3756         case 'M':
3757         case 'm':
3758         {
3759           if (LocaleCompare(attribute,"method") == 0)
3760             {
3761               option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3762                 SvPV(ST(i),na));
3763               if (option < 0)
3764                 {
3765                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
3766                     SvPV(ST(i),na));
3767                   break;
3768                 }
3769                method=(LayerMethod) option;
3770               break;
3771             }
3772           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3773             attribute);
3774           break;
3775         }
3776         default:
3777         {
3778           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3779             attribute);
3780           break;
3781         }
3782       }
3783     }
3784     image=CompareImagesLayers(image,method,exception);
3785     if (image == (Image *) NULL)
3786       goto PerlException;
3787     for ( ; image; image=image->next)
3788     {
3789       AddImageToRegistry(sv,image);
3790       rv=newRV(sv);
3791       av_push(av,sv_bless(rv,hv));
3792       SvREFCNT_dec(sv);
3793     }
3794     exception=DestroyExceptionInfo(exception);
3795     ST(0)=av_reference;
3796     SvREFCNT_dec(perl_exception);
3797     XSRETURN(1);
3798 
3799   PerlException:
3800     InheritPerlException(exception,perl_exception);
3801     exception=DestroyExceptionInfo(exception);
3802     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3803     SvPOK_on(perl_exception);
3804     ST(0)=sv_2mortal(perl_exception);
3805     XSRETURN(1);
3806   }
3807 
3808 #
3809 ###############################################################################
3810 #                                                                             #
3811 #                                                                             #
3812 #                                                                             #
3813 #   D e s t r o y                                                             #
3814 #                                                                             #
3815 #                                                                             #
3816 #                                                                             #
3817 ###############################################################################
3818 #
3819 #
3820 void
DESTROY(ref)3821 DESTROY(ref)
3822   Image::Magick ref=NO_INIT
3823   PPCODE:
3824   {
3825     SV
3826       *reference;
3827 
3828     PERL_UNUSED_VAR(ref);
3829     if (sv_isobject(ST(0)) == 0)
3830       croak("ReferenceIsNotMyType");
3831     reference=SvRV(ST(0));
3832     switch (SvTYPE(reference))
3833     {
3834       case SVt_PVAV:
3835       {
3836         char
3837           message[MagickPathExtent];
3838 
3839         const SV
3840           *key;
3841 
3842         HV
3843           *hv;
3844 
3845         GV
3846           **gvp;
3847 
3848         struct PackageInfo
3849           *info;
3850 
3851         SV
3852           *sv;
3853 
3854         /*
3855           Array (AV *) reference
3856         */
3857         (void) FormatLocaleString(message,MagickPathExtent,"package%s%p",
3858           XS_VERSION,reference);
3859         hv=gv_stashpv(PackageName, FALSE);
3860         if (!hv)
3861           break;
3862         gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3863         if (!gvp)
3864           break;
3865         sv=GvSV(*gvp);
3866         if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3867           {
3868             info=INT2PTR(struct PackageInfo *,SvIV(sv));
3869             DestroyPackageInfo(info);
3870           }
3871         key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3872         (void) key;
3873         break;
3874       }
3875       case SVt_PVMG:
3876       {
3877         Image
3878           *image;
3879 
3880         /*
3881           Blessed scalar = (Image *) SvIV(reference)
3882         */
3883         image=INT2PTR(Image *,SvIV(reference));
3884         if (image != (Image *) NULL)
3885           DeleteImageFromRegistry(reference,image);
3886         break;
3887       }
3888       default:
3889         break;
3890     }
3891   }
3892 
3893 #
3894 ###############################################################################
3895 #                                                                             #
3896 #                                                                             #
3897 #                                                                             #
3898 #   D i s p l a y                                                             #
3899 #                                                                             #
3900 #                                                                             #
3901 #                                                                             #
3902 ###############################################################################
3903 #
3904 #
3905 void
Display(ref,...)3906 Display(ref,...)
3907   Image::Magick ref=NO_INIT
3908   ALIAS:
3909     DisplayImage  = 1
3910     display       = 2
3911     displayimage  = 3
3912   PPCODE:
3913   {
3914     ExceptionInfo
3915       *exception;
3916 
3917     Image
3918       *image;
3919 
3920     register ssize_t
3921       i;
3922 
3923     struct PackageInfo
3924       *info,
3925       *package_info;
3926 
3927     SV
3928       *perl_exception,
3929       *reference;
3930 
3931     PERL_UNUSED_VAR(ref);
3932     PERL_UNUSED_VAR(ix);
3933     exception=AcquireExceptionInfo();
3934     perl_exception=newSVpv("",0);
3935     package_info=(struct PackageInfo *) NULL;
3936     if (sv_isobject(ST(0)) == 0)
3937       {
3938         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3939           PackageName);
3940         goto PerlException;
3941       }
3942     reference=SvRV(ST(0));
3943     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3944     if (image == (Image *) NULL)
3945       {
3946         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3947           PackageName);
3948         goto PerlException;
3949       }
3950     package_info=ClonePackageInfo(info,exception);
3951     if (items == 2)
3952       SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3953     else
3954       if (items > 2)
3955         for (i=2; i < items; i+=2)
3956           SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3957             exception);
3958     (void) DisplayImages(package_info->image_info,image,exception);
3959     (void) CatchImageException(image);
3960 
3961   PerlException:
3962     if (package_info != (struct PackageInfo *) NULL)
3963       DestroyPackageInfo(package_info);
3964     InheritPerlException(exception,perl_exception);
3965     exception=DestroyExceptionInfo(exception);
3966     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3967     SvPOK_on(perl_exception);
3968     ST(0)=sv_2mortal(perl_exception);
3969     XSRETURN(1);
3970   }
3971 
3972 #
3973 ###############################################################################
3974 #                                                                             #
3975 #                                                                             #
3976 #                                                                             #
3977 #   E v a l u a t e I m a g e s                                               #
3978 #                                                                             #
3979 #                                                                             #
3980 #                                                                             #
3981 ###############################################################################
3982 #
3983 #
3984 void
EvaluateImages(ref)3985 EvaluateImages(ref)
3986   Image::Magick ref=NO_INIT
3987   ALIAS:
3988     EvaluateImages   = 1
3989     evaluateimages   = 2
3990   PPCODE:
3991   {
3992     AV
3993       *av;
3994 
3995     char
3996       *attribute,
3997       *p;
3998 
3999     ExceptionInfo
4000       *exception;
4001 
4002     HV
4003       *hv;
4004 
4005     Image
4006       *image;
4007 
4008     MagickEvaluateOperator
4009       op;
4010 
4011     register ssize_t
4012       i;
4013 
4014     struct PackageInfo
4015       *info;
4016 
4017     SV
4018       *perl_exception,
4019       *reference,
4020       *rv,
4021       *sv;
4022 
4023     PERL_UNUSED_VAR(ref);
4024     PERL_UNUSED_VAR(ix);
4025     exception=AcquireExceptionInfo();
4026     perl_exception=newSVpv("",0);
4027     sv=NULL;
4028     if (sv_isobject(ST(0)) == 0)
4029       {
4030         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4031           PackageName);
4032         goto PerlException;
4033       }
4034     reference=SvRV(ST(0));
4035     hv=SvSTASH(reference);
4036     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4037     if (image == (Image *) NULL)
4038       {
4039         ThrowPerlException(exception,OptionError,"NoImagesDefined",
4040           PackageName);
4041         goto PerlException;
4042       }
4043     op=MeanEvaluateOperator;
4044     if (items == 2)
4045       {
4046         ssize_t
4047           in;
4048 
4049         in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
4050           SvPV(ST(1),na));
4051         if (in < 0)
4052           {
4053             ThrowPerlException(exception,OptionError,"UnrecognizedType",
4054               SvPV(ST(1),na));
4055             return;
4056           }
4057         op=(MagickEvaluateOperator) in;
4058       }
4059     else
4060       for (i=2; i < items; i+=2)
4061       {
4062         attribute=(char *) SvPV(ST(i-1),na);
4063         switch (*attribute)
4064         {
4065           case 'O':
4066           case 'o':
4067           {
4068             if (LocaleCompare(attribute,"operator") == 0)
4069               {
4070                 ssize_t
4071                   in;
4072 
4073                 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
4074                   MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
4075                 if (in < 0)
4076                   {
4077                     ThrowPerlException(exception,OptionError,"UnrecognizedType",
4078                       SvPV(ST(i),na));
4079                     return;
4080                   }
4081                 op=(MagickEvaluateOperator) in;
4082                 break;
4083               }
4084             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4085               attribute);
4086             break;
4087           }
4088           default:
4089           {
4090             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4091               attribute);
4092             break;
4093           }
4094         }
4095       }
4096     image=EvaluateImages(image,op,exception);
4097     if (image == (Image *) NULL)
4098       goto PerlException;
4099     /*
4100       Create blessed Perl array for the returned image.
4101     */
4102     av=newAV();
4103     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4104     SvREFCNT_dec(av);
4105     AddImageToRegistry(sv,image);
4106     rv=newRV(sv);
4107     av_push(av,sv_bless(rv,hv));
4108     SvREFCNT_dec(sv);
4109     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4110     (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4111       "evaluate-%.*s",(int) (MagickPathExtent-9),
4112       ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4113     (void) CopyMagickString(image->filename,info->image_info->filename,
4114       MagickPathExtent);
4115     SetImageInfo(info->image_info,0,exception);
4116     exception=DestroyExceptionInfo(exception);
4117     SvREFCNT_dec(perl_exception);
4118     XSRETURN(1);
4119 
4120   PerlException:
4121     InheritPerlException(exception,perl_exception);
4122     exception=DestroyExceptionInfo(exception);
4123     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4124     SvPOK_on(perl_exception);
4125     ST(0)=sv_2mortal(perl_exception);
4126     XSRETURN(1);
4127   }
4128 
4129 #
4130 ###############################################################################
4131 #                                                                             #
4132 #                                                                             #
4133 #                                                                             #
4134 #   F e a t u r e s                                                           #
4135 #                                                                             #
4136 #                                                                             #
4137 #                                                                             #
4138 ###############################################################################
4139 #
4140 #
4141 void
Features(ref,...)4142 Features(ref,...)
4143   Image::Magick ref=NO_INIT
4144   ALIAS:
4145     FeaturesImage = 1
4146     features      = 2
4147     featuresimage = 3
4148   PPCODE:
4149   {
4150 #define ChannelFeatures(channel,direction) \
4151 { \
4152   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4153     channel_features[channel].angular_second_moment[direction]); \
4154   PUSHs(sv_2mortal(newSVpv(message,0))); \
4155   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4156     channel_features[channel].contrast[direction]); \
4157   PUSHs(sv_2mortal(newSVpv(message,0))); \
4158   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4159     channel_features[channel].contrast[direction]); \
4160   PUSHs(sv_2mortal(newSVpv(message,0))); \
4161   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4162     channel_features[channel].variance_sum_of_squares[direction]); \
4163   PUSHs(sv_2mortal(newSVpv(message,0))); \
4164   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4165     channel_features[channel].inverse_difference_moment[direction]); \
4166   PUSHs(sv_2mortal(newSVpv(message,0))); \
4167   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4168     channel_features[channel].sum_average[direction]); \
4169   PUSHs(sv_2mortal(newSVpv(message,0))); \
4170   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4171     channel_features[channel].sum_variance[direction]); \
4172   PUSHs(sv_2mortal(newSVpv(message,0))); \
4173   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4174     channel_features[channel].sum_entropy[direction]); \
4175   PUSHs(sv_2mortal(newSVpv(message,0))); \
4176   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4177     channel_features[channel].entropy[direction]); \
4178   PUSHs(sv_2mortal(newSVpv(message,0))); \
4179   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4180     channel_features[channel].difference_variance[direction]); \
4181   PUSHs(sv_2mortal(newSVpv(message,0))); \
4182   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4183     channel_features[channel].difference_entropy[direction]); \
4184   PUSHs(sv_2mortal(newSVpv(message,0))); \
4185   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4186     channel_features[channel].measure_of_correlation_1[direction]); \
4187   PUSHs(sv_2mortal(newSVpv(message,0))); \
4188   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4189     channel_features[channel].measure_of_correlation_2[direction]); \
4190   PUSHs(sv_2mortal(newSVpv(message,0))); \
4191   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
4192     channel_features[channel].maximum_correlation_coefficient[direction]); \
4193   PUSHs(sv_2mortal(newSVpv(message,0))); \
4194 }
4195 
4196     AV
4197       *av;
4198 
4199     char
4200       *attribute,
4201       message[MagickPathExtent];
4202 
4203     ChannelFeatures
4204       *channel_features;
4205 
4206     double
4207       distance;
4208 
4209     ExceptionInfo
4210       *exception;
4211 
4212     Image
4213       *image;
4214 
4215     register ssize_t
4216       i;
4217 
4218     ssize_t
4219       count;
4220 
4221     struct PackageInfo
4222       *info;
4223 
4224     SV
4225       *perl_exception,
4226       *reference;
4227 
4228     PERL_UNUSED_VAR(ref);
4229     PERL_UNUSED_VAR(ix);
4230     exception=AcquireExceptionInfo();
4231     perl_exception=newSVpv("",0);
4232     av=NULL;
4233     if (sv_isobject(ST(0)) == 0)
4234       {
4235         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4236           PackageName);
4237         goto PerlException;
4238       }
4239     reference=SvRV(ST(0));
4240     av=newAV();
4241     SvREFCNT_dec(av);
4242     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4243     if (image == (Image *) NULL)
4244       {
4245         ThrowPerlException(exception,OptionError,"NoImagesDefined",
4246           PackageName);
4247         goto PerlException;
4248       }
4249     distance=1.0;
4250     for (i=2; i < items; i+=2)
4251     {
4252       attribute=(char *) SvPV(ST(i-1),na);
4253       switch (*attribute)
4254       {
4255         case 'D':
4256         case 'd':
4257         {
4258           if (LocaleCompare(attribute,"distance") == 0)
4259             {
4260               distance=StringToLong((char *) SvPV(ST(1),na));
4261               break;
4262             }
4263           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4264             attribute);
4265           break;
4266         }
4267         default:
4268         {
4269           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4270             attribute);
4271           break;
4272         }
4273       }
4274     }
4275     count=0;
4276     for ( ; image; image=image->next)
4277     {
4278       register ssize_t
4279         j;
4280 
4281       channel_features=GetImageFeatures(image,distance,exception);
4282       if (channel_features == (ChannelFeatures *) NULL)
4283         continue;
4284       count++;
4285       for (j=0; j < 4; j++)
4286       {
4287         for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
4288         {
4289           PixelChannel channel=GetPixelChannelChannel(image,i);
4290           PixelTrait traits=GetPixelChannelTraits(image,channel);
4291           if (traits == UndefinedPixelTrait)
4292             continue;
4293           EXTEND(sp,14*(i+1)*count);
4294           ChannelFeatures(channel,j);
4295         }
4296       }
4297       channel_features=(ChannelFeatures *)
4298         RelinquishMagickMemory(channel_features);
4299     }
4300 
4301   PerlException:
4302     InheritPerlException(exception,perl_exception);
4303     exception=DestroyExceptionInfo(exception);
4304     SvREFCNT_dec(perl_exception);
4305   }
4306 
4307 #
4308 ###############################################################################
4309 #                                                                             #
4310 #                                                                             #
4311 #                                                                             #
4312 #   F l a t t e n                                                             #
4313 #                                                                             #
4314 #                                                                             #
4315 #                                                                             #
4316 ###############################################################################
4317 #
4318 #
4319 void
Flatten(ref)4320 Flatten(ref)
4321   Image::Magick ref=NO_INIT
4322   ALIAS:
4323     FlattenImage   = 1
4324     flatten        = 2
4325     flattenimage   = 3
4326   PPCODE:
4327   {
4328     AV
4329       *av;
4330 
4331     char
4332       *attribute,
4333       *p;
4334 
4335     ExceptionInfo
4336       *exception;
4337 
4338     HV
4339       *hv;
4340 
4341     Image
4342       *image;
4343 
4344     PixelInfo
4345       background_color;
4346 
4347     register ssize_t
4348       i;
4349 
4350     struct PackageInfo
4351       *info;
4352 
4353     SV
4354       *perl_exception,
4355       *reference,
4356       *rv,
4357       *sv;
4358 
4359     PERL_UNUSED_VAR(ref);
4360     PERL_UNUSED_VAR(ix);
4361     exception=AcquireExceptionInfo();
4362     perl_exception=newSVpv("",0);
4363     sv=NULL;
4364     if (sv_isobject(ST(0)) == 0)
4365       {
4366         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4367           PackageName);
4368         goto PerlException;
4369       }
4370     reference=SvRV(ST(0));
4371     hv=SvSTASH(reference);
4372     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4373     if (image == (Image *) NULL)
4374       {
4375         ThrowPerlException(exception,OptionError,"NoImagesDefined",
4376           PackageName);
4377         goto PerlException;
4378       }
4379     background_color=image->background_color;
4380     if (items == 2)
4381       (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4382         &background_color,exception);
4383     else
4384       for (i=2; i < items; i+=2)
4385       {
4386         attribute=(char *) SvPV(ST(i-1),na);
4387         switch (*attribute)
4388         {
4389           case 'B':
4390           case 'b':
4391           {
4392             if (LocaleCompare(attribute,"background") == 0)
4393               {
4394                 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4395                   AllCompliance,&background_color,exception);
4396                 break;
4397               }
4398             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4399               attribute);
4400             break;
4401           }
4402           default:
4403           {
4404             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4405               attribute);
4406             break;
4407           }
4408         }
4409       }
4410     image->background_color=background_color;
4411     image=MergeImageLayers(image,FlattenLayer,exception);
4412     if (image == (Image *) NULL)
4413       goto PerlException;
4414     /*
4415       Create blessed Perl array for the returned image.
4416     */
4417     av=newAV();
4418     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4419     SvREFCNT_dec(av);
4420     AddImageToRegistry(sv,image);
4421     rv=newRV(sv);
4422     av_push(av,sv_bless(rv,hv));
4423     SvREFCNT_dec(sv);
4424     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4425     (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4426       "flatten-%.*s",(int) (MagickPathExtent-9),
4427       ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4428     (void) CopyMagickString(image->filename,info->image_info->filename,
4429       MagickPathExtent);
4430     SetImageInfo(info->image_info,0,exception);
4431     exception=DestroyExceptionInfo(exception);
4432     SvREFCNT_dec(perl_exception);
4433     XSRETURN(1);
4434 
4435   PerlException:
4436     InheritPerlException(exception,perl_exception);
4437     exception=DestroyExceptionInfo(exception);
4438     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4439     SvPOK_on(perl_exception);  /* return messages in string context */
4440     ST(0)=sv_2mortal(perl_exception);
4441     XSRETURN(1);
4442   }
4443 
4444 #
4445 ###############################################################################
4446 #                                                                             #
4447 #                                                                             #
4448 #                                                                             #
4449 #   F x                                                                       #
4450 #                                                                             #
4451 #                                                                             #
4452 #                                                                             #
4453 ###############################################################################
4454 #
4455 #
4456 void
Fx(ref,...)4457 Fx(ref,...)
4458   Image::Magick ref=NO_INIT
4459   ALIAS:
4460     FxImage  = 1
4461     fx       = 2
4462     fximage  = 3
4463   PPCODE:
4464   {
4465     AV
4466       *av;
4467 
4468     char
4469       *attribute,
4470       expression[MagickPathExtent];
4471 
4472     ChannelType
4473       channel,
4474       channel_mask;
4475 
4476     ExceptionInfo
4477       *exception;
4478 
4479     HV
4480       *hv;
4481 
4482     Image
4483       *image;
4484 
4485     register ssize_t
4486       i;
4487 
4488     struct PackageInfo
4489       *info;
4490 
4491     SV
4492       *av_reference,
4493       *perl_exception,
4494       *reference,
4495       *rv,
4496       *sv;
4497 
4498     PERL_UNUSED_VAR(ref);
4499     PERL_UNUSED_VAR(ix);
4500     exception=AcquireExceptionInfo();
4501     perl_exception=newSVpv("",0);
4502     sv=NULL;
4503     attribute=NULL;
4504     av=NULL;
4505     if (sv_isobject(ST(0)) == 0)
4506       {
4507         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4508           PackageName);
4509         goto PerlException;
4510       }
4511     reference=SvRV(ST(0));
4512     hv=SvSTASH(reference);
4513     av=newAV();
4514     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4515     SvREFCNT_dec(av);
4516     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4517     if (image == (Image *) NULL)
4518       {
4519         ThrowPerlException(exception,OptionError,"NoImagesDefined",
4520           PackageName);
4521         goto PerlException;
4522       }
4523     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4524     /*
4525       Get options.
4526     */
4527     channel=DefaultChannels;
4528     (void) CopyMagickString(expression,"u",MagickPathExtent);
4529     if (items == 2)
4530       (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
4531     else
4532       for (i=2; i < items; i+=2)
4533       {
4534         attribute=(char *) SvPV(ST(i-1),na);
4535         switch (*attribute)
4536         {
4537           case 'C':
4538           case 'c':
4539           {
4540             if (LocaleCompare(attribute,"channel") == 0)
4541               {
4542                 ssize_t
4543                   option;
4544 
4545                 option=ParseChannelOption(SvPV(ST(i),na));
4546                 if (option < 0)
4547                   {
4548                     ThrowPerlException(exception,OptionError,
4549                       "UnrecognizedType",SvPV(ST(i),na));
4550                     return;
4551                   }
4552                 channel=(ChannelType) option;
4553                 break;
4554               }
4555             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4556               attribute);
4557             break;
4558           }
4559           case 'E':
4560           case 'e':
4561           {
4562             if (LocaleCompare(attribute,"expression") == 0)
4563               {
4564                 (void) CopyMagickString(expression,SvPV(ST(i),na),
4565                   MagickPathExtent);
4566                 break;
4567               }
4568             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4569               attribute);
4570             break;
4571           }
4572           default:
4573           {
4574             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4575               attribute);
4576             break;
4577           }
4578         }
4579       }
4580     channel_mask=SetImageChannelMask(image,channel);
4581     image=FxImage(image,expression,exception);
4582     if (image != (Image *) NULL)
4583       (void) SetImageChannelMask(image,channel_mask);
4584     if (image == (Image *) NULL)
4585       goto PerlException;
4586     for ( ; image; image=image->next)
4587     {
4588       AddImageToRegistry(sv,image);
4589       rv=newRV(sv);
4590       av_push(av,sv_bless(rv,hv));
4591       SvREFCNT_dec(sv);
4592     }
4593     exception=DestroyExceptionInfo(exception);
4594     ST(0)=av_reference;
4595     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
4596     XSRETURN(1);
4597 
4598   PerlException:
4599     InheritPerlException(exception,perl_exception);
4600     exception=DestroyExceptionInfo(exception);
4601     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4602     SvPOK_on(perl_exception);
4603     ST(0)=sv_2mortal(perl_exception);
4604     XSRETURN(1);
4605   }
4606 
4607 #
4608 ###############################################################################
4609 #                                                                             #
4610 #                                                                             #
4611 #                                                                             #
4612 #   G e t                                                                     #
4613 #                                                                             #
4614 #                                                                             #
4615 #                                                                             #
4616 ###############################################################################
4617 #
4618 #
4619 void
Get(ref,...)4620 Get(ref,...)
4621   Image::Magick ref=NO_INIT
4622   ALIAS:
4623     GetAttributes = 1
4624     GetAttribute  = 2
4625     get           = 3
4626     getattributes = 4
4627     getattribute  = 5
4628   PPCODE:
4629   {
4630     char
4631       *attribute,
4632       color[MagickPathExtent];
4633 
4634     const char
4635       *value;
4636 
4637     ExceptionInfo
4638       *exception;
4639 
4640     Image
4641       *image;
4642 
4643     long
4644       j;
4645 
4646     register ssize_t
4647       i;
4648 
4649     struct PackageInfo
4650       *info;
4651 
4652     SV
4653       *perl_exception,
4654       *reference,
4655       *s;
4656 
4657     PERL_UNUSED_VAR(ref);
4658     PERL_UNUSED_VAR(ix);
4659     exception=AcquireExceptionInfo();
4660     perl_exception=newSVpv("",0);
4661     if (sv_isobject(ST(0)) == 0)
4662       {
4663         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4664           PackageName);
4665         XSRETURN_EMPTY;
4666       }
4667     reference=SvRV(ST(0));
4668     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4669     if (image == (Image *) NULL && !info)
4670       XSRETURN_EMPTY;
4671     EXTEND(sp,items);
4672     for (i=1; i < items; i++)
4673     {
4674       attribute=(char *) SvPV(ST(i),na);
4675       s=NULL;
4676       switch (*attribute)
4677       {
4678         case 'A':
4679         case 'a':
4680         {
4681           if (LocaleCompare(attribute,"adjoin") == 0)
4682             {
4683               if (info)
4684                 s=newSViv((ssize_t) info->image_info->adjoin);
4685               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4686               continue;
4687             }
4688           if (LocaleCompare(attribute,"antialias") == 0)
4689             {
4690               if (info)
4691                 s=newSViv((ssize_t) info->image_info->antialias);
4692               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4693               continue;
4694             }
4695           if (LocaleCompare(attribute,"area") == 0)
4696             {
4697               s=newSViv(GetMagickResource(AreaResource));
4698               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4699               continue;
4700             }
4701           if (LocaleCompare(attribute,"attenuate") == 0)
4702             {
4703               const char
4704                 *value;
4705 
4706               value=GetImageProperty(image,attribute,exception);
4707               if (value != (const char *) NULL)
4708                 s=newSVpv(value,0);
4709               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4710               continue;
4711             }
4712           if (LocaleCompare(attribute,"authenticate") == 0)
4713             {
4714               if (info)
4715                 {
4716                   const char
4717                     *option;
4718 
4719                   option=GetImageOption(info->image_info,attribute);
4720                   if (option != (const char *) NULL)
4721                     s=newSVpv(option,0);
4722                 }
4723               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4724               continue;
4725             }
4726           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4727             attribute);
4728           break;
4729         }
4730         case 'B':
4731         case 'b':
4732         {
4733           if (LocaleCompare(attribute,"background") == 0)
4734             {
4735               if (image == (Image *) NULL)
4736                 break;
4737               (void) FormatLocaleString(color,MagickPathExtent,
4738                 "%.20g,%.20g,%.20g,%.20g",(double) image->background_color.red,
4739                 (double) image->background_color.green,
4740                 (double) image->background_color.blue,
4741                 (double) image->background_color.alpha);
4742               s=newSVpv(color,0);
4743               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4744               continue;
4745             }
4746           if (LocaleCompare(attribute,"base-columns") == 0)
4747             {
4748               if (image != (Image *) NULL)
4749                 s=newSViv((ssize_t) image->magick_columns);
4750               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4751               continue;
4752             }
4753           if (LocaleCompare(attribute,"base-filename") == 0)
4754             {
4755               if (image != (Image *) NULL)
4756                 s=newSVpv(image->magick_filename,0);
4757               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4758               continue;
4759             }
4760           if (LocaleCompare(attribute,"base-height") == 0)
4761             {
4762               if (image != (Image *) NULL)
4763                 s=newSViv((ssize_t) image->magick_rows);
4764               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4765               continue;
4766             }
4767           if (LocaleCompare(attribute,"base-rows") == 0)
4768             {
4769               if (image != (Image *) NULL)
4770                 s=newSViv((ssize_t) image->magick_rows);
4771               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4772               continue;
4773             }
4774           if (LocaleCompare(attribute,"base-width") == 0)
4775             {
4776               if (image != (Image *) NULL)
4777                 s=newSViv((ssize_t) image->magick_columns);
4778               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4779               continue;
4780             }
4781           if (LocaleCompare(attribute,"blue-primary") == 0)
4782             {
4783               if (image == (Image *) NULL)
4784                 break;
4785               (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
4786                 image->chromaticity.blue_primary.x,
4787                 image->chromaticity.blue_primary.y);
4788               s=newSVpv(color,0);
4789               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4790               continue;
4791             }
4792           if (LocaleCompare(attribute,"bordercolor") == 0)
4793             {
4794               if (image == (Image *) NULL)
4795                 break;
4796               (void) FormatLocaleString(color,MagickPathExtent,
4797                 "%.20g,%.20g,%.20g,%.20g",(double) image->border_color.red,
4798                 (double) image->border_color.green,
4799                 (double) image->border_color.blue,
4800                 (double) image->border_color.alpha);
4801               s=newSVpv(color,0);
4802               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4803               continue;
4804             }
4805           if (LocaleCompare(attribute,"bounding-box") == 0)
4806             {
4807               char
4808                 geometry[MagickPathExtent];
4809 
4810               RectangleInfo
4811                 page;
4812 
4813               if (image == (Image *) NULL)
4814                 break;
4815               page=GetImageBoundingBox(image,exception);
4816               (void) FormatLocaleString(geometry,MagickPathExtent,
4817                 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4818                 page.height,(double) page.x,(double) page.y);
4819               s=newSVpv(geometry,0);
4820               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4821               continue;
4822             }
4823           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4824             attribute);
4825           break;
4826         }
4827         case 'C':
4828         case 'c':
4829         {
4830           if (LocaleCompare(attribute,"class") == 0)
4831             {
4832               if (image == (Image *) NULL)
4833                 break;
4834               s=newSViv(image->storage_class);
4835               (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4836                 image->storage_class));
4837               SvIOK_on(s);
4838               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4839               continue;
4840             }
4841           if (LocaleCompare(attribute,"clip-mask") == 0)
4842             {
4843               if (image != (Image *) NULL)
4844                 {
4845                   Image
4846                     *mask_image;
4847 
4848                   SV
4849                     *sv;
4850 
4851                   sv=NULL;
4852                   if (image->read_mask == MagickFalse)
4853                     ClipImage(image,exception);
4854                   mask_image=GetImageMask(image,ReadPixelMask,exception);
4855                   if (mask_image != (Image *) NULL)
4856                     {
4857                       AddImageToRegistry(sv,mask_image);
4858                       s=sv_bless(newRV(sv),SvSTASH(reference));
4859                     }
4860                 }
4861               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4862               continue;
4863             }
4864           if (LocaleCompare(attribute,"clip-path") == 0)
4865             {
4866               if (image != (Image *) NULL)
4867                 {
4868                   Image
4869                     *mask_image;
4870 
4871                   SV
4872                     *sv;
4873 
4874                   sv=NULL;
4875                   if (image->read_mask != MagickFalse)
4876                     ClipImage(image,exception);
4877                   mask_image=GetImageMask(image,ReadPixelMask,exception);
4878                   if (mask_image != (Image *) NULL)
4879                     {
4880                       AddImageToRegistry(sv,mask_image);
4881                       s=sv_bless(newRV(sv),SvSTASH(reference));
4882                     }
4883                 }
4884               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4885               continue;
4886             }
4887           if (LocaleCompare(attribute,"compression") == 0)
4888             {
4889               j=info ? info->image_info->compression : image ?
4890                 image->compression : UndefinedCompression;
4891               if (info)
4892                 if (info->image_info->compression == UndefinedCompression)
4893                   j=image->compression;
4894               s=newSViv(j);
4895               (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4896                 j));
4897               SvIOK_on(s);
4898               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4899               continue;
4900             }
4901           if (LocaleCompare(attribute,"colorspace") == 0)
4902             {
4903               j=image ? image->colorspace : RGBColorspace;
4904               s=newSViv(j);
4905               (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4906                 j));
4907               SvIOK_on(s);
4908               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4909               continue;
4910             }
4911           if (LocaleCompare(attribute,"colors") == 0)
4912             {
4913               if (image != (Image *) NULL)
4914                 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4915                   exception));
4916               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4917               continue;
4918             }
4919           if (LocaleNCompare(attribute,"colormap",8) == 0)
4920             {
4921               int
4922                 items;
4923 
4924               if (image == (Image *) NULL || !image->colormap)
4925                 break;
4926               j=0;
4927               items=sscanf(attribute,"%*[^[][%ld",&j);
4928               (void) items;
4929               if (j > (ssize_t) image->colors)
4930                 j%=image->colors;
4931               (void) FormatLocaleString(color,MagickPathExtent,
4932                 "%.20g,%.20g,%.20g,%.20g",(double) image->colormap[j].red,
4933                 (double) image->colormap[j].green,
4934                 (double) image->colormap[j].blue,
4935                 (double) image->colormap[j].alpha);
4936               s=newSVpv(color,0);
4937               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4938               continue;
4939             }
4940           if (LocaleCompare(attribute,"columns") == 0)
4941             {
4942               if (image != (Image *) NULL)
4943                 s=newSViv((ssize_t) image->columns);
4944               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4945               continue;
4946             }
4947           if (LocaleCompare(attribute,"comment") == 0)
4948             {
4949               const char
4950                 *value;
4951 
4952               value=GetImageProperty(image,attribute,exception);
4953               if (value != (const char *) NULL)
4954                 s=newSVpv(value,0);
4955               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4956               continue;
4957             }
4958           if (LocaleCompare(attribute,"copyright") == 0)
4959             {
4960               s=newSVpv(GetMagickCopyright(),0);
4961               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4962               continue;
4963             }
4964           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4965             attribute);
4966           break;
4967         }
4968         case 'D':
4969         case 'd':
4970         {
4971           if (LocaleCompare(attribute,"density") == 0)
4972             {
4973               char
4974                 geometry[MagickPathExtent];
4975 
4976               if (image == (Image *) NULL)
4977                 break;
4978               (void) FormatLocaleString(geometry,MagickPathExtent,"%.20gx%.20g",
4979                 image->resolution.x,image->resolution.y);
4980               s=newSVpv(geometry,0);
4981               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4982               continue;
4983             }
4984           if (LocaleCompare(attribute,"delay") == 0)
4985             {
4986               if (image != (Image *) NULL)
4987                 s=newSViv((ssize_t) image->delay);
4988               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4989               continue;
4990             }
4991           if (LocaleCompare(attribute,"depth") == 0)
4992             {
4993               s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4994               if (image != (Image *) NULL)
4995                 s=newSViv((ssize_t) GetImageDepth(image,exception));
4996               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4997               continue;
4998             }
4999           if (LocaleCompare(attribute,"directory") == 0)
5000             {
5001               if (image && image->directory)
5002                 s=newSVpv(image->directory,0);
5003               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5004               continue;
5005             }
5006           if (LocaleCompare(attribute,"dispose") == 0)
5007             {
5008               if (image == (Image *) NULL)
5009                 break;
5010 
5011               s=newSViv(image->dispose);
5012               (void) sv_setpv(s,
5013                 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
5014               SvIOK_on(s);
5015               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5016               continue;
5017             }
5018           if (LocaleCompare(attribute,"disk") == 0)
5019             {
5020               s=newSViv(GetMagickResource(DiskResource));
5021               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5022               continue;
5023             }
5024           if (LocaleCompare(attribute,"dither") == 0)
5025             {
5026               if (info)
5027                 s=newSViv((ssize_t) info->image_info->dither);
5028               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5029               continue;
5030             }
5031           if (LocaleCompare(attribute,"display") == 0)  /* same as server */
5032             {
5033               if (info && info->image_info->server_name)
5034                 s=newSVpv(info->image_info->server_name,0);
5035               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5036               continue;
5037             }
5038           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5039             attribute);
5040           break;
5041         }
5042         case 'E':
5043         case 'e':
5044         {
5045           if (LocaleCompare(attribute,"elapsed-time") == 0)
5046             {
5047               if (image != (Image *) NULL)
5048                 s=newSVnv(GetElapsedTime(&image->timer));
5049               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5050               continue;
5051             }
5052           if (LocaleCompare(attribute,"endian") == 0)
5053             {
5054               j=info ? info->image_info->endian : image ? image->endian :
5055                 UndefinedEndian;
5056               s=newSViv(j);
5057               (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
5058               SvIOK_on(s);
5059               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5060               continue;
5061             }
5062           if (LocaleCompare(attribute,"error") == 0)
5063             {
5064               if (image != (Image *) NULL)
5065                 s=newSVnv(image->error.mean_error_per_pixel);
5066               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5067               continue;
5068             }
5069           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5070             attribute);
5071           break;
5072         }
5073         case 'F':
5074         case 'f':
5075         {
5076           if (LocaleCompare(attribute,"filesize") == 0)
5077             {
5078               if (image != (Image *) NULL)
5079                 s=newSViv((ssize_t) GetBlobSize(image));
5080               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5081               continue;
5082             }
5083           if (LocaleCompare(attribute,"filename") == 0)
5084             {
5085               if (info && *info->image_info->filename)
5086                 s=newSVpv(info->image_info->filename,0);
5087               if (image != (Image *) NULL)
5088                 s=newSVpv(image->filename,0);
5089               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5090               continue;
5091             }
5092           if (LocaleCompare(attribute,"filter") == 0)
5093             {
5094               s=image ? newSViv(image->filter) : newSViv(0);
5095               (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
5096                 image->filter));
5097               SvIOK_on(s);
5098               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5099               continue;
5100             }
5101           if (LocaleCompare(attribute,"font") == 0)
5102             {
5103               if (info && info->image_info->font)
5104                 s=newSVpv(info->image_info->font,0);
5105               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5106               continue;
5107             }
5108           if (LocaleCompare(attribute,"foreground") == 0)
5109             continue;
5110           if (LocaleCompare(attribute,"format") == 0)
5111             {
5112               const MagickInfo
5113                 *magick_info;
5114 
5115               magick_info=(const MagickInfo *) NULL;
5116               if (info && (*info->image_info->magick != '\0'))
5117                 magick_info=GetMagickInfo(info->image_info->magick,exception);
5118               if (image != (Image *) NULL)
5119                 magick_info=GetMagickInfo(image->magick,exception);
5120               if ((magick_info != (const MagickInfo *) NULL) &&
5121                   (*magick_info->description != '\0'))
5122                 s=newSVpv((char *) magick_info->description,0);
5123               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5124               continue;
5125             }
5126           if (LocaleCompare(attribute,"fuzz") == 0)
5127             {
5128               if (info)
5129                 s=newSVnv(info->image_info->fuzz);
5130               if (image != (Image *) NULL)
5131                 s=newSVnv(image->fuzz);
5132               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5133               continue;
5134             }
5135           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5136             attribute);
5137           break;
5138         }
5139         case 'G':
5140         case 'g':
5141         {
5142           if (LocaleCompare(attribute,"gamma") == 0)
5143             {
5144               if (image != (Image *) NULL)
5145                 s=newSVnv(image->gamma);
5146               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5147               continue;
5148             }
5149           if (LocaleCompare(attribute,"geometry") == 0)
5150             {
5151               if (image && image->geometry)
5152                 s=newSVpv(image->geometry,0);
5153               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5154               continue;
5155             }
5156           if (LocaleCompare(attribute,"gravity") == 0)
5157             {
5158               s=image ? newSViv(image->gravity) : newSViv(0);
5159               (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
5160                 image->gravity));
5161               SvIOK_on(s);
5162               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5163               continue;
5164             }
5165           if (LocaleCompare(attribute,"green-primary") == 0)
5166             {
5167               if (image == (Image *) NULL)
5168                 break;
5169               (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
5170                 image->chromaticity.green_primary.x,
5171                 image->chromaticity.green_primary.y);
5172               s=newSVpv(color,0);
5173               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5174               continue;
5175             }
5176           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5177             attribute);
5178           break;
5179         }
5180         case 'H':
5181         case 'h':
5182         {
5183           if (LocaleCompare(attribute,"height") == 0)
5184             {
5185               if (image != (Image *) NULL)
5186                 s=newSViv((ssize_t) image->rows);
5187               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5188               continue;
5189             }
5190           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5191             attribute);
5192           break;
5193         }
5194         case 'I':
5195         case 'i':
5196         {
5197           if (LocaleCompare(attribute,"icc") == 0)
5198             {
5199               if (image != (Image *) NULL)
5200                 {
5201                   const StringInfo
5202                     *profile;
5203 
5204                   profile=GetImageProfile(image,"icc");
5205                   if (profile != (StringInfo *) NULL)
5206                     s=newSVpv((const char *) GetStringInfoDatum(profile),
5207                       GetStringInfoLength(profile));
5208                 }
5209               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5210               continue;
5211             }
5212           if (LocaleCompare(attribute,"icm") == 0)
5213             {
5214               if (image != (Image *) NULL)
5215                 {
5216                   const StringInfo
5217                     *profile;
5218 
5219                   profile=GetImageProfile(image,"icm");
5220                   if (profile != (const StringInfo *) NULL)
5221                     s=newSVpv((const char *) GetStringInfoDatum(profile),
5222                       GetStringInfoLength(profile));
5223                 }
5224               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5225               continue;
5226             }
5227           if (LocaleCompare(attribute,"id") == 0)
5228             {
5229               if (image != (Image *) NULL)
5230                 {
5231                   char
5232                     key[MagickPathExtent];
5233 
5234                   MagickBooleanType
5235                     status;
5236 
5237                   static ssize_t
5238                     id = 0;
5239 
5240                   (void) FormatLocaleString(key,MagickPathExtent,"%.20g\n",(double)
5241                     id);
5242                   status=SetImageRegistry(ImageRegistryType,key,image,
5243                     exception);
5244                   (void) status;
5245                   s=newSViv(id++);
5246                 }
5247               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5248               continue;
5249             }
5250           if (LocaleNCompare(attribute,"index",5) == 0)
5251             {
5252               char
5253                 name[MagickPathExtent];
5254 
5255               int
5256                 items;
5257 
5258               long
5259                 x,
5260                 y;
5261 
5262               register const Quantum
5263                 *p;
5264 
5265               CacheView
5266                 *image_view;
5267 
5268               if (image == (Image *) NULL)
5269                 break;
5270               if (image->storage_class != PseudoClass)
5271                 break;
5272               x=0;
5273               y=0;
5274               items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5275               (void) items;
5276               image_view=AcquireVirtualCacheView(image,exception);
5277               p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5278               if (p != (const Quantum *) NULL)
5279                 {
5280                   (void) FormatLocaleString(name,MagickPathExtent,QuantumFormat,
5281                     GetPixelIndex(image,p));
5282                   s=newSVpv(name,0);
5283                   PUSHs(s ? sv_2mortal(s) : &sv_undef);
5284                 }
5285               image_view=DestroyCacheView(image_view);
5286               continue;
5287             }
5288           if (LocaleCompare(attribute,"iptc") == 0)
5289             {
5290               if (image != (Image *) NULL)
5291                 {
5292                   const StringInfo
5293                     *profile;
5294 
5295                   profile=GetImageProfile(image,"iptc");
5296                   if (profile != (const StringInfo *) NULL)
5297                     s=newSVpv((const char *) GetStringInfoDatum(profile),
5298                       GetStringInfoLength(profile));
5299                 }
5300               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5301               continue;
5302             }
5303           if (LocaleCompare(attribute,"iterations") == 0)  /* same as loop */
5304             {
5305               if (image != (Image *) NULL)
5306                 s=newSViv((ssize_t) image->iterations);
5307               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5308               continue;
5309             }
5310           if (LocaleCompare(attribute,"interlace") == 0)
5311             {
5312               j=info ? info->image_info->interlace : image ? image->interlace :
5313                 UndefinedInterlace;
5314               s=newSViv(j);
5315               (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5316                 j));
5317               SvIOK_on(s);
5318               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5319               continue;
5320             }
5321           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5322             attribute);
5323           break;
5324         }
5325         case 'L':
5326         case 'l':
5327         {
5328           if (LocaleCompare(attribute,"label") == 0)
5329             {
5330               const char
5331                 *value;
5332 
5333               if (image == (Image *) NULL)
5334                 break;
5335               value=GetImageProperty(image,"Label",exception);
5336               if (value != (const char *) NULL)
5337                 s=newSVpv(value,0);
5338               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5339               continue;
5340             }
5341           if (LocaleCompare(attribute,"loop") == 0)  /* same as iterations */
5342             {
5343               if (image != (Image *) NULL)
5344                 s=newSViv((ssize_t) image->iterations);
5345               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5346               continue;
5347             }
5348           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5349             attribute);
5350           break;
5351         }
5352         case 'M':
5353         case 'm':
5354         {
5355           if (LocaleCompare(attribute,"magick") == 0)
5356             {
5357               if (info && *info->image_info->magick)
5358                 s=newSVpv(info->image_info->magick,0);
5359               if (image != (Image *) NULL)
5360                 s=newSVpv(image->magick,0);
5361               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5362               continue;
5363             }
5364           if (LocaleCompare(attribute,"map") == 0)
5365             {
5366               s=newSViv(GetMagickResource(MapResource));
5367               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5368               continue;
5369             }
5370           if (LocaleCompare(attribute,"maximum-error") == 0)
5371             {
5372               if (image != (Image *) NULL)
5373                 s=newSVnv(image->error.normalized_maximum_error);
5374               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5375               continue;
5376             }
5377           if (LocaleCompare(attribute,"memory") == 0)
5378             {
5379               s=newSViv(GetMagickResource(MemoryResource));
5380               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5381               continue;
5382             }
5383           if (LocaleCompare(attribute,"mean-error") == 0)
5384             {
5385               if (image != (Image *) NULL)
5386                 s=newSVnv(image->error.normalized_mean_error);
5387               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5388               continue;
5389             }
5390           if (LocaleCompare(attribute,"mime") == 0)
5391             {
5392               if (info && *info->image_info->magick)
5393                 s=newSVpv(MagickToMime(info->image_info->magick),0);
5394               if (image != (Image *) NULL)
5395                 s=newSVpv(MagickToMime(image->magick),0);
5396               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5397               continue;
5398             }
5399           if (LocaleCompare(attribute,"mattecolor") == 0)
5400             {
5401               if (image == (Image *) NULL)
5402                 break;
5403               (void) FormatLocaleString(color,MagickPathExtent,
5404                 "%.20g,%.20g,%.20g,%.20g",(double) image->alpha_color.red,
5405                 (double) image->alpha_color.green,
5406                 (double) image->alpha_color.blue,
5407                 (double) image->alpha_color.alpha);
5408               s=newSVpv(color,0);
5409               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5410               continue;
5411             }
5412           if (LocaleCompare(attribute,"matte") == 0)
5413             {
5414               if (image != (Image *) NULL)
5415                 s=newSViv((ssize_t) image->alpha_trait != UndefinedPixelTrait ?
5416                   1 : 0);
5417               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5418               continue;
5419             }
5420           if (LocaleCompare(attribute,"mime") == 0)
5421             {
5422               const char
5423                 *magick;
5424 
5425               magick=NULL;
5426               if (info && *info->image_info->magick)
5427                 magick=info->image_info->magick;
5428               if (image != (Image *) NULL)
5429                 magick=image->magick;
5430               if (magick)
5431                 {
5432                   char
5433                     *mime;
5434 
5435                   mime=MagickToMime(magick);
5436                   s=newSVpv(mime,0);
5437                   mime=(char *) RelinquishMagickMemory(mime);
5438                 }
5439               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5440               continue;
5441             }
5442           if (LocaleCompare(attribute,"monochrome") == 0)
5443             {
5444               if (image == (Image *) NULL)
5445                 continue;
5446               j=info ? info->image_info->monochrome :
5447                 SetImageMonochrome(image,exception);
5448               s=newSViv(j);
5449               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5450               continue;
5451             }
5452           if (LocaleCompare(attribute,"montage") == 0)
5453             {
5454               if (image && image->montage)
5455                 s=newSVpv(image->montage,0);
5456               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5457               continue;
5458             }
5459           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5460             attribute);
5461           break;
5462         }
5463         case 'O':
5464         case 'o':
5465         {
5466           if (LocaleCompare(attribute,"orientation") == 0)
5467             {
5468               j=info ? info->image_info->orientation : image ?
5469                 image->orientation : UndefinedOrientation;
5470               s=newSViv(j);
5471               (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5472                 j));
5473               SvIOK_on(s);
5474               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5475               continue;
5476             }
5477           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5478             attribute);
5479           break;
5480         }
5481         case 'P':
5482         case 'p':
5483         {
5484           if (LocaleCompare(attribute,"page") == 0)
5485             {
5486               if (info && info->image_info->page)
5487                 s=newSVpv(info->image_info->page,0);
5488               if (image != (Image *) NULL)
5489                 {
5490                   char
5491                     geometry[MagickPathExtent];
5492 
5493                   (void) FormatLocaleString(geometry,MagickPathExtent,
5494                     "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5495                     (double) image->page.height,(double) image->page.x,(double)
5496                     image->page.y);
5497                   s=newSVpv(geometry,0);
5498                 }
5499               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5500               continue;
5501             }
5502           if (LocaleCompare(attribute,"page.x") == 0)
5503             {
5504               if (image != (Image *) NULL)
5505                 s=newSViv((ssize_t) image->page.x);
5506               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5507               continue;
5508             }
5509           if (LocaleCompare(attribute,"page.y") == 0)
5510             {
5511               if (image != (Image *) NULL)
5512                 s=newSViv((ssize_t) image->page.y);
5513               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5514               continue;
5515             }
5516           if (LocaleNCompare(attribute,"pixel",5) == 0)
5517             {
5518               char
5519                 tuple[MagickPathExtent];
5520 
5521               int
5522                 items;
5523 
5524               long
5525                 x,
5526                 y;
5527 
5528               register const Quantum
5529                 *p;
5530 
5531               if (image == (Image *) NULL)
5532                 break;
5533               x=0;
5534               y=0;
5535               items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5536               (void) items;
5537               p=GetVirtualPixels(image,x,y,1,1,exception);
5538               if (image->colorspace != CMYKColorspace)
5539                 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
5540                   QuantumFormat "," QuantumFormat "," QuantumFormat,
5541                   GetPixelRed(image,p),GetPixelGreen(image,p),
5542                   GetPixelBlue(image,p),GetPixelAlpha(image,p));
5543               else
5544                 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
5545                   QuantumFormat "," QuantumFormat "," QuantumFormat ","
5546                   QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5547                   GetPixelBlue(image,p),GetPixelBlack(image,p),
5548                   GetPixelAlpha(image,p));
5549               s=newSVpv(tuple,0);
5550               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5551               continue;
5552             }
5553           if (LocaleCompare(attribute,"pointsize") == 0)
5554             {
5555               if (info)
5556                 s=newSViv((ssize_t) info->image_info->pointsize);
5557               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5558               continue;
5559             }
5560           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5561             attribute);
5562           break;
5563         }
5564         case 'Q':
5565         case 'q':
5566         {
5567           if (LocaleCompare(attribute,"quality") == 0)
5568             {
5569               if (info)
5570                 s=newSViv((ssize_t) info->image_info->quality);
5571               if (image != (Image *) NULL)
5572                 s=newSViv((ssize_t) image->quality);
5573               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5574               continue;
5575             }
5576           if (LocaleCompare(attribute,"quantum") == 0)
5577             {
5578               if (info)
5579                 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5580               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5581               continue;
5582             }
5583           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5584             attribute);
5585           break;
5586         }
5587         case 'R':
5588         case 'r':
5589         {
5590           if (LocaleCompare(attribute,"rendering-intent") == 0)
5591             {
5592               s=newSViv(image->rendering_intent);
5593               (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5594                 image->rendering_intent));
5595               SvIOK_on(s);
5596               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5597               continue;
5598             }
5599           if (LocaleCompare(attribute,"red-primary") == 0)
5600             {
5601               if (image == (Image *) NULL)
5602                 break;
5603               (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
5604                 image->chromaticity.red_primary.x,
5605                 image->chromaticity.red_primary.y);
5606               s=newSVpv(color,0);
5607               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5608               continue;
5609             }
5610           if (LocaleCompare(attribute,"rows") == 0)
5611             {
5612               if (image != (Image *) NULL)
5613                 s=newSViv((ssize_t) image->rows);
5614               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5615               continue;
5616             }
5617           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5618             attribute);
5619           break;
5620         }
5621         case 'S':
5622         case 's':
5623         {
5624           if (LocaleCompare(attribute,"sampling-factor") == 0)
5625             {
5626               if (info && info->image_info->sampling_factor)
5627                 s=newSVpv(info->image_info->sampling_factor,0);
5628               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5629               continue;
5630             }
5631           if (LocaleCompare(attribute,"server") == 0)  /* same as display */
5632             {
5633               if (info && info->image_info->server_name)
5634                 s=newSVpv(info->image_info->server_name,0);
5635               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5636               continue;
5637             }
5638           if (LocaleCompare(attribute,"size") == 0)
5639             {
5640               if (info && info->image_info->size)
5641                 s=newSVpv(info->image_info->size,0);
5642               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5643               continue;
5644             }
5645           if (LocaleCompare(attribute,"scene") == 0)
5646             {
5647               if (image != (Image *) NULL)
5648                 s=newSViv((ssize_t) image->scene);
5649               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5650               continue;
5651             }
5652           if (LocaleCompare(attribute,"scenes") == 0)
5653             {
5654               if (image != (Image *) NULL)
5655                 s=newSViv((ssize_t) info->image_info->number_scenes);
5656               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5657               continue;
5658             }
5659           if (LocaleCompare(attribute,"signature") == 0)
5660             {
5661               const char
5662                 *value;
5663 
5664               if (image == (Image *) NULL)
5665                 break;
5666               (void) SignatureImage(image,exception);
5667               value=GetImageProperty(image,"Signature",exception);
5668               if (value != (const char *) NULL)
5669                 s=newSVpv(value,0);
5670               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5671               continue;
5672             }
5673           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5674             attribute);
5675           break;
5676         }
5677         case 'T':
5678         case 't':
5679         {
5680           if (LocaleCompare(attribute,"taint") == 0)
5681             {
5682               if (image != (Image *) NULL)
5683                 s=newSViv((ssize_t) IsTaintImage(image));
5684               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5685               continue;
5686             }
5687           if (LocaleCompare(attribute,"texture") == 0)
5688             {
5689               if (info && info->image_info->texture)
5690                 s=newSVpv(info->image_info->texture,0);
5691               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5692               continue;
5693             }
5694           if (LocaleCompare(attribute,"total-ink-density") == 0)
5695             {
5696               s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5697               if (image != (Image *) NULL)
5698                 s=newSVnv(GetImageTotalInkDensity(image,exception));
5699               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5700               continue;
5701             }
5702           if (LocaleCompare(attribute,"transparent-color") == 0)
5703             {
5704               if (image == (Image *) NULL)
5705                 break;
5706               (void) FormatLocaleString(color,MagickPathExtent,
5707                 "%.20g,%.20g,%.20g,%.20g",(double) image->transparent_color.red,
5708                 (double) image->transparent_color.green,
5709                 (double) image->transparent_color.blue,
5710                 (double) image->transparent_color.alpha);
5711               s=newSVpv(color,0);
5712               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5713               continue;
5714             }
5715           if (LocaleCompare(attribute,"type") == 0)
5716             {
5717               if (image == (Image *) NULL)
5718                 break;
5719               j=(ssize_t) GetImageType(image);
5720               s=newSViv(j);
5721               (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5722               SvIOK_on(s);
5723               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5724               continue;
5725             }
5726           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5727             attribute);
5728           break;
5729         }
5730         case 'U':
5731         case 'u':
5732         {
5733           if (LocaleCompare(attribute,"units") == 0)
5734             {
5735               j=info ? info->image_info->units : image ? image->units :
5736                 UndefinedResolution;
5737               if (info && (info->image_info->units == UndefinedResolution))
5738                 if (image)
5739                   j=image->units;
5740               if (j == UndefinedResolution)
5741                 s=newSVpv("undefined units",0);
5742               else
5743                 if (j == PixelsPerInchResolution)
5744                   s=newSVpv("pixels / inch",0);
5745                 else
5746                   s=newSVpv("pixels / centimeter",0);
5747               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5748               continue;
5749             }
5750           if (LocaleCompare(attribute,"user-time") == 0)
5751             {
5752               if (image != (Image *) NULL)
5753                 s=newSVnv(GetUserTime(&image->timer));
5754               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5755               continue;
5756             }
5757           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5758             attribute);
5759           break;
5760         }
5761         case 'V':
5762         case 'v':
5763         {
5764           if (LocaleCompare(attribute,"verbose") == 0)
5765             {
5766               if (info)
5767                 s=newSViv((ssize_t) info->image_info->verbose);
5768               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5769               continue;
5770             }
5771           if (LocaleCompare(attribute,"version") == 0)
5772             {
5773               s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5774               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5775               continue;
5776             }
5777           if (LocaleCompare(attribute,"virtual-pixel") == 0)
5778             {
5779               if (image == (Image *) NULL)
5780                 break;
5781               j=(ssize_t) GetImageVirtualPixelMethod(image);
5782               s=newSViv(j);
5783               (void) sv_setpv(s,CommandOptionToMnemonic(
5784                 MagickVirtualPixelOptions,j));
5785               SvIOK_on(s);
5786               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5787               continue;
5788             }
5789           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5790             attribute);
5791           break;
5792         }
5793         case 'W':
5794         case 'w':
5795         {
5796           if (LocaleCompare(attribute,"white-point") == 0)
5797             {
5798               if (image == (Image *) NULL)
5799                 break;
5800               (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
5801                 image->chromaticity.white_point.x,
5802                 image->chromaticity.white_point.y);
5803               s=newSVpv(color,0);
5804               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5805               continue;
5806             }
5807           if (LocaleCompare(attribute,"width") == 0)
5808             {
5809               if (image != (Image *) NULL)
5810                 s=newSViv((ssize_t) image->columns);
5811               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5812               continue;
5813             }
5814           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5815              attribute);
5816           break;
5817         }
5818         case 'X':
5819         case 'x':
5820         {
5821           if (LocaleCompare(attribute,"xmp") == 0)
5822             {
5823               if (image != (Image *) NULL)
5824                 {
5825                   const StringInfo
5826                     *profile;
5827 
5828                   profile=GetImageProfile(image,"xmp");
5829                   if (profile != (StringInfo *) NULL)
5830                     s=newSVpv((const char *) GetStringInfoDatum(profile),
5831                       GetStringInfoLength(profile));
5832                 }
5833               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5834               continue;
5835             }
5836           if (LocaleCompare(attribute,"x-resolution") == 0)
5837             {
5838               if (image != (Image *) NULL)
5839                 s=newSVnv(image->resolution.x);
5840               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5841               continue;
5842             }
5843           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5844             attribute);
5845           break;
5846         }
5847         case 'Y':
5848         case 'y':
5849         {
5850           if (LocaleCompare(attribute,"y-resolution") == 0)
5851             {
5852               if (image != (Image *) NULL)
5853                 s=newSVnv(image->resolution.y);
5854               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5855               continue;
5856             }
5857           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5858             attribute);
5859           break;
5860         }
5861         default:
5862           break;
5863       }
5864       if (image == (Image *) NULL)
5865         ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5866           attribute)
5867       else
5868         {
5869           value=GetImageProperty(image,attribute,exception);
5870           if (value != (const char *) NULL)
5871             {
5872               s=newSVpv(value,0);
5873               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5874             }
5875           else
5876             if (*attribute != '%')
5877               ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5878                 attribute)
5879             else
5880               {
5881                  char
5882                    *meta;
5883 
5884                  meta=InterpretImageProperties(info ? info->image_info :
5885                    (ImageInfo *) NULL,image,attribute,exception);
5886                  s=newSVpv(meta,0);
5887                  PUSHs(s ? sv_2mortal(s) : &sv_undef);
5888                  meta=(char *) RelinquishMagickMemory(meta);
5889               }
5890         }
5891     }
5892     exception=DestroyExceptionInfo(exception);
5893     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
5894   }
5895 
5896 #
5897 ###############################################################################
5898 #                                                                             #
5899 #                                                                             #
5900 #                                                                             #
5901 #   G e t A u t h e n t i c P i x e l s                                       #
5902 #                                                                             #
5903 #                                                                             #
5904 #                                                                             #
5905 ###############################################################################
5906 #
5907 #
5908 void *
GetAuthenticPixels(ref,...)5909 GetAuthenticPixels(ref,...)
5910   Image::Magick ref = NO_INIT
5911   ALIAS:
5912     getauthenticpixels = 1
5913     GetImagePixels = 2
5914     getimagepixels = 3
5915   CODE:
5916   {
5917     char
5918       *attribute;
5919 
5920     ExceptionInfo
5921       *exception;
5922 
5923     Image
5924       *image;
5925 
5926     RectangleInfo
5927       region;
5928 
5929     ssize_t
5930       i;
5931 
5932     struct PackageInfo
5933       *info;
5934 
5935     SV
5936       *perl_exception,
5937       *reference;
5938 
5939     void
5940       *blob = NULL;
5941 
5942     PERL_UNUSED_VAR(ref);
5943     PERL_UNUSED_VAR(ix);
5944     exception=AcquireExceptionInfo();
5945     perl_exception=newSVpv("",0);
5946     if (sv_isobject(ST(0)) == 0)
5947       {
5948         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5949           PackageName);
5950         goto PerlException;
5951       }
5952     reference=SvRV(ST(0));
5953 
5954     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5955     if (image == (Image *) NULL)
5956       {
5957         ThrowPerlException(exception,OptionError,"NoImagesDefined",
5958           PackageName);
5959         goto PerlException;
5960       }
5961 
5962     region.x=0;
5963     region.y=0;
5964     region.width=image->columns;
5965     region.height=1;
5966     if (items == 1)
5967       (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5968     for (i=2; i < items; i+=2)
5969     {
5970       attribute=(char *) SvPV(ST(i-1),na);
5971       switch (*attribute)
5972       {
5973         case 'g':
5974         case 'G':
5975         {
5976           if (LocaleCompare(attribute,"geometry") == 0)
5977             {
5978               (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5979               break;
5980             }
5981           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5982             attribute);
5983           break;
5984         }
5985         case 'H':
5986         case 'h':
5987         {
5988           if (LocaleCompare(attribute,"height") == 0)
5989             {
5990               region.height=SvIV(ST(i));
5991               continue;
5992             }
5993           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5994             attribute);
5995           break;
5996         }
5997         case 'X':
5998         case 'x':
5999         {
6000           if (LocaleCompare(attribute,"x") == 0)
6001             {
6002               region.x=SvIV(ST(i));
6003               continue;
6004             }
6005           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6006             attribute);
6007           break;
6008         }
6009         case 'Y':
6010         case 'y':
6011         {
6012           if (LocaleCompare(attribute,"y") == 0)
6013             {
6014               region.y=SvIV(ST(i));
6015               continue;
6016             }
6017           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6018             attribute);
6019           break;
6020         }
6021         case 'W':
6022         case 'w':
6023         {
6024           if (LocaleCompare(attribute,"width") == 0)
6025             {
6026               region.width=SvIV(ST(i));
6027               continue;
6028             }
6029           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6030             attribute);
6031           break;
6032         }
6033       }
6034     }
6035     blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
6036       region.height,exception);
6037     if (blob != (void *) NULL)
6038       goto PerlEnd;
6039 
6040   PerlException:
6041     InheritPerlException(exception,perl_exception);
6042     exception=DestroyExceptionInfo(exception);
6043     SvREFCNT_dec(perl_exception);  /* throw away all errors */
6044 
6045   PerlEnd:
6046     RETVAL = blob;
6047   }
6048   OUTPUT:
6049     RETVAL
6050 
6051 #
6052 ###############################################################################
6053 #                                                                             #
6054 #                                                                             #
6055 #                                                                             #
6056 #   G e t V i r t u a l P i x e l s                                           #
6057 #                                                                             #
6058 #                                                                             #
6059 #                                                                             #
6060 ###############################################################################
6061 #
6062 #
6063 void *
GetVirtualPixels(ref,...)6064 GetVirtualPixels(ref,...)
6065   Image::Magick ref = NO_INIT
6066   ALIAS:
6067     getvirtualpixels = 1
6068     AcquireImagePixels = 2
6069     acquireimagepixels = 3
6070   CODE:
6071   {
6072     char
6073       *attribute;
6074 
6075     const void
6076       *blob = NULL;
6077 
6078     ExceptionInfo
6079       *exception;
6080 
6081     Image
6082       *image;
6083 
6084     RectangleInfo
6085       region;
6086 
6087     ssize_t
6088       i;
6089 
6090     struct PackageInfo
6091       *info;
6092 
6093     SV
6094       *perl_exception,
6095       *reference;
6096 
6097     PERL_UNUSED_VAR(ref);
6098     PERL_UNUSED_VAR(ix);
6099     exception=AcquireExceptionInfo();
6100     perl_exception=newSVpv("",0);
6101     if (sv_isobject(ST(0)) == 0)
6102       {
6103         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6104           PackageName);
6105         goto PerlException;
6106       }
6107     reference=SvRV(ST(0));
6108 
6109     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6110     if (image == (Image *) NULL)
6111       {
6112         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6113           PackageName);
6114         goto PerlException;
6115       }
6116 
6117     region.x=0;
6118     region.y=0;
6119     region.width=image->columns;
6120     region.height=1;
6121     if (items == 1)
6122       (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6123     for (i=2; i < items; i+=2)
6124     {
6125       attribute=(char *) SvPV(ST(i-1),na);
6126       switch (*attribute)
6127       {
6128         case 'g':
6129         case 'G':
6130         {
6131           if (LocaleCompare(attribute,"geometry") == 0)
6132             {
6133               (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6134               break;
6135             }
6136           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6137             attribute);
6138           break;
6139         }
6140         case 'H':
6141         case 'h':
6142         {
6143           if (LocaleCompare(attribute,"height") == 0)
6144             {
6145               region.height=SvIV(ST(i));
6146               continue;
6147             }
6148           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6149             attribute);
6150           break;
6151         }
6152         case 'X':
6153         case 'x':
6154         {
6155           if (LocaleCompare(attribute,"x") == 0)
6156             {
6157               region.x=SvIV(ST(i));
6158               continue;
6159             }
6160           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6161             attribute);
6162           break;
6163         }
6164         case 'Y':
6165         case 'y':
6166         {
6167           if (LocaleCompare(attribute,"y") == 0)
6168             {
6169               region.y=SvIV(ST(i));
6170               continue;
6171             }
6172           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6173             attribute);
6174           break;
6175         }
6176         case 'W':
6177         case 'w':
6178         {
6179           if (LocaleCompare(attribute,"width") == 0)
6180             {
6181               region.width=SvIV(ST(i));
6182               continue;
6183             }
6184           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6185             attribute);
6186           break;
6187         }
6188       }
6189     }
6190     blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
6191       region.height,exception);
6192     if (blob != (void *) NULL)
6193       goto PerlEnd;
6194 
6195   PerlException:
6196     InheritPerlException(exception,perl_exception);
6197     exception=DestroyExceptionInfo(exception);
6198     SvREFCNT_dec(perl_exception);  /* throw away all errors */
6199 
6200   PerlEnd:
6201     RETVAL = (void *) blob;
6202   }
6203   OUTPUT:
6204     RETVAL
6205 
6206 #
6207 ###############################################################################
6208 #                                                                             #
6209 #                                                                             #
6210 #                                                                             #
6211 #   G e t A u t h e n t i c M e t a c o n t e n t                             #
6212 #                                                                             #
6213 #                                                                             #
6214 #                                                                             #
6215 ###############################################################################
6216 #
6217 #
6218 void *
GetAuthenticMetacontent(ref,...)6219 GetAuthenticMetacontent(ref,...)
6220   Image::Magick ref = NO_INIT
6221   ALIAS:
6222     getauthenticmetacontent = 1
6223     GetMetacontent = 2
6224     getmetacontent = 3
6225   CODE:
6226   {
6227     ExceptionInfo
6228       *exception;
6229 
6230     Image
6231       *image;
6232 
6233     struct PackageInfo
6234       *info;
6235 
6236     SV
6237       *perl_exception,
6238       *reference;
6239 
6240     void
6241       *blob = NULL;
6242 
6243     PERL_UNUSED_VAR(ref);
6244     PERL_UNUSED_VAR(ix);
6245     exception=AcquireExceptionInfo();
6246     perl_exception=newSVpv("",0);
6247     if (sv_isobject(ST(0)) == 0)
6248       {
6249         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6250           PackageName);
6251         goto PerlException;
6252       }
6253     reference=SvRV(ST(0));
6254 
6255     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6256     if (image == (Image *) NULL)
6257       {
6258         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6259           PackageName);
6260         goto PerlException;
6261       }
6262 
6263     blob=(void *) GetAuthenticMetacontent(image);
6264     if (blob != (void *) NULL)
6265       goto PerlEnd;
6266 
6267   PerlException:
6268     InheritPerlException(exception,perl_exception);
6269     exception=DestroyExceptionInfo(exception);
6270     SvREFCNT_dec(perl_exception);  /* throw away all errors */
6271 
6272   PerlEnd:
6273     RETVAL = blob;
6274   }
6275   OUTPUT:
6276     RETVAL
6277 
6278 #
6279 ###############################################################################
6280 #                                                                             #
6281 #                                                                             #
6282 #                                                                             #
6283 #   G e t V i r t u a l M e t a c o n t e n t                                 #
6284 #                                                                             #
6285 #                                                                             #
6286 #                                                                             #
6287 ###############################################################################
6288 #
6289 #
6290 void *
GetVirtualMetacontent(ref,...)6291 GetVirtualMetacontent(ref,...)
6292   Image::Magick ref = NO_INIT
6293   ALIAS:
6294     getvirtualmetacontent = 1
6295   CODE:
6296   {
6297     ExceptionInfo
6298       *exception;
6299 
6300     Image
6301       *image;
6302 
6303     struct PackageInfo
6304       *info;
6305 
6306     SV
6307       *perl_exception,
6308       *reference;
6309 
6310     void
6311       *blob = NULL;
6312 
6313     PERL_UNUSED_VAR(ref);
6314     PERL_UNUSED_VAR(ix);
6315     exception=AcquireExceptionInfo();
6316     perl_exception=newSVpv("",0);
6317     if (sv_isobject(ST(0)) == 0)
6318       {
6319         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6320           PackageName);
6321         goto PerlException;
6322       }
6323     reference=SvRV(ST(0));
6324 
6325     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6326     if (image == (Image *) NULL)
6327       {
6328         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6329           PackageName);
6330         goto PerlException;
6331       }
6332 
6333     blob=(void *) GetVirtualMetacontent(image);
6334     if (blob != (void *) NULL)
6335       goto PerlEnd;
6336 
6337   PerlException:
6338     InheritPerlException(exception,perl_exception);
6339     exception=DestroyExceptionInfo(exception);
6340     SvREFCNT_dec(perl_exception);  /* throw away all errors */
6341 
6342   PerlEnd:
6343     RETVAL = blob;
6344   }
6345   OUTPUT:
6346     RETVAL
6347 
6348 #
6349 ###############################################################################
6350 #                                                                             #
6351 #                                                                             #
6352 #                                                                             #
6353 #   H i s t o g r a m                                                         #
6354 #                                                                             #
6355 #                                                                             #
6356 #                                                                             #
6357 ###############################################################################
6358 #
6359 #
6360 void
Histogram(ref,...)6361 Histogram(ref,...)
6362   Image::Magick ref=NO_INIT
6363   ALIAS:
6364     HistogramImage = 1
6365     histogram      = 2
6366     histogramimage = 3
6367   PPCODE:
6368   {
6369     AV
6370       *av;
6371 
6372     char
6373       message[MagickPathExtent];
6374 
6375     PixelInfo
6376       *histogram;
6377 
6378     ExceptionInfo
6379       *exception;
6380 
6381     Image
6382       *image;
6383 
6384     register ssize_t
6385       i;
6386 
6387     ssize_t
6388       count;
6389 
6390     struct PackageInfo
6391       *info;
6392 
6393     SV
6394       *perl_exception,
6395       *reference;
6396 
6397     size_t
6398       number_colors;
6399 
6400     PERL_UNUSED_VAR(ref);
6401     PERL_UNUSED_VAR(ix);
6402     exception=AcquireExceptionInfo();
6403     perl_exception=newSVpv("",0);
6404     av=NULL;
6405     if (sv_isobject(ST(0)) == 0)
6406       {
6407         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6408           PackageName);
6409         goto PerlException;
6410       }
6411     reference=SvRV(ST(0));
6412     av=newAV();
6413     SvREFCNT_dec(av);
6414     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6415     if (image == (Image *) NULL)
6416       {
6417         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6418           PackageName);
6419         goto PerlException;
6420       }
6421     count=0;
6422     for ( ; image; image=image->next)
6423     {
6424       histogram=GetImageHistogram(image,&number_colors,exception);
6425       if (histogram == (PixelInfo *) NULL)
6426         continue;
6427       count+=(ssize_t) number_colors;
6428       EXTEND(sp,6*count);
6429       for (i=0; i < (ssize_t) number_colors; i++)
6430       {
6431         (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
6432           histogram[i].red);
6433         PUSHs(sv_2mortal(newSVpv(message,0)));
6434         (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
6435           histogram[i].green);
6436         PUSHs(sv_2mortal(newSVpv(message,0)));
6437         (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
6438           histogram[i].blue);
6439         PUSHs(sv_2mortal(newSVpv(message,0)));
6440         if (image->colorspace == CMYKColorspace)
6441           {
6442             (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
6443               histogram[i].black);
6444             PUSHs(sv_2mortal(newSVpv(message,0)));
6445           }
6446         (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
6447           histogram[i].alpha);
6448         PUSHs(sv_2mortal(newSVpv(message,0)));
6449         (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
6450           histogram[i].count);
6451         PUSHs(sv_2mortal(newSVpv(message,0)));
6452       }
6453       histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6454     }
6455 
6456   PerlException:
6457     InheritPerlException(exception,perl_exception);
6458     exception=DestroyExceptionInfo(exception);
6459     SvREFCNT_dec(perl_exception);
6460   }
6461 
6462 #
6463 ###############################################################################
6464 #                                                                             #
6465 #                                                                             #
6466 #                                                                             #
6467 #   G e t P i x e l                                                           #
6468 #                                                                             #
6469 #                                                                             #
6470 #                                                                             #
6471 ###############################################################################
6472 #
6473 #
6474 void
GetPixel(ref,...)6475 GetPixel(ref,...)
6476   Image::Magick ref=NO_INIT
6477   ALIAS:
6478     getpixel = 1
6479     getPixel = 2
6480   PPCODE:
6481   {
6482     AV
6483       *av;
6484 
6485     char
6486       *attribute;
6487 
6488     ExceptionInfo
6489       *exception;
6490 
6491     Image
6492       *image;
6493 
6494     MagickBooleanType
6495       normalize;
6496 
6497     RectangleInfo
6498       region;
6499 
6500     register const Quantum
6501       *p;
6502 
6503     register ssize_t
6504       i;
6505 
6506     ssize_t
6507       option;
6508 
6509     struct PackageInfo
6510       *info;
6511 
6512     SV
6513       *perl_exception,
6514       *reference;  /* reference is the SV* of ref=SvIV(reference) */
6515 
6516     PERL_UNUSED_VAR(ref);
6517     PERL_UNUSED_VAR(ix);
6518     exception=AcquireExceptionInfo();
6519     perl_exception=newSVpv("",0);
6520     reference=SvRV(ST(0));
6521     av=(AV *) reference;
6522     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6523       exception);
6524     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6525     if (image == (Image *) NULL)
6526       {
6527         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6528           PackageName);
6529         goto PerlException;
6530       }
6531     normalize=MagickTrue;
6532     region.x=0;
6533     region.y=0;
6534     region.width=image->columns;
6535     region.height=1;
6536     if (items == 1)
6537       (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6538     for (i=2; i < items; i+=2)
6539     {
6540       attribute=(char *) SvPV(ST(i-1),na);
6541       switch (*attribute)
6542       {
6543         case 'C':
6544         case 'c':
6545         {
6546           if (LocaleCompare(attribute,"channel") == 0)
6547             {
6548               ssize_t
6549                 option;
6550 
6551               option=ParseChannelOption(SvPV(ST(i),na));
6552               if (option < 0)
6553                 {
6554                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
6555                     SvPV(ST(i),na));
6556                   return;
6557                 }
6558               (void) SetPixelChannelMask(image,(ChannelType) option);
6559               break;
6560             }
6561           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6562             attribute);
6563           break;
6564         }
6565         case 'g':
6566         case 'G':
6567         {
6568           if (LocaleCompare(attribute,"geometry") == 0)
6569             {
6570               (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6571               break;
6572             }
6573           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6574             attribute);
6575           break;
6576         }
6577         case 'N':
6578         case 'n':
6579         {
6580           if (LocaleCompare(attribute,"normalize") == 0)
6581             {
6582               option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6583                 SvPV(ST(i),na));
6584               if (option < 0)
6585                 {
6586                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
6587                     SvPV(ST(i),na));
6588                   break;
6589                 }
6590              normalize=option != 0 ? MagickTrue : MagickFalse;
6591              break;
6592             }
6593           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6594             attribute);
6595           break;
6596         }
6597         case 'x':
6598         case 'X':
6599         {
6600           if (LocaleCompare(attribute,"x") == 0)
6601             {
6602               region.x=SvIV(ST(i));
6603               break;
6604             }
6605           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6606             attribute);
6607           break;
6608         }
6609         case 'y':
6610         case 'Y':
6611         {
6612           if (LocaleCompare(attribute,"y") == 0)
6613             {
6614               region.y=SvIV(ST(i));
6615               break;
6616             }
6617           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6618             attribute);
6619           break;
6620         }
6621         default:
6622         {
6623           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6624             attribute);
6625           break;
6626         }
6627       }
6628     }
6629     p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6630     if (p == (const Quantum *) NULL)
6631       PUSHs(&sv_undef);
6632     else
6633       {
6634         double
6635           scale;
6636 
6637         scale=1.0;
6638         if (normalize != MagickFalse)
6639           scale=1.0/QuantumRange;
6640         if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6641           PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6642         if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6643           PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6644         if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6645           PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6646         if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6647             (image->colorspace == CMYKColorspace))
6648           PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6649         if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6650           PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6651       }
6652 
6653   PerlException:
6654     InheritPerlException(exception,perl_exception);
6655     exception=DestroyExceptionInfo(exception);
6656     SvREFCNT_dec(perl_exception);
6657   }
6658 
6659 #
6660 ###############################################################################
6661 #                                                                             #
6662 #                                                                             #
6663 #                                                                             #
6664 #   G e t P i x e l s                                                         #
6665 #                                                                             #
6666 #                                                                             #
6667 #                                                                             #
6668 ###############################################################################
6669 #
6670 #
6671 void
GetPixels(ref,...)6672 GetPixels(ref,...)
6673   Image::Magick ref=NO_INIT
6674   ALIAS:
6675     getpixels = 1
6676     getPixels = 2
6677   PPCODE:
6678   {
6679     AV
6680       *av;
6681 
6682     char
6683       *attribute;
6684 
6685     const char
6686       *map;
6687 
6688     ExceptionInfo
6689       *exception;
6690 
6691     Image
6692       *image;
6693 
6694     MagickBooleanType
6695       normalize,
6696       status;
6697 
6698     RectangleInfo
6699       region;
6700 
6701     register ssize_t
6702       i;
6703 
6704     ssize_t
6705       option;
6706 
6707     struct PackageInfo
6708       *info;
6709 
6710     SV
6711       *perl_exception,
6712       *reference;  /* reference is the SV* of ref=SvIV(reference) */
6713 
6714     PERL_UNUSED_VAR(ref);
6715     PERL_UNUSED_VAR(ix);
6716     exception=AcquireExceptionInfo();
6717     perl_exception=newSVpv("",0);
6718     reference=SvRV(ST(0));
6719     av=(AV *) reference;
6720     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6721       exception);
6722     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6723     if (image == (Image *) NULL)
6724       {
6725         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6726           PackageName);
6727         goto PerlException;
6728       }
6729     map="RGB";
6730     if (image->alpha_trait != UndefinedPixelTrait)
6731       map="RGBA";
6732     if (image->colorspace == CMYKColorspace)
6733       {
6734         map="CMYK";
6735         if (image->alpha_trait != UndefinedPixelTrait)
6736           map="CMYKA";
6737       }
6738     normalize=MagickFalse;
6739     region.x=0;
6740     region.y=0;
6741     region.width=image->columns;
6742     region.height=1;
6743     if (items == 1)
6744       (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6745     for (i=2; i < items; i+=2)
6746     {
6747       attribute=(char *) SvPV(ST(i-1),na);
6748       switch (*attribute)
6749       {
6750         case 'g':
6751         case 'G':
6752         {
6753           if (LocaleCompare(attribute,"geometry") == 0)
6754             {
6755               (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6756               break;
6757             }
6758           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6759             attribute);
6760           break;
6761         }
6762         case 'H':
6763         case 'h':
6764         {
6765           if (LocaleCompare(attribute,"height") == 0)
6766             {
6767               region.height=SvIV(ST(i));
6768               break;
6769             }
6770           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6771             attribute);
6772           break;
6773         }
6774         case 'M':
6775         case 'm':
6776         {
6777           if (LocaleCompare(attribute,"map") == 0)
6778             {
6779               map=SvPV(ST(i),na);
6780               break;
6781             }
6782           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6783             attribute);
6784           break;
6785         }
6786         case 'N':
6787         case 'n':
6788         {
6789           if (LocaleCompare(attribute,"normalize") == 0)
6790             {
6791               option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6792                 SvPV(ST(i),na));
6793               if (option < 0)
6794                 {
6795                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
6796                     SvPV(ST(i),na));
6797                   break;
6798                 }
6799              normalize=option != 0 ? MagickTrue : MagickFalse;
6800              break;
6801             }
6802           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6803             attribute);
6804           break;
6805         }
6806         case 'W':
6807         case 'w':
6808         {
6809           if (LocaleCompare(attribute,"width") == 0)
6810             {
6811               region.width=SvIV(ST(i));
6812               break;
6813             }
6814           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6815             attribute);
6816           break;
6817         }
6818         case 'x':
6819         case 'X':
6820         {
6821           if (LocaleCompare(attribute,"x") == 0)
6822             {
6823               region.x=SvIV(ST(i));
6824               break;
6825             }
6826           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6827             attribute);
6828           break;
6829         }
6830         case 'y':
6831         case 'Y':
6832         {
6833           if (LocaleCompare(attribute,"y") == 0)
6834             {
6835               region.y=SvIV(ST(i));
6836               break;
6837             }
6838           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6839             attribute);
6840           break;
6841         }
6842         default:
6843         {
6844           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6845             attribute);
6846           break;
6847         }
6848       }
6849     }
6850     if (normalize != MagickFalse)
6851       {
6852         float
6853           *pixels;
6854 
6855         pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6856           region.height*sizeof(*pixels));
6857         if (pixels == (float *) NULL)
6858           {
6859             ThrowPerlException(exception,ResourceLimitError,
6860               "MemoryAllocationFailed",PackageName);
6861             goto PerlException;
6862           }
6863         status=ExportImagePixels(image,region.x,region.y,region.width,
6864           region.height,map,FloatPixel,pixels,exception);
6865         if (status == MagickFalse)
6866           PUSHs(&sv_undef);
6867         else
6868           {
6869             EXTEND(sp,strlen(map)*region.width*region.height);
6870             for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6871               PUSHs(sv_2mortal(newSVnv(pixels[i])));
6872           }
6873         pixels=(float *) RelinquishMagickMemory(pixels);
6874       }
6875     else
6876       {
6877         Quantum
6878           *pixels;
6879 
6880         pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6881           region.height*sizeof(*pixels));
6882         if (pixels == (Quantum *) NULL)
6883           {
6884             ThrowPerlException(exception,ResourceLimitError,
6885               "MemoryAllocationFailed",PackageName);
6886             goto PerlException;
6887           }
6888         status=ExportImagePixels(image,region.x,region.y,region.width,
6889           region.height,map,QuantumPixel,pixels,exception);
6890         if (status == MagickFalse)
6891           PUSHs(&sv_undef);
6892         else
6893           {
6894             EXTEND(sp,strlen(map)*region.width*region.height);
6895             for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6896               PUSHs(sv_2mortal(newSViv(pixels[i])));
6897           }
6898         pixels=(Quantum *) RelinquishMagickMemory(pixels);
6899       }
6900 
6901   PerlException:
6902     InheritPerlException(exception,perl_exception);
6903     exception=DestroyExceptionInfo(exception);
6904     SvREFCNT_dec(perl_exception);
6905   }
6906 
6907 #
6908 ###############################################################################
6909 #                                                                             #
6910 #                                                                             #
6911 #                                                                             #
6912 #   I m a g e T o B l o b                                                     #
6913 #                                                                             #
6914 #                                                                             #
6915 #                                                                             #
6916 ###############################################################################
6917 #
6918 #
6919 void
ImageToBlob(ref,...)6920 ImageToBlob(ref,...)
6921   Image::Magick ref=NO_INIT
6922   ALIAS:
6923     ImageToBlob  = 1
6924     imagetoblob  = 2
6925     toblob       = 3
6926     blob         = 4
6927   PPCODE:
6928   {
6929     char
6930       filename[MagickPathExtent];
6931 
6932     ExceptionInfo
6933       *exception;
6934 
6935     Image
6936       *image,
6937       *next;
6938 
6939     register ssize_t
6940       i;
6941 
6942     struct PackageInfo
6943       *info,
6944       *package_info;
6945 
6946     size_t
6947       length;
6948 
6949     ssize_t
6950       scene;
6951 
6952     SV
6953       *perl_exception,
6954       *reference;
6955 
6956     void
6957       *blob;
6958 
6959     PERL_UNUSED_VAR(ref);
6960     PERL_UNUSED_VAR(ix);
6961     exception=AcquireExceptionInfo();
6962     perl_exception=newSVpv("",0);
6963     package_info=(struct PackageInfo *) NULL;
6964     if (sv_isobject(ST(0)) == 0)
6965       {
6966         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6967           PackageName);
6968         goto PerlException;
6969       }
6970     reference=SvRV(ST(0));
6971     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6972     if (image == (Image *) NULL)
6973       {
6974         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6975           PackageName);
6976         goto PerlException;
6977       }
6978     package_info=ClonePackageInfo(info,exception);
6979     for (i=2; i < items; i+=2)
6980       SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6981     (void) CopyMagickString(filename,package_info->image_info->filename,
6982       MagickPathExtent);
6983     scene=0;
6984     for (next=image; next; next=next->next)
6985     {
6986       (void) CopyMagickString(next->filename,filename,MagickPathExtent);
6987       next->scene=scene++;
6988     }
6989     SetImageInfo(package_info->image_info,(unsigned int)
6990       GetImageListLength(image),exception);
6991     EXTEND(sp,(ssize_t) GetImageListLength(image));
6992     for ( ; image; image=image->next)
6993     {
6994       length=0;
6995       blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6996       if (blob != (char *) NULL)
6997         {
6998           PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6999           blob=(unsigned char *) RelinquishMagickMemory(blob);
7000         }
7001       if (package_info->image_info->adjoin)
7002         break;
7003     }
7004 
7005   PerlException:
7006     if (package_info != (struct PackageInfo *) NULL)
7007       DestroyPackageInfo(package_info);
7008     InheritPerlException(exception,perl_exception);
7009     exception=DestroyExceptionInfo(exception);
7010     SvREFCNT_dec(perl_exception);  /* throw away all errors */
7011   }
7012 
7013 #
7014 ###############################################################################
7015 #                                                                             #
7016 #                                                                             #
7017 #                                                                             #
7018 #   L a y e r s                                                               #
7019 #                                                                             #
7020 #                                                                             #
7021 #                                                                             #
7022 ###############################################################################
7023 #
7024 #
7025 void
Layers(ref,...)7026 Layers(ref,...)
7027   Image::Magick ref=NO_INIT
7028   ALIAS:
7029     Layers                = 1
7030     layers           = 2
7031     OptimizeImageLayers   = 3
7032     optimizelayers        = 4
7033     optimizeimagelayers   = 5
7034   PPCODE:
7035   {
7036     AV
7037       *av;
7038 
7039     char
7040       *attribute;
7041 
7042     CompositeOperator
7043       compose;
7044 
7045     ExceptionInfo
7046       *exception;
7047 
7048     HV
7049       *hv;
7050 
7051     Image
7052       *image,
7053       *layers;
7054 
7055     LayerMethod
7056       method;
7057 
7058     register ssize_t
7059       i;
7060 
7061     ssize_t
7062       option,
7063       sp;
7064 
7065     struct PackageInfo
7066       *info;
7067 
7068     SV
7069       *av_reference,
7070       *perl_exception,
7071       *reference,
7072       *rv,
7073       *sv;
7074 
7075     PERL_UNUSED_VAR(ref);
7076     PERL_UNUSED_VAR(ix);
7077     exception=AcquireExceptionInfo();
7078     perl_exception=newSVpv("",0);
7079     sv=NULL;
7080     if (sv_isobject(ST(0)) == 0)
7081       {
7082         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7083           PackageName);
7084         goto PerlException;
7085       }
7086     reference=SvRV(ST(0));
7087     hv=SvSTASH(reference);
7088     av=newAV();
7089     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
7090     SvREFCNT_dec(av);
7091     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
7092     if (image == (Image *) NULL)
7093       {
7094         ThrowPerlException(exception,OptionError,"NoImagesDefined",
7095           PackageName);
7096         goto PerlException;
7097       }
7098     compose=image->compose;
7099     method=OptimizeLayer;
7100     for (i=2; i < items; i+=2)
7101     {
7102       attribute=(char *) SvPV(ST(i-1),na);
7103       switch (*attribute)
7104       {
7105         case 'C':
7106         case 'c':
7107         {
7108           if (LocaleCompare(attribute,"compose") == 0)
7109             {
7110               sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
7111                 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
7112               if (sp < 0)
7113                 {
7114                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
7115                     SvPV(ST(i),na));
7116                   break;
7117                 }
7118               compose=(CompositeOperator) sp;
7119               break;
7120             }
7121           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7122             attribute);
7123           break;
7124         }
7125         case 'M':
7126         case 'm':
7127         {
7128           if (LocaleCompare(attribute,"method") == 0)
7129             {
7130               option=ParseCommandOption(MagickLayerOptions,MagickFalse,
7131                 SvPV(ST(i),na));
7132               if (option < 0)
7133                 {
7134                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
7135                     SvPV(ST(i),na));
7136                   break;
7137                 }
7138               method=(LayerMethod) option;
7139               break;
7140             }
7141           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7142             attribute);
7143           break;
7144         }
7145         default:
7146         {
7147           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7148             attribute);
7149           break;
7150         }
7151       }
7152     }
7153     layers=(Image *) NULL;
7154     switch (method)
7155     {
7156       case CompareAnyLayer:
7157       case CompareClearLayer:
7158       case CompareOverlayLayer:
7159       default:
7160       {
7161         layers=CompareImagesLayers(image,method,exception);
7162         break;
7163       }
7164       case MergeLayer:
7165       case FlattenLayer:
7166       case MosaicLayer:
7167       {
7168         layers=MergeImageLayers(image,method,exception);
7169         break;
7170       }
7171       case DisposeLayer:
7172       {
7173         layers=DisposeImages(image,exception);
7174         break;
7175       }
7176       case OptimizeImageLayer:
7177       {
7178         layers=OptimizeImageLayers(image,exception);
7179         break;
7180       }
7181       case OptimizePlusLayer:
7182       {
7183         layers=OptimizePlusImageLayers(image,exception);
7184         break;
7185       }
7186       case OptimizeTransLayer:
7187       {
7188         OptimizeImageTransparency(image,exception);
7189         break;
7190       }
7191       case RemoveDupsLayer:
7192       {
7193         RemoveDuplicateLayers(&image,exception);
7194         break;
7195       }
7196       case RemoveZeroLayer:
7197       {
7198         RemoveZeroDelayLayers(&image,exception);
7199         break;
7200       }
7201       case OptimizeLayer:
7202       {
7203         QuantizeInfo
7204           *quantize_info;
7205 
7206         /*
7207           General Purpose, GIF Animation Optimizer.
7208         */
7209         layers=CoalesceImages(image,exception);
7210         if (layers == (Image *) NULL)
7211           break;
7212         image=layers;
7213         layers=OptimizeImageLayers(image,exception);
7214         if (layers == (Image *) NULL)
7215           break;
7216         image=DestroyImageList(image);
7217         image=layers;
7218         layers=(Image *) NULL;
7219         OptimizeImageTransparency(image,exception);
7220         quantize_info=AcquireQuantizeInfo(info->image_info);
7221         (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
7222         quantize_info=DestroyQuantizeInfo(quantize_info);
7223         break;
7224       }
7225       case CompositeLayer:
7226       {
7227         Image
7228           *source;
7229 
7230         RectangleInfo
7231           geometry;
7232 
7233         /*
7234           Split image sequence at the first 'NULL:' image.
7235         */
7236         source=image;
7237         while (source != (Image *) NULL)
7238         {
7239           source=GetNextImageInList(source);
7240           if ((source != (Image *) NULL) &&
7241               (LocaleCompare(source->magick,"NULL") == 0))
7242             break;
7243         }
7244         if (source != (Image *) NULL)
7245           {
7246             if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7247                 (GetNextImageInList(source) == (Image *) NULL))
7248               source=(Image *) NULL;
7249             else
7250               {
7251                 /*
7252                   Separate the two lists, junk the null: image.
7253                 */
7254                 source=SplitImageList(source->previous);
7255                 DeleteImageFromList(&source);
7256               }
7257           }
7258         if (source == (Image *) NULL)
7259           {
7260             (void) ThrowMagickException(exception,GetMagickModule(),
7261               OptionError,"MissingNullSeparator","layers Composite");
7262             break;
7263           }
7264         /*
7265           Adjust offset with gravity and virtual canvas.
7266         */
7267         SetGeometry(image,&geometry);
7268         (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7269         geometry.width=source->page.width != 0 ? source->page.width :
7270           source->columns;
7271         geometry.height=source->page.height != 0 ? source->page.height :
7272           source->rows;
7273         GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7274           image->columns,image->page.height != 0 ? image->page.height :
7275           image->rows,image->gravity,&geometry);
7276         CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7277         source=DestroyImageList(source);
7278         break;
7279       }
7280     }
7281     if (layers != (Image *) NULL)
7282       image=layers;
7283     else
7284       image=CloneImage(image,0,0,MagickTrue,exception);
7285     if (image == (Image *) NULL)
7286       goto PerlException;
7287     for ( ; image; image=image->next)
7288     {
7289       AddImageToRegistry(sv,image);
7290       rv=newRV(sv);
7291       av_push(av,sv_bless(rv,hv));
7292       SvREFCNT_dec(sv);
7293     }
7294     exception=DestroyExceptionInfo(exception);
7295     ST(0)=av_reference;
7296     SvREFCNT_dec(perl_exception);
7297     XSRETURN(1);
7298 
7299   PerlException:
7300     InheritPerlException(exception,perl_exception);
7301     exception=DestroyExceptionInfo(exception);
7302     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7303     SvPOK_on(perl_exception);
7304     ST(0)=sv_2mortal(perl_exception);
7305     XSRETURN(1);
7306   }
7307 
7308 #
7309 ###############################################################################
7310 #                                                                             #
7311 #                                                                             #
7312 #                                                                             #
7313 #   M a g i c k T o M i m e                                                   #
7314 #                                                                             #
7315 #                                                                             #
7316 #                                                                             #
7317 ###############################################################################
7318 #
7319 #
7320 SV *
MagickToMime(ref,name)7321 MagickToMime(ref,name)
7322   Image::Magick ref=NO_INIT
7323   char *name
7324   ALIAS:
7325     magicktomime = 1
7326   CODE:
7327   {
7328     char
7329       *mime;
7330 
7331     PERL_UNUSED_VAR(ref);
7332     PERL_UNUSED_VAR(ix);
7333     mime=MagickToMime(name);
7334     RETVAL=newSVpv(mime,0);
7335     mime=(char *) RelinquishMagickMemory(mime);
7336   }
7337   OUTPUT:
7338     RETVAL
7339 
7340 #
7341 ###############################################################################
7342 #                                                                             #
7343 #                                                                             #
7344 #                                                                             #
7345 #   M o g r i f y                                                             #
7346 #                                                                             #
7347 #                                                                             #
7348 #                                                                             #
7349 ###############################################################################
7350 #
7351 #
7352 void
Mogrify(ref,...)7353 Mogrify(ref,...)
7354   Image::Magick ref=NO_INIT
7355   ALIAS:
7356     Comment            =   1
7357     CommentImage       =   2
7358     Label              =   3
7359     LabelImage         =   4
7360     AddNoise           =   5
7361     AddNoiseImage      =   6
7362     Colorize           =   7
7363     ColorizeImage      =   8
7364     Border             =   9
7365     BorderImage        =  10
7366     Blur               =  11
7367     BlurImage          =  12
7368     Chop               =  13
7369     ChopImage          =  14
7370     Crop               =  15
7371     CropImage          =  16
7372     Despeckle          =  17
7373     DespeckleImage     =  18
7374     Edge               =  19
7375     EdgeImage          =  20
7376     Emboss             =  21
7377     EmbossImage        =  22
7378     Enhance            =  23
7379     EnhanceImage       =  24
7380     Flip               =  25
7381     FlipImage          =  26
7382     Flop               =  27
7383     FlopImage          =  28
7384     Frame              =  29
7385     FrameImage         =  30
7386     Implode            =  31
7387     ImplodeImage       =  32
7388     Magnify            =  33
7389     MagnifyImage       =  34
7390     MedianFilter       =  35
7391     MedianConvolveImage  =  36
7392     Minify             =  37
7393     MinifyImage        =  38
7394     OilPaint           =  39
7395     OilPaintImage      =  40
7396     ReduceNoise        =  41
7397     ReduceNoiseImage   =  42
7398     Roll               =  43
7399     RollImage          =  44
7400     Rotate             =  45
7401     RotateImage        =  46
7402     Sample             =  47
7403     SampleImage        =  48
7404     Scale              =  49
7405     ScaleImage         =  50
7406     Shade              =  51
7407     ShadeImage         =  52
7408     Sharpen            =  53
7409     SharpenImage       =  54
7410     Shear              =  55
7411     ShearImage         =  56
7412     Spread             =  57
7413     SpreadImage        =  58
7414     Swirl              =  59
7415     SwirlImage         =  60
7416     Resize             =  61
7417     ResizeImage        =  62
7418     Zoom               =  63
7419     ZoomImage          =  64
7420     Annotate           =  65
7421     AnnotateImage      =  66
7422     ColorFloodfill     =  67
7423     ColorFloodfillImage=  68
7424     Composite          =  69
7425     CompositeImage     =  70
7426     Contrast           =  71
7427     ContrastImage      =  72
7428     CycleColormap      =  73
7429     CycleColormapImage =  74
7430     Draw               =  75
7431     DrawImage          =  76
7432     Equalize           =  77
7433     EqualizeImage      =  78
7434     Gamma              =  79
7435     GammaImage         =  80
7436     Map                =  81
7437     MapImage           =  82
7438     MatteFloodfill     =  83
7439     MatteFloodfillImage=  84
7440     Modulate           =  85
7441     ModulateImage      =  86
7442     Negate             =  87
7443     NegateImage        =  88
7444     Normalize          =  89
7445     NormalizeImage     =  90
7446     NumberColors       =  91
7447     NumberColorsImage  =  92
7448     Opaque             =  93
7449     OpaqueImage        =  94
7450     Quantize           =  95
7451     QuantizeImage      =  96
7452     Raise              =  97
7453     RaiseImage         =  98
7454     Segment            =  99
7455     SegmentImage       = 100
7456     Signature          = 101
7457     SignatureImage     = 102
7458     Solarize           = 103
7459     SolarizeImage      = 104
7460     Sync               = 105
7461     SyncImage          = 106
7462     Texture            = 107
7463     TextureImage       = 108
7464     Evaluate           = 109
7465     EvaluateImage      = 110
7466     Transparent        = 111
7467     TransparentImage   = 112
7468     Threshold          = 113
7469     ThresholdImage     = 114
7470     Charcoal           = 115
7471     CharcoalImage      = 116
7472     Trim               = 117
7473     TrimImage          = 118
7474     Wave               = 119
7475     WaveImage          = 120
7476     Separate           = 121
7477     SeparateImage      = 122
7478     Stereo             = 125
7479     StereoImage        = 126
7480     Stegano            = 127
7481     SteganoImage       = 128
7482     Deconstruct        = 129
7483     DeconstructImage   = 130
7484     GaussianBlur       = 131
7485     GaussianBlurImage  = 132
7486     Convolve           = 133
7487     ConvolveImage      = 134
7488     Profile            = 135
7489     ProfileImage       = 136
7490     UnsharpMask        = 137
7491     UnsharpMaskImage   = 138
7492     MotionBlur         = 139
7493     MotionBlurImage    = 140
7494     OrderedDither      = 141
7495     OrderedDitherImage = 142
7496     Shave              = 143
7497     ShaveImage         = 144
7498     Level              = 145
7499     LevelImage         = 146
7500     Clip               = 147
7501     ClipImage          = 148
7502     AffineTransform    = 149
7503     AffineTransformImage = 150
7504     Difference         = 151
7505     DifferenceImage    = 152
7506     AdaptiveThreshold  = 153
7507     AdaptiveThresholdImage = 154
7508     Resample           = 155
7509     ResampleImage      = 156
7510     Describe           = 157
7511     DescribeImage      = 158
7512     BlackThreshold     = 159
7513     BlackThresholdImage= 160
7514     WhiteThreshold     = 161
7515     WhiteThresholdImage= 162
7516     RotationalBlur     = 163
7517     RotationalBlurImage= 164
7518     Thumbnail          = 165
7519     ThumbnailImage     = 166
7520     Strip              = 167
7521     StripImage         = 168
7522     Tint               = 169
7523     TintImage          = 170
7524     Channel            = 171
7525     ChannelImage       = 172
7526     Splice             = 173
7527     SpliceImage        = 174
7528     Posterize          = 175
7529     PosterizeImage     = 176
7530     Shadow             = 177
7531     ShadowImage        = 178
7532     Identify           = 179
7533     IdentifyImage      = 180
7534     SepiaTone          = 181
7535     SepiaToneImage     = 182
7536     SigmoidalContrast  = 183
7537     SigmoidalContrastImage = 184
7538     Extent             = 185
7539     ExtentImage        = 186
7540     Vignette           = 187
7541     VignetteImage      = 188
7542     ContrastStretch    = 189
7543     ContrastStretchImage = 190
7544     Sans0              = 191
7545     Sans0Image         = 192
7546     Sans1              = 193
7547     Sans1Image         = 194
7548     AdaptiveSharpen    = 195
7549     AdaptiveSharpenImage = 196
7550     Transpose          = 197
7551     TransposeImage     = 198
7552     Transverse         = 199
7553     TransverseImage    = 200
7554     AutoOrient         = 201
7555     AutoOrientImage    = 202
7556     AdaptiveBlur       = 203
7557     AdaptiveBlurImage  = 204
7558     Sketch             = 205
7559     SketchImage        = 206
7560     UniqueColors       = 207
7561     UniqueColorsImage  = 208
7562     AdaptiveResize     = 209
7563     AdaptiveResizeImage= 210
7564     ClipMask           = 211
7565     ClipMaskImage      = 212
7566     LinearStretch      = 213
7567     LinearStretchImage = 214
7568     ColorMatrix        = 215
7569     ColorMatrixImage   = 216
7570     Mask               = 217
7571     MaskImage          = 218
7572     Polaroid           = 219
7573     PolaroidImage      = 220
7574     FloodfillPaint     = 221
7575     FloodfillPaintImage= 222
7576     Distort            = 223
7577     DistortImage       = 224
7578     Clut               = 225
7579     ClutImage          = 226
7580     LiquidRescale      = 227
7581     LiquidRescaleImage = 228
7582     Encipher           = 229
7583     EncipherImage      = 230
7584     Decipher           = 231
7585     DecipherImage      = 232
7586     Deskew             = 233
7587     DeskewImage        = 234
7588     Remap              = 235
7589     RemapImage         = 236
7590     SparseColor        = 237
7591     SparseColorImage   = 238
7592     Function           = 239
7593     FunctionImage      = 240
7594     SelectiveBlur      = 241
7595     SelectiveBlurImage = 242
7596     HaldClut           = 243
7597     HaldClutImage      = 244
7598     BlueShift          = 245
7599     BlueShiftImage     = 246
7600     ForwardFourierTransform  = 247
7601     ForwardFourierTransformImage = 248
7602     InverseFourierTransform = 249
7603     InverseFourierTransformImage = 250
7604     ColorDecisionList  = 251
7605     ColorDecisionListImage = 252
7606     AutoGamma          = 253
7607     AutoGammaImage     = 254
7608     AutoLevel          = 255
7609     AutoLevelImage     = 256
7610     LevelColors        = 257
7611     LevelImageColors   = 258
7612     Clamp              = 259
7613     ClampImage         = 260
7614     BrightnessContrast = 261
7615     BrightnessContrastImage = 262
7616     Morphology         = 263
7617     MorphologyImage    = 264
7618     Mode               = 265
7619     ModeImage          = 266
7620     Statistic          = 267
7621     StatisticImage     = 268
7622     Perceptible        = 269
7623     PerceptibleImage   = 270
7624     Poly               = 271
7625     PolyImage          = 272
7626     Grayscale          = 273
7627     GrayscaleImage     = 274
7628     CannyEdge          = 275
7629     CannyEdgeImage     = 276
7630     HoughLine          = 277
7631     HoughLineImage     = 278
7632     MeanShift          = 279
7633     MeanShiftImage     = 280
7634     Kuwahara           = 281
7635     KuwaharaImage      = 282
7636     ConnectedComponents = 283
7637     ConnectedComponentsImage = 284
7638     CopyPixels         = 285
7639     CopyImagePixels    = 286
7640     Color              = 287
7641     ColorImage         = 288
7642     WaveletDenoise     = 289
7643     WaveletDenoiseImage= 290
7644     Colorspace         = 291
7645     ColorspaceImage    = 292
7646     AutoThreshold      = 293
7647     AutoThresholdImage = 294
7648     RangeThreshold     = 295
7649     RangeThresholdImage= 296
7650     CLAHE              = 297
7651     CLAHEImage         = 298
7652     Kmeans             = 299
7653     KMeansImage        = 300
7654     MogrifyRegion      = 666
7655   PPCODE:
7656   {
7657     AffineMatrix
7658       affine,
7659       current;
7660 
7661     char
7662       attribute_flag[MaxArguments],
7663       message[MagickPathExtent];
7664 
7665     ChannelType
7666       channel,
7667       channel_mask;
7668 
7669     CompositeOperator
7670       compose;
7671 
7672     const char
7673       *attribute,
7674       *value;
7675 
7676     double
7677       angle;
7678 
7679     ExceptionInfo
7680       *exception;
7681 
7682     GeometryInfo
7683       geometry_info;
7684 
7685     Image
7686       *image,
7687       *next;
7688 
7689     MagickStatusType
7690       flags;
7691 
7692     PixelInfo
7693       fill_color;
7694 
7695     RectangleInfo
7696       geometry,
7697       region_info;
7698 
7699     register ssize_t
7700       i;
7701 
7702     ssize_t
7703       base,
7704       j,
7705       number_images;
7706 
7707     struct Methods
7708       *rp;
7709 
7710     struct PackageInfo
7711       *info;
7712 
7713     SV
7714       *perl_exception,
7715       **pv,
7716       *reference,
7717       **reference_vector;
7718 
7719     struct ArgumentList
7720       argument_list[MaxArguments];
7721 
7722     PERL_UNUSED_VAR(ref);
7723     PERL_UNUSED_VAR(ix);
7724     exception=AcquireExceptionInfo();
7725     perl_exception=newSVpv("",0);
7726     reference_vector=NULL;
7727     number_images=0;
7728     base=2;
7729     if (sv_isobject(ST(0)) == 0)
7730       {
7731         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7732           PackageName);
7733         goto PerlException;
7734       }
7735     reference=SvRV(ST(0));
7736     region_info.width=0;
7737     region_info.height=0;
7738     region_info.x=0;
7739     region_info.y=0;
7740     image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7741     if (ix && (ix != 666))
7742       {
7743         /*
7744           Called as Method(...)
7745         */
7746         ix=(ix+1)/2;
7747         rp=(&Methods[ix-1]);
7748         attribute=rp->name;
7749       }
7750     else
7751       {
7752         /*
7753           Called as Mogrify("Method",...)
7754         */
7755         attribute=(char *) SvPV(ST(1),na);
7756         if (ix)
7757           {
7758             flags=ParseGravityGeometry(image,attribute,&region_info,exception);
7759             attribute=(char *) SvPV(ST(2),na);
7760             base++;
7761           }
7762         for (rp=Methods; ; rp++)
7763         {
7764           if (rp >= EndOf(Methods))
7765             {
7766               ThrowPerlException(exception,OptionError,
7767                 "UnrecognizedPerlMagickMethod",attribute);
7768               goto PerlException;
7769             }
7770           if (strEQcase(attribute,rp->name))
7771             break;
7772         }
7773         ix=rp-Methods+1;
7774         base++;
7775       }
7776     if (image == (Image *) NULL)
7777       {
7778         ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7779         goto PerlException;
7780       }
7781     Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7782     Zero(&attribute_flag,NumberOf(attribute_flag),char);
7783     for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7784     {
7785       Arguments
7786         *pp,
7787         *qq;
7788 
7789       ssize_t
7790         ssize_test;
7791 
7792       struct ArgumentList
7793         *al;
7794 
7795       SV
7796         *sv;
7797 
7798       sv=NULL;
7799       ssize_test=0;
7800       pp=(Arguments *) NULL;
7801       qq=rp->arguments;
7802       if (i == items)
7803         {
7804           pp=rp->arguments,
7805           sv=ST(i-1);
7806         }
7807       else
7808         for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7809         {
7810           if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7811             break;
7812           if (strEQcase(attribute,qq->method) > ssize_test)
7813             {
7814               pp=qq;
7815               ssize_test=strEQcase(attribute,qq->method);
7816             }
7817         }
7818       if (pp == (Arguments *) NULL)
7819         {
7820           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7821             attribute);
7822           goto continue_outer_loop;
7823         }
7824       al=(&argument_list[pp-rp->arguments]);
7825       switch (pp->type)
7826       {
7827         case ArrayReference:
7828         {
7829           if (SvTYPE(sv) != SVt_RV)
7830             {
7831               (void) FormatLocaleString(message,MagickPathExtent,
7832                 "invalid %.60s value",pp->method);
7833               ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7834               goto continue_outer_loop;
7835             }
7836           al->array_reference=SvRV(sv);
7837           break;
7838         }
7839         case RealReference:
7840         {
7841           al->real_reference=SvNV(sv);
7842           break;
7843         }
7844         case FileReference:
7845         {
7846           al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7847           break;
7848         }
7849         case ImageReference:
7850         {
7851           if (!sv_isobject(sv) ||
7852               !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7853                 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7854             {
7855               ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7856                 PackageName);
7857               goto PerlException;
7858             }
7859           break;
7860         }
7861         case IntegerReference:
7862         {
7863           al->integer_reference=SvIV(sv);
7864           break;
7865         }
7866         case StringReference:
7867         {
7868           al->string_reference=(char *) SvPV(sv,al->length);
7869           if (sv_isobject(sv))
7870             al->image_reference=SetupList(aTHX_ SvRV(sv),
7871               (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7872           break;
7873         }
7874         default:
7875         {
7876           /*
7877             Is a string; look up name.
7878           */
7879           if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7880             {
7881               al->string_reference=(char *) SvPV(sv,al->length);
7882               al->integer_reference=(-1);
7883               break;
7884             }
7885           al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7886             MagickFalse,SvPV(sv,na));
7887           if (pp->type == MagickChannelOptions)
7888             al->integer_reference=ParseChannelOption(SvPV(sv,na));
7889           if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7890             {
7891               (void) FormatLocaleString(message,MagickPathExtent,
7892                 "invalid %.60s value",pp->method);
7893               ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7894               goto continue_outer_loop;
7895             }
7896           break;
7897         }
7898       }
7899       attribute_flag[pp-rp->arguments]++;
7900       continue_outer_loop: ;
7901     }
7902     (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7903     pv=reference_vector;
7904     SetGeometryInfo(&geometry_info);
7905     channel=DefaultChannels;
7906     for (next=image; next; next=next->next)
7907     {
7908       image=next;
7909       SetGeometry(image,&geometry);
7910       if ((region_info.width*region_info.height) != 0)
7911         (void) SetImageRegionMask(image,WritePixelMask,&region_info,exception);
7912       switch (ix)
7913       {
7914         default:
7915         {
7916           (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double) ix);
7917           ThrowPerlException(exception,OptionError,
7918             "UnrecognizedPerlMagickMethod",message);
7919           goto PerlException;
7920         }
7921         case 1:  /* Comment */
7922         {
7923           if (attribute_flag[0] == 0)
7924             argument_list[0].string_reference=(char *) NULL;
7925           (void) SetImageProperty(image,"comment",InterpretImageProperties(
7926             info ? info->image_info : (ImageInfo *) NULL,image,
7927             argument_list[0].string_reference,exception),exception);
7928           break;
7929         }
7930         case 2:  /* Label */
7931         {
7932           if (attribute_flag[0] == 0)
7933             argument_list[0].string_reference=(char *) NULL;
7934           (void) SetImageProperty(image,"label",InterpretImageProperties(
7935             info ? info->image_info : (ImageInfo *) NULL,image,
7936             argument_list[0].string_reference,exception),exception);
7937           break;
7938         }
7939         case 3:  /* AddNoise */
7940         {
7941           double
7942             attenuate;
7943 
7944           if (attribute_flag[0] == 0)
7945             argument_list[0].integer_reference=UniformNoise;
7946           attenuate=1.0;
7947           if (attribute_flag[1] != 0)
7948             attenuate=argument_list[1].real_reference;
7949           if (attribute_flag[2] != 0)
7950             channel=(ChannelType) argument_list[2].integer_reference;
7951           channel_mask=SetImageChannelMask(image,channel);
7952           image=AddNoiseImage(image,(NoiseType)
7953             argument_list[0].integer_reference,attenuate,exception);
7954           if (image != (Image *) NULL)
7955             (void) SetImageChannelMask(image,channel_mask);
7956           break;
7957         }
7958         case 4:  /* Colorize */
7959         {
7960           PixelInfo
7961             target;
7962 
7963           (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7964             0,0,&target,exception);
7965           if (attribute_flag[0] != 0)
7966             (void) QueryColorCompliance(argument_list[0].string_reference,
7967               AllCompliance,&target,exception);
7968           if (attribute_flag[1] == 0)
7969             argument_list[1].string_reference="100%";
7970           image=ColorizeImage(image,argument_list[1].string_reference,&target,
7971             exception);
7972           break;
7973         }
7974         case 5:  /* Border */
7975         {
7976           CompositeOperator
7977             compose;
7978 
7979           geometry.width=0;
7980           geometry.height=0;
7981           if (attribute_flag[0] != 0)
7982             flags=ParsePageGeometry(image,argument_list[0].string_reference,
7983               &geometry,exception);
7984           if (attribute_flag[1] != 0)
7985             geometry.width=argument_list[1].integer_reference;
7986           if (attribute_flag[2] != 0)
7987             geometry.height=argument_list[2].integer_reference;
7988           if (attribute_flag[3] != 0)
7989             QueryColorCompliance(argument_list[3].string_reference,
7990               AllCompliance,&image->border_color,exception);
7991           if (attribute_flag[4] != 0)
7992             QueryColorCompliance(argument_list[4].string_reference,
7993               AllCompliance,&image->border_color,exception);
7994           if (attribute_flag[5] != 0)
7995             QueryColorCompliance(argument_list[5].string_reference,
7996               AllCompliance,&image->border_color,exception);
7997           compose=image->compose;
7998           if (attribute_flag[6] != 0)
7999             compose=(CompositeOperator) argument_list[6].integer_reference;
8000           image=BorderImage(image,&geometry,compose,exception);
8001           break;
8002         }
8003         case 6:  /* Blur */
8004         {
8005           if (attribute_flag[0] != 0)
8006             {
8007               flags=ParseGeometry(argument_list[0].string_reference,
8008                 &geometry_info);
8009               if ((flags & SigmaValue) == 0)
8010                 geometry_info.sigma=1.0;
8011             }
8012           if (attribute_flag[1] != 0)
8013             geometry_info.rho=argument_list[1].real_reference;
8014           if (attribute_flag[2] != 0)
8015             geometry_info.sigma=argument_list[2].real_reference;
8016           if (attribute_flag[3] != 0)
8017             channel=(ChannelType) argument_list[3].integer_reference;
8018           channel_mask=SetImageChannelMask(image,channel);
8019           image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
8020             exception);
8021           if (image != (Image *) NULL)
8022             (void) SetImageChannelMask(image,channel_mask);
8023           break;
8024         }
8025         case 7:  /* Chop */
8026         {
8027           if (attribute_flag[5] != 0)
8028             image->gravity=(GravityType) argument_list[5].integer_reference;
8029           if (attribute_flag[0] != 0)
8030             flags=ParseGravityGeometry(image,argument_list[0].string_reference,
8031               &geometry,exception);
8032           if (attribute_flag[1] != 0)
8033             geometry.width=argument_list[1].integer_reference;
8034           if (attribute_flag[2] != 0)
8035             geometry.height=argument_list[2].integer_reference;
8036           if (attribute_flag[3] != 0)
8037             geometry.x=argument_list[3].integer_reference;
8038           if (attribute_flag[4] != 0)
8039             geometry.y=argument_list[4].integer_reference;
8040           image=ChopImage(image,&geometry,exception);
8041           break;
8042         }
8043         case 8:  /* Crop */
8044         {
8045           if (attribute_flag[6] != 0)
8046             image->gravity=(GravityType) argument_list[6].integer_reference;
8047           if (attribute_flag[0] != 0)
8048             flags=ParseGravityGeometry(image,argument_list[0].string_reference,
8049               &geometry,exception);
8050           if (attribute_flag[1] != 0)
8051             geometry.width=argument_list[1].integer_reference;
8052           if (attribute_flag[2] != 0)
8053             geometry.height=argument_list[2].integer_reference;
8054           if (attribute_flag[3] != 0)
8055             geometry.x=argument_list[3].integer_reference;
8056           if (attribute_flag[4] != 0)
8057             geometry.y=argument_list[4].integer_reference;
8058           if (attribute_flag[5] != 0)
8059             image->fuzz=StringToDoubleInterval(
8060               argument_list[5].string_reference,(double) QuantumRange+1.0);
8061           image=CropImage(image,&geometry,exception);
8062           break;
8063         }
8064         case 9:  /* Despeckle */
8065         {
8066           image=DespeckleImage(image,exception);
8067           break;
8068         }
8069         case 10:  /* Edge */
8070         {
8071           if (attribute_flag[0] != 0)
8072             geometry_info.rho=argument_list[0].real_reference;
8073           image=EdgeImage(image,geometry_info.rho,exception);
8074           break;
8075         }
8076         case 11:  /* Emboss */
8077         {
8078           if (attribute_flag[0] != 0)
8079             {
8080               flags=ParseGeometry(argument_list[0].string_reference,
8081                 &geometry_info);
8082               if ((flags & SigmaValue) == 0)
8083                 geometry_info.sigma=1.0;
8084             }
8085           if (attribute_flag[1] != 0)
8086             geometry_info.rho=argument_list[1].real_reference;
8087           if (attribute_flag[2] != 0)
8088             geometry_info.sigma=argument_list[2].real_reference;
8089           image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
8090             exception);
8091           break;
8092         }
8093         case 12:  /* Enhance */
8094         {
8095           image=EnhanceImage(image,exception);
8096           break;
8097         }
8098         case 13:  /* Flip */
8099         {
8100           image=FlipImage(image,exception);
8101           break;
8102         }
8103         case 14:  /* Flop */
8104         {
8105           image=FlopImage(image,exception);
8106           break;
8107         }
8108         case 15:  /* Frame */
8109         {
8110           CompositeOperator
8111             compose;
8112 
8113           FrameInfo
8114             frame_info;
8115 
8116           if (attribute_flag[0] != 0)
8117             {
8118               flags=ParsePageGeometry(image,argument_list[0].string_reference,
8119                 &geometry,exception);
8120               frame_info.width=geometry.width;
8121               frame_info.height=geometry.height;
8122               frame_info.outer_bevel=geometry.x;
8123               frame_info.inner_bevel=geometry.y;
8124             }
8125           if (attribute_flag[1] != 0)
8126             frame_info.width=argument_list[1].integer_reference;
8127           if (attribute_flag[2] != 0)
8128             frame_info.height=argument_list[2].integer_reference;
8129           if (attribute_flag[3] != 0)
8130             frame_info.inner_bevel=argument_list[3].integer_reference;
8131           if (attribute_flag[4] != 0)
8132             frame_info.outer_bevel=argument_list[4].integer_reference;
8133           if (attribute_flag[5] != 0)
8134             QueryColorCompliance(argument_list[5].string_reference,
8135               AllCompliance,&fill_color,exception);
8136           if (attribute_flag[6] != 0)
8137             QueryColorCompliance(argument_list[6].string_reference,
8138               AllCompliance,&fill_color,exception);
8139           frame_info.x=(ssize_t) frame_info.width;
8140           frame_info.y=(ssize_t) frame_info.height;
8141           frame_info.width=image->columns+2*frame_info.x;
8142           frame_info.height=image->rows+2*frame_info.y;
8143           if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
8144             image->alpha_color=fill_color;
8145           compose=image->compose;
8146           if (attribute_flag[7] != 0)
8147             compose=(CompositeOperator) argument_list[7].integer_reference;
8148           image=FrameImage(image,&frame_info,compose,exception);
8149           break;
8150         }
8151         case 16:  /* Implode */
8152         {
8153           PixelInterpolateMethod
8154             method;
8155 
8156           if (attribute_flag[0] == 0)
8157             argument_list[0].real_reference=0.5;
8158           method=UndefinedInterpolatePixel;
8159           if (attribute_flag[1] != 0)
8160             method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8161           image=ImplodeImage(image,argument_list[0].real_reference,
8162             method,exception);
8163           break;
8164         }
8165         case 17:  /* Magnify */
8166         {
8167           image=MagnifyImage(image,exception);
8168           break;
8169         }
8170         case 18:  /* MedianFilter */
8171         {
8172           if (attribute_flag[0] != 0)
8173             {
8174               flags=ParseGeometry(argument_list[0].string_reference,
8175                 &geometry_info);
8176               if ((flags & SigmaValue) == 0)
8177                 geometry_info.sigma=geometry_info.rho;
8178             }
8179           if (attribute_flag[1] != 0)
8180             geometry_info.rho=argument_list[1].real_reference;
8181           if (attribute_flag[2] != 0)
8182             geometry_info.sigma=argument_list[2].real_reference;
8183           if (attribute_flag[3] != 0)
8184             channel=(ChannelType) argument_list[3].integer_reference;
8185           channel_mask=SetImageChannelMask(image,channel);
8186           image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
8187             (size_t) geometry_info.sigma,exception);
8188           if (image != (Image *) NULL)
8189             (void) SetImageChannelMask(image,channel_mask);
8190           break;
8191         }
8192         case 19:  /* Minify */
8193         {
8194           image=MinifyImage(image,exception);
8195           break;
8196         }
8197         case 20:  /* OilPaint */
8198         {
8199           if (attribute_flag[0] == 0)
8200             argument_list[0].real_reference=0.0;
8201           if (attribute_flag[1] == 0)
8202             argument_list[1].real_reference=1.0;
8203           image=OilPaintImage(image,argument_list[0].real_reference,
8204             argument_list[1].real_reference,exception);
8205           break;
8206         }
8207         case 21:  /* ReduceNoise */
8208         {
8209           if (attribute_flag[0] != 0)
8210             {
8211               flags=ParseGeometry(argument_list[0].string_reference,
8212                 &geometry_info);
8213               if ((flags & SigmaValue) == 0)
8214                 geometry_info.sigma=1.0;
8215             }
8216           if (attribute_flag[1] != 0)
8217             geometry_info.rho=argument_list[1].real_reference;
8218           if (attribute_flag[2] != 0)
8219             geometry_info.sigma=argument_list[2].real_reference;
8220           if (attribute_flag[3] != 0)
8221             channel=(ChannelType) argument_list[3].integer_reference;
8222           channel_mask=SetImageChannelMask(image,channel);
8223           image=StatisticImage(image,NonpeakStatistic,(size_t)
8224             geometry_info.rho,(size_t) geometry_info.sigma,exception);
8225           if (image != (Image *) NULL)
8226             (void) SetImageChannelMask(image,channel_mask);
8227           break;
8228         }
8229         case 22:  /* Roll */
8230         {
8231           if (attribute_flag[0] != 0)
8232             {
8233               flags=ParsePageGeometry(image,argument_list[0].string_reference,
8234                 &geometry,exception);
8235               if ((flags & PercentValue) != 0)
8236                 {
8237                   geometry.x*=(double) image->columns/100.0;
8238                   geometry.y*=(double) image->rows/100.0;
8239                 }
8240             }
8241           if (attribute_flag[1] != 0)
8242             geometry.x=argument_list[1].integer_reference;
8243           if (attribute_flag[2] != 0)
8244             geometry.y=argument_list[2].integer_reference;
8245           image=RollImage(image,geometry.x,geometry.y,exception);
8246           break;
8247         }
8248         case 23:  /* Rotate */
8249         {
8250           if (attribute_flag[0] == 0)
8251             argument_list[0].real_reference=90.0;
8252           if (attribute_flag[1] != 0)
8253             {
8254               QueryColorCompliance(argument_list[1].string_reference,
8255                 AllCompliance,&image->background_color,exception);
8256               if ((image->background_color.alpha_trait != UndefinedPixelTrait) &&
8257                   (image->alpha_trait == UndefinedPixelTrait))
8258                 (void) SetImageAlpha(image,OpaqueAlpha,exception);
8259             }
8260           image=RotateImage(image,argument_list[0].real_reference,exception);
8261           break;
8262         }
8263         case 24:  /* Sample */
8264         {
8265           if (attribute_flag[0] != 0)
8266             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8267               &geometry,exception);
8268           if (attribute_flag[1] != 0)
8269             geometry.width=argument_list[1].integer_reference;
8270           if (attribute_flag[2] != 0)
8271             geometry.height=argument_list[2].integer_reference;
8272           image=SampleImage(image,geometry.width,geometry.height,exception);
8273           break;
8274         }
8275         case 25:  /* Scale */
8276         {
8277           if (attribute_flag[0] != 0)
8278             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8279               &geometry,exception);
8280           if (attribute_flag[1] != 0)
8281             geometry.width=argument_list[1].integer_reference;
8282           if (attribute_flag[2] != 0)
8283             geometry.height=argument_list[2].integer_reference;
8284           image=ScaleImage(image,geometry.width,geometry.height,exception);
8285           break;
8286         }
8287         case 26:  /* Shade */
8288         {
8289           if (attribute_flag[0] != 0)
8290             {
8291               flags=ParseGeometry(argument_list[0].string_reference,
8292                 &geometry_info);
8293               if ((flags & SigmaValue) == 0)
8294                 geometry_info.sigma=0.0;
8295             }
8296           if (attribute_flag[1] != 0)
8297             geometry_info.rho=argument_list[1].real_reference;
8298           if (attribute_flag[2] != 0)
8299             geometry_info.sigma=argument_list[2].real_reference;
8300           image=ShadeImage(image,
8301             argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8302             geometry_info.rho,geometry_info.sigma,exception);
8303           break;
8304         }
8305         case 27:  /* Sharpen */
8306         {
8307           if (attribute_flag[0] != 0)
8308             {
8309               flags=ParseGeometry(argument_list[0].string_reference,
8310                 &geometry_info);
8311               if ((flags & SigmaValue) == 0)
8312                 geometry_info.sigma=1.0;
8313             }
8314           if (attribute_flag[1] != 0)
8315             geometry_info.rho=argument_list[1].real_reference;
8316           if (attribute_flag[2] != 0)
8317             geometry_info.sigma=argument_list[2].real_reference;
8318           if (attribute_flag[3] != 0)
8319             channel=(ChannelType) argument_list[3].integer_reference;
8320           channel_mask=SetImageChannelMask(image,channel);
8321           image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8322             exception);
8323           if (image != (Image *) NULL)
8324             (void) SetImageChannelMask(image,channel_mask);
8325           break;
8326         }
8327         case 28:  /* Shear */
8328         {
8329           if (attribute_flag[0] != 0)
8330             {
8331               flags=ParseGeometry(argument_list[0].string_reference,
8332                 &geometry_info);
8333               if ((flags & SigmaValue) == 0)
8334                 geometry_info.sigma=geometry_info.rho;
8335             }
8336           if (attribute_flag[1] != 0)
8337             geometry_info.rho=argument_list[1].real_reference;
8338           if (attribute_flag[2] != 0)
8339             geometry_info.sigma=argument_list[2].real_reference;
8340           if (attribute_flag[3] != 0)
8341             QueryColorCompliance(argument_list[3].string_reference,
8342               AllCompliance,&image->background_color,exception);
8343           if (attribute_flag[4] != 0)
8344             QueryColorCompliance(argument_list[4].string_reference,
8345               AllCompliance,&image->background_color,exception);
8346           image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8347             exception);
8348           break;
8349         }
8350         case 29:  /* Spread */
8351         {
8352           PixelInterpolateMethod
8353             method;
8354 
8355           if (attribute_flag[0] == 0)
8356             argument_list[0].real_reference=1.0;
8357           method=UndefinedInterpolatePixel;
8358           if (attribute_flag[1] != 0)
8359             method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8360           image=SpreadImage(image,method,argument_list[0].real_reference,
8361             exception);
8362           break;
8363         }
8364         case 30:  /* Swirl */
8365         {
8366           PixelInterpolateMethod
8367             method;
8368 
8369           if (attribute_flag[0] == 0)
8370             argument_list[0].real_reference=50.0;
8371           method=UndefinedInterpolatePixel;
8372           if (attribute_flag[1] != 0)
8373             method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8374           image=SwirlImage(image,argument_list[0].real_reference,
8375             method,exception);
8376           break;
8377         }
8378         case 31:  /* Resize */
8379         case 32:  /* Zoom */
8380         {
8381           if (attribute_flag[0] != 0)
8382             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8383               &geometry,exception);
8384           if (attribute_flag[1] != 0)
8385             geometry.width=argument_list[1].integer_reference;
8386           if (attribute_flag[2] != 0)
8387             geometry.height=argument_list[2].integer_reference;
8388           if (attribute_flag[3] == 0)
8389             argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8390           if (attribute_flag[4] != 0)
8391             SetImageArtifact(image,"filter:support",
8392               argument_list[4].string_reference);
8393           image=ResizeImage(image,geometry.width,geometry.height,
8394             (FilterType) argument_list[3].integer_reference,
8395             exception);
8396           break;
8397         }
8398         case 33:  /* Annotate */
8399         {
8400           DrawInfo
8401             *draw_info;
8402 
8403           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8404             (DrawInfo *) NULL);
8405           if (attribute_flag[0] != 0)
8406             {
8407               char
8408                 *text;
8409 
8410               text=InterpretImageProperties(info ? info->image_info :
8411                 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8412                 exception);
8413               (void) CloneString(&draw_info->text,text);
8414               text=DestroyString(text);
8415             }
8416           if (attribute_flag[1] != 0)
8417             (void) CloneString(&draw_info->font,
8418               argument_list[1].string_reference);
8419           if (attribute_flag[2] != 0)
8420             draw_info->pointsize=argument_list[2].real_reference;
8421           if (attribute_flag[3] != 0)
8422             (void) CloneString(&draw_info->density,
8423               argument_list[3].string_reference);
8424           if (attribute_flag[4] != 0)
8425             (void) QueryColorCompliance(argument_list[4].string_reference,
8426               AllCompliance,&draw_info->undercolor,exception);
8427           if (attribute_flag[5] != 0)
8428             {
8429               (void) QueryColorCompliance(argument_list[5].string_reference,
8430                 AllCompliance,&draw_info->stroke,exception);
8431               if (argument_list[5].image_reference != (Image *) NULL)
8432                 draw_info->stroke_pattern=CloneImage(
8433                   argument_list[5].image_reference,0,0,MagickTrue,exception);
8434             }
8435           if (attribute_flag[6] != 0)
8436             {
8437               (void) QueryColorCompliance(argument_list[6].string_reference,
8438                 AllCompliance,&draw_info->fill,exception);
8439               if (argument_list[6].image_reference != (Image *) NULL)
8440                 draw_info->fill_pattern=CloneImage(
8441                   argument_list[6].image_reference,0,0,MagickTrue,exception);
8442             }
8443           if (attribute_flag[7] != 0)
8444             {
8445               (void) CloneString(&draw_info->geometry,
8446                 argument_list[7].string_reference);
8447               flags=ParsePageGeometry(image,argument_list[7].string_reference,
8448                 &geometry,exception);
8449               if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8450                 geometry_info.sigma=geometry_info.xi;
8451             }
8452           if (attribute_flag[8] != 0)
8453             (void) QueryColorCompliance(argument_list[8].string_reference,
8454               AllCompliance,&draw_info->fill,exception);
8455           if (attribute_flag[11] != 0)
8456             draw_info->gravity=(GravityType)
8457               argument_list[11].integer_reference;
8458           if (attribute_flag[25] != 0)
8459             {
8460               AV
8461                 *av;
8462 
8463               av=(AV *) argument_list[25].array_reference;
8464               if ((av_len(av) != 3) && (av_len(av) != 5))
8465                 {
8466                   ThrowPerlException(exception,OptionError,
8467                     "affine matrix must have 4 or 6 elements",PackageName);
8468                   goto PerlException;
8469                 }
8470               draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8471               draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8472               draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8473               draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8474               if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8475                   draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8476                 {
8477                   ThrowPerlException(exception,OptionError,
8478                     "affine matrix is singular",PackageName);
8479                    goto PerlException;
8480                 }
8481               if (av_len(av) == 5)
8482                 {
8483                   draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8484                   draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8485                 }
8486             }
8487           for (j=12; j < 17; j++)
8488           {
8489             if (attribute_flag[j] == 0)
8490               continue;
8491             value=argument_list[j].string_reference;
8492             angle=argument_list[j].real_reference;
8493             current=draw_info->affine;
8494             GetAffineMatrix(&affine);
8495             switch (j)
8496             {
8497               case 12:
8498               {
8499                 /*
8500                   Translate.
8501                 */
8502                 flags=ParseGeometry(value,&geometry_info);
8503                 affine.tx=geometry_info.xi;
8504                 affine.ty=geometry_info.psi;
8505                 if ((flags & PsiValue) == 0)
8506                   affine.ty=affine.tx;
8507                 break;
8508               }
8509               case 13:
8510               {
8511                 /*
8512                   Scale.
8513                 */
8514                 flags=ParseGeometry(value,&geometry_info);
8515                 affine.sx=geometry_info.rho;
8516                 affine.sy=geometry_info.sigma;
8517                 if ((flags & SigmaValue) == 0)
8518                   affine.sy=affine.sx;
8519                 break;
8520               }
8521               case 14:
8522               {
8523                 /*
8524                   Rotate.
8525                 */
8526                 if (angle == 0.0)
8527                   break;
8528                 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8529                 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8530                 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8531                 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8532                 break;
8533               }
8534               case 15:
8535               {
8536                 /*
8537                   SkewX.
8538                 */
8539                 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8540                 break;
8541               }
8542               case 16:
8543               {
8544                 /*
8545                   SkewY.
8546                 */
8547                 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8548                 break;
8549               }
8550             }
8551             draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8552             draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8553             draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8554             draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8555             draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8556               current.tx;
8557             draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8558               current.ty;
8559           }
8560           if (attribute_flag[9] == 0)
8561             argument_list[9].real_reference=0.0;
8562           if (attribute_flag[10] == 0)
8563             argument_list[10].real_reference=0.0;
8564           if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8565             {
8566               char
8567                 geometry[MagickPathExtent];
8568 
8569               (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
8570                 (double) argument_list[9].real_reference+draw_info->affine.tx,
8571                 (double) argument_list[10].real_reference+draw_info->affine.ty);
8572               (void) CloneString(&draw_info->geometry,geometry);
8573             }
8574           if (attribute_flag[17] != 0)
8575             draw_info->stroke_width=argument_list[17].real_reference;
8576           if (attribute_flag[18] != 0)
8577             {
8578               draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8579                 MagickTrue : MagickFalse;
8580               draw_info->stroke_antialias=draw_info->text_antialias;
8581             }
8582           if (attribute_flag[19] != 0)
8583             (void) CloneString(&draw_info->family,
8584               argument_list[19].string_reference);
8585           if (attribute_flag[20] != 0)
8586             draw_info->style=(StyleType) argument_list[20].integer_reference;
8587           if (attribute_flag[21] != 0)
8588             draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8589           if (attribute_flag[22] != 0)
8590             draw_info->weight=argument_list[22].integer_reference;
8591           if (attribute_flag[23] != 0)
8592             draw_info->align=(AlignType) argument_list[23].integer_reference;
8593           if (attribute_flag[24] != 0)
8594             (void) CloneString(&draw_info->encoding,
8595               argument_list[24].string_reference);
8596           if (attribute_flag[25] != 0)
8597             draw_info->fill_pattern=CloneImage(
8598               argument_list[25].image_reference,0,0,MagickTrue,exception);
8599           if (attribute_flag[26] != 0)
8600             draw_info->fill_pattern=CloneImage(
8601               argument_list[26].image_reference,0,0,MagickTrue,exception);
8602           if (attribute_flag[27] != 0)
8603             draw_info->stroke_pattern=CloneImage(
8604               argument_list[27].image_reference,0,0,MagickTrue,exception);
8605           if (attribute_flag[29] != 0)
8606             draw_info->kerning=argument_list[29].real_reference;
8607           if (attribute_flag[30] != 0)
8608             draw_info->interline_spacing=argument_list[30].real_reference;
8609           if (attribute_flag[31] != 0)
8610             draw_info->interword_spacing=argument_list[31].real_reference;
8611           if (attribute_flag[32] != 0)
8612             draw_info->direction=(DirectionType)
8613               argument_list[32].integer_reference;
8614           if (attribute_flag[33] != 0)
8615             draw_info->decorate=(DecorationType)
8616               argument_list[33].integer_reference;
8617           (void) AnnotateImage(image,draw_info,exception);
8618           draw_info=DestroyDrawInfo(draw_info);
8619           break;
8620         }
8621         case 34:  /* ColorFloodfill */
8622         {
8623           DrawInfo
8624             *draw_info;
8625 
8626           MagickBooleanType
8627             invert;
8628 
8629           PixelInfo
8630             target;
8631 
8632           draw_info=CloneDrawInfo(info ? info->image_info :
8633             (ImageInfo *) NULL,(DrawInfo *) NULL);
8634           if (attribute_flag[0] != 0)
8635             flags=ParsePageGeometry(image,argument_list[0].string_reference,
8636               &geometry,exception);
8637           if (attribute_flag[1] != 0)
8638             geometry.x=argument_list[1].integer_reference;
8639           if (attribute_flag[2] != 0)
8640             geometry.y=argument_list[2].integer_reference;
8641           if (attribute_flag[3] != 0)
8642             (void) QueryColorCompliance(argument_list[3].string_reference,
8643               AllCompliance,&draw_info->fill,exception);
8644           (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8645             geometry.x,geometry.y,&target,exception);
8646           invert=MagickFalse;
8647           if (attribute_flag[4] != 0)
8648             {
8649               QueryColorCompliance(argument_list[4].string_reference,
8650                 AllCompliance,&target,exception);
8651               invert=MagickTrue;
8652             }
8653           if (attribute_flag[5] != 0)
8654             image->fuzz=StringToDoubleInterval(
8655               argument_list[5].string_reference,(double) QuantumRange+1.0);
8656           if (attribute_flag[6] != 0)
8657             invert=(MagickBooleanType) argument_list[6].integer_reference;
8658           (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8659             geometry.y,invert,exception);
8660           draw_info=DestroyDrawInfo(draw_info);
8661           break;
8662         }
8663         case 35:  /* Composite */
8664         {
8665           char
8666             composite_geometry[MagickPathExtent];
8667 
8668           Image
8669             *composite_image,
8670             *rotate_image;
8671 
8672           MagickBooleanType
8673             clip_to_self;
8674 
8675           compose=OverCompositeOp;
8676           if (attribute_flag[0] != 0)
8677             composite_image=argument_list[0].image_reference;
8678           else
8679             {
8680               ThrowPerlException(exception,OptionError,
8681                 "CompositeImageRequired",PackageName);
8682               goto PerlException;
8683             }
8684           /*
8685             Parameter Handling used for BOTH normal and tiled composition.
8686           */
8687           if (attribute_flag[1] != 0) /* compose */
8688             compose=(CompositeOperator) argument_list[1].integer_reference;
8689           if (attribute_flag[6] != 0) /* opacity  */
8690             {
8691               if (compose != DissolveCompositeOp)
8692                 (void) SetImageAlpha(composite_image,(Quantum)
8693                   StringToDoubleInterval(argument_list[6].string_reference,
8694                   (double) QuantumRange+1.0),exception);
8695               else
8696                 {
8697                   CacheView
8698                     *composite_view;
8699 
8700                   double
8701                     opacity;
8702 
8703                   MagickBooleanType
8704                     sync;
8705 
8706                   register ssize_t
8707                     x;
8708 
8709                   register Quantum
8710                     *q;
8711 
8712                   ssize_t
8713                     y;
8714 
8715                   /*
8716                     Handle dissolve composite operator (patch by
8717                     Kevin A. McGrail).
8718                   */
8719                   (void) CloneString(&image->geometry,
8720                     argument_list[6].string_reference);
8721                   opacity=(Quantum) StringToDoubleInterval(
8722                     argument_list[6].string_reference,(double) QuantumRange+
8723                     1.0);
8724                   if (composite_image->alpha_trait != UndefinedPixelTrait)
8725                     (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8726                   composite_view=AcquireAuthenticCacheView(composite_image,exception);
8727                   for (y=0; y < (ssize_t) composite_image->rows ; y++)
8728                   {
8729                     q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8730                       composite_image->columns,1,exception);
8731                     for (x=0; x < (ssize_t) composite_image->columns; x++)
8732                     {
8733                       if (GetPixelAlpha(image,q) == OpaqueAlpha)
8734                         SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8735                           q);
8736                       q+=GetPixelChannels(composite_image);
8737                     }
8738                     sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8739                     if (sync == MagickFalse)
8740                       break;
8741                   }
8742                   composite_view=DestroyCacheView(composite_view);
8743                 }
8744             }
8745           if (attribute_flag[9] != 0)    /* "color=>" */
8746             QueryColorCompliance(argument_list[9].string_reference,
8747               AllCompliance,&composite_image->background_color,exception);
8748           if (attribute_flag[12] != 0) /* "interpolate=>" */
8749             image->interpolate=(PixelInterpolateMethod)
8750               argument_list[12].integer_reference;
8751           if (attribute_flag[13] != 0)   /* "args=>" */
8752             (void) SetImageArtifact(composite_image,"compose:args",
8753               argument_list[13].string_reference);
8754           if (attribute_flag[14] != 0)   /* "blend=>"  depreciated */
8755             (void) SetImageArtifact(composite_image,"compose:args",
8756               argument_list[14].string_reference);
8757           clip_to_self=MagickTrue;
8758           switch (compose)
8759           {
8760             case ClearCompositeOp:
8761             case SrcCompositeOp:
8762             case InCompositeOp:
8763             case SrcInCompositeOp:
8764             case OutCompositeOp:
8765             case SrcOutCompositeOp:
8766             case DstInCompositeOp:
8767             case DstAtopCompositeOp:
8768             case CopyAlphaCompositeOp:
8769             case ChangeMaskCompositeOp:
8770             case DissolveCompositeOp:
8771             case BlendCompositeOp:
8772             {
8773               clip_to_self=MagickFalse;
8774               break;
8775             }
8776             default:
8777               break;
8778           }
8779           if (attribute_flag[15] != 0)
8780             clip_to_self=(MagickBooleanType)
8781               argument_list[15].integer_reference;
8782           /*
8783             Tiling Composition (with orthogonal rotate).
8784           */
8785           rotate_image=(Image *) NULL;
8786           if (attribute_flag[8] != 0)   /* "rotate=>" */
8787             {
8788                /*
8789                  Rotate image.
8790                */
8791                rotate_image=RotateImage(composite_image,
8792                  argument_list[8].real_reference,exception);
8793                if (rotate_image == (Image *) NULL)
8794                  break;
8795             }
8796           if ((attribute_flag[7] != 0) &&
8797               (argument_list[7].integer_reference != 0)) /* tile */
8798             {
8799               ssize_t
8800                 x,
8801                 y;
8802 
8803               /*
8804                 Tile the composite image.
8805               */
8806              for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8807                 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8808                 {
8809                   if (attribute_flag[8] != 0) /* rotate */
8810                     (void) CompositeImage(image,rotate_image,compose,
8811                       MagickTrue,x,y,exception);
8812                   else
8813                     (void) CompositeImage(image,composite_image,compose,
8814                       MagickTrue,x,y,exception);
8815                 }
8816               if (attribute_flag[8] != 0) /* rotate */
8817                 rotate_image=DestroyImage(rotate_image);
8818               break;
8819             }
8820           /*
8821             Parameter Handling used used ONLY for normal composition.
8822           */
8823           if (attribute_flag[5] != 0) /* gravity */
8824             image->gravity=(GravityType) argument_list[5].integer_reference;
8825           if (attribute_flag[2] != 0) /* geometry offset */
8826             {
8827               SetGeometry(image,&geometry);
8828               (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8829                 &geometry);
8830               GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8831                 &geometry);
8832             }
8833           if (attribute_flag[3] != 0) /* x offset */
8834             geometry.x=argument_list[3].integer_reference;
8835           if (attribute_flag[4] != 0) /* y offset */
8836             geometry.y=argument_list[4].integer_reference;
8837           if (attribute_flag[10] != 0) /* mask */
8838             {
8839               if ((image->compose == DisplaceCompositeOp) ||
8840                   (image->compose == DistortCompositeOp))
8841                 {
8842                   /*
8843                     Merge Y displacement into X displacement image.
8844                   */
8845                   composite_image=CloneImage(composite_image,0,0,MagickTrue,
8846                     exception);
8847                   (void) CompositeImage(composite_image,
8848                     argument_list[10].image_reference,CopyGreenCompositeOp,
8849                     clip_to_self,0,0,exception);
8850                 }
8851               else
8852                 {
8853                   Image
8854                     *mask_image;
8855 
8856                   /*
8857                     Set a blending mask for the composition.
8858                   */
8859                   mask_image=CloneImage(argument_list[10].image_reference,0,0,
8860                     MagickTrue,exception);
8861                   (void) SetImageMask(composite_image,ReadPixelMask,mask_image,
8862                     exception);
8863                   mask_image=DestroyImage(mask_image);
8864                 }
8865             }
8866           if (attribute_flag[11] != 0) /* channel */
8867             channel=(ChannelType) argument_list[11].integer_reference;
8868           /*
8869             Composite two images (normal composition).
8870           */
8871           (void) FormatLocaleString(composite_geometry,MagickPathExtent,
8872             "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8873             (double) composite_image->rows,(double) geometry.x,(double)
8874             geometry.y);
8875           flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8876             exception);
8877           channel_mask=SetImageChannelMask(image,channel);
8878           if (attribute_flag[8] == 0) /* no rotate */
8879             CompositeImage(image,composite_image,compose,clip_to_self,
8880               geometry.x,geometry.y,exception);
8881           else
8882             {
8883               /*
8884                 Position adjust rotated image then composite.
8885               */
8886               geometry.x-=(ssize_t) (rotate_image->columns-
8887                 composite_image->columns)/2;
8888               geometry.y-=(ssize_t) (rotate_image->rows-
8889                 composite_image->rows)/2;
8890               CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8891                 geometry.y,exception);
8892               rotate_image=DestroyImage(rotate_image);
8893             }
8894           if (attribute_flag[10] != 0) /* mask */
8895             {
8896               if ((image->compose == DisplaceCompositeOp) ||
8897                   (image->compose == DistortCompositeOp))
8898                 composite_image=DestroyImage(composite_image);
8899               else
8900                 (void) SetImageMask(image,ReadPixelMask,(Image *) NULL,
8901                   exception);
8902             }
8903           (void) SetImageChannelMask(image,channel_mask);
8904           break;
8905         }
8906         case 36:  /* Contrast */
8907         {
8908           if (attribute_flag[0] == 0)
8909             argument_list[0].integer_reference=0;
8910           (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8911             MagickTrue : MagickFalse,exception);
8912           break;
8913         }
8914         case 37:  /* CycleColormap */
8915         {
8916           if (attribute_flag[0] == 0)
8917             argument_list[0].integer_reference=6;
8918           (void) CycleColormapImage(image,argument_list[0].integer_reference,
8919             exception);
8920           break;
8921         }
8922         case 38:  /* Draw */
8923         {
8924           DrawInfo
8925             *draw_info;
8926 
8927           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8928             (DrawInfo *) NULL);
8929           (void) CloneString(&draw_info->primitive,"point");
8930           if (attribute_flag[0] != 0)
8931             {
8932               if (argument_list[0].integer_reference < 0)
8933                 (void) CloneString(&draw_info->primitive,
8934                   argument_list[0].string_reference);
8935               else
8936                 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8937                   MagickPrimitiveOptions,argument_list[0].integer_reference));
8938             }
8939           if (attribute_flag[1] != 0)
8940             {
8941               if (LocaleCompare(draw_info->primitive,"path") == 0)
8942                 {
8943                   (void) ConcatenateString(&draw_info->primitive," '");
8944                   ConcatenateString(&draw_info->primitive,
8945                     argument_list[1].string_reference);
8946                   (void) ConcatenateString(&draw_info->primitive,"'");
8947                 }
8948               else
8949                 {
8950                   (void) ConcatenateString(&draw_info->primitive," ");
8951                   ConcatenateString(&draw_info->primitive,
8952                     argument_list[1].string_reference);
8953                 }
8954             }
8955           if (attribute_flag[2] != 0)
8956             {
8957               (void) ConcatenateString(&draw_info->primitive," ");
8958               (void) ConcatenateString(&draw_info->primitive,
8959                 CommandOptionToMnemonic(MagickMethodOptions,
8960                 argument_list[2].integer_reference));
8961             }
8962           if (attribute_flag[3] != 0)
8963             {
8964               (void) QueryColorCompliance(argument_list[3].string_reference,
8965                 AllCompliance,&draw_info->stroke,exception);
8966               if (argument_list[3].image_reference != (Image *) NULL)
8967                 draw_info->stroke_pattern=CloneImage(
8968                   argument_list[3].image_reference,0,0,MagickTrue,exception);
8969             }
8970           if (attribute_flag[4] != 0)
8971             {
8972               (void) QueryColorCompliance(argument_list[4].string_reference,
8973                 AllCompliance,&draw_info->fill,exception);
8974               if (argument_list[4].image_reference != (Image *) NULL)
8975                 draw_info->fill_pattern=CloneImage(
8976                   argument_list[4].image_reference,0,0,MagickTrue,exception);
8977             }
8978           if (attribute_flag[5] != 0)
8979             draw_info->stroke_width=argument_list[5].real_reference;
8980           if (attribute_flag[6] != 0)
8981             (void) CloneString(&draw_info->font,
8982               argument_list[6].string_reference);
8983           if (attribute_flag[7] != 0)
8984             (void) QueryColorCompliance(argument_list[7].string_reference,
8985               AllCompliance,&draw_info->border_color,exception);
8986           if (attribute_flag[8] != 0)
8987             draw_info->affine.tx=argument_list[8].real_reference;
8988           if (attribute_flag[9] != 0)
8989             draw_info->affine.ty=argument_list[9].real_reference;
8990           if (attribute_flag[20] != 0)
8991             {
8992               AV
8993                 *av;
8994 
8995               av=(AV *) argument_list[20].array_reference;
8996               if ((av_len(av) != 3) && (av_len(av) != 5))
8997                 {
8998                   ThrowPerlException(exception,OptionError,
8999                     "affine matrix must have 4 or 6 elements",PackageName);
9000                   goto PerlException;
9001                 }
9002               draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9003               draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9004               draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9005               draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9006               if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9007                   draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9008                 {
9009                   ThrowPerlException(exception,OptionError,
9010                     "affine matrix is singular",PackageName);
9011                    goto PerlException;
9012                 }
9013               if (av_len(av) == 5)
9014                 {
9015                   draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9016                   draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9017                 }
9018             }
9019           for (j=10; j < 15; j++)
9020           {
9021             if (attribute_flag[j] == 0)
9022               continue;
9023             value=argument_list[j].string_reference;
9024             angle=argument_list[j].real_reference;
9025             current=draw_info->affine;
9026             GetAffineMatrix(&affine);
9027             switch (j)
9028             {
9029               case 10:
9030               {
9031                 /*
9032                   Translate.
9033                 */
9034                 flags=ParseGeometry(value,&geometry_info);
9035                 affine.tx=geometry_info.xi;
9036                 affine.ty=geometry_info.psi;
9037                 if ((flags & PsiValue) == 0)
9038                   affine.ty=affine.tx;
9039                 break;
9040               }
9041               case 11:
9042               {
9043                 /*
9044                   Scale.
9045                 */
9046                 flags=ParseGeometry(value,&geometry_info);
9047                 affine.sx=geometry_info.rho;
9048                 affine.sy=geometry_info.sigma;
9049                 if ((flags & SigmaValue) == 0)
9050                   affine.sy=affine.sx;
9051                 break;
9052               }
9053               case 12:
9054               {
9055                 /*
9056                   Rotate.
9057                 */
9058                 if (angle == 0.0)
9059                   break;
9060                 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9061                 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9062                 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9063                 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9064                 break;
9065               }
9066               case 13:
9067               {
9068                 /*
9069                   SkewX.
9070                 */
9071                 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9072                 break;
9073               }
9074               case 14:
9075               {
9076                 /*
9077                   SkewY.
9078                 */
9079                 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9080                 break;
9081               }
9082             }
9083             draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9084             draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9085             draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9086             draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9087             draw_info->affine.tx=
9088               current.sx*affine.tx+current.ry*affine.ty+current.tx;
9089             draw_info->affine.ty=
9090               current.rx*affine.tx+current.sy*affine.ty+current.ty;
9091           }
9092           if (attribute_flag[15] != 0)
9093             draw_info->fill_pattern=CloneImage(
9094               argument_list[15].image_reference,0,0,MagickTrue,exception);
9095           if (attribute_flag[16] != 0)
9096             draw_info->pointsize=argument_list[16].real_reference;
9097           if (attribute_flag[17] != 0)
9098             {
9099               draw_info->stroke_antialias=argument_list[17].integer_reference != 0 ? MagickTrue : MagickFalse;
9100               draw_info->text_antialias=draw_info->stroke_antialias;
9101             }
9102           if (attribute_flag[18] != 0)
9103             (void) CloneString(&draw_info->density,
9104               argument_list[18].string_reference);
9105           if (attribute_flag[19] != 0)
9106             draw_info->stroke_width=argument_list[19].real_reference;
9107           if (attribute_flag[21] != 0)
9108             draw_info->dash_offset=argument_list[21].real_reference;
9109           if (attribute_flag[22] != 0)
9110             {
9111               AV
9112                 *av;
9113 
9114               av=(AV *) argument_list[22].array_reference;
9115               draw_info->dash_pattern=(double *) AcquireQuantumMemory(
9116                 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
9117               if (draw_info->dash_pattern != (double *) NULL)
9118                 {
9119                   for (i=0; i <= av_len(av); i++)
9120                     draw_info->dash_pattern[i]=(double)
9121                       SvNV(*(av_fetch(av,i,0)));
9122                   draw_info->dash_pattern[i]=0.0;
9123                 }
9124             }
9125           if (attribute_flag[23] != 0)
9126             image->interpolate=(PixelInterpolateMethod)
9127               argument_list[23].integer_reference;
9128           if ((attribute_flag[24] != 0) &&
9129               (draw_info->fill_pattern != (Image *) NULL))
9130             flags=ParsePageGeometry(draw_info->fill_pattern,
9131               argument_list[24].string_reference,
9132               &draw_info->fill_pattern->tile_offset,exception);
9133           if (attribute_flag[25] != 0)
9134             {
9135               (void) ConcatenateString(&draw_info->primitive," '");
9136               (void) ConcatenateString(&draw_info->primitive,
9137                 argument_list[25].string_reference);
9138               (void) ConcatenateString(&draw_info->primitive,"'");
9139             }
9140           if (attribute_flag[26] != 0)
9141             draw_info->fill_pattern=CloneImage(
9142               argument_list[26].image_reference,0,0,MagickTrue,exception);
9143           if (attribute_flag[27] != 0)
9144             draw_info->stroke_pattern=CloneImage(
9145               argument_list[27].image_reference,0,0,MagickTrue,exception);
9146           if (attribute_flag[28] != 0)
9147             (void) CloneString(&draw_info->primitive,
9148               argument_list[28].string_reference);
9149           if (attribute_flag[29] != 0)
9150             draw_info->kerning=argument_list[29].real_reference;
9151           if (attribute_flag[30] != 0)
9152             draw_info->interline_spacing=argument_list[30].real_reference;
9153           if (attribute_flag[31] != 0)
9154             draw_info->interword_spacing=argument_list[31].real_reference;
9155           if (attribute_flag[32] != 0)
9156             draw_info->direction=(DirectionType)
9157               argument_list[32].integer_reference;
9158           (void) DrawImage(image,draw_info,exception);
9159           draw_info=DestroyDrawInfo(draw_info);
9160           break;
9161         }
9162         case 39:  /* Equalize */
9163         {
9164           if (attribute_flag[0] != 0)
9165             channel=(ChannelType) argument_list[0].integer_reference;
9166           channel_mask=SetImageChannelMask(image,channel);
9167           (void) EqualizeImage(image,exception);
9168           (void) SetImageChannelMask(image,channel_mask);
9169           break;
9170         }
9171         case 40:  /* Gamma */
9172         {
9173           if (attribute_flag[1] != 0)
9174             channel=(ChannelType) argument_list[1].integer_reference;
9175           if (attribute_flag[2] == 0)
9176             argument_list[2].real_reference=1.0;
9177           if (attribute_flag[3] == 0)
9178             argument_list[3].real_reference=1.0;
9179           if (attribute_flag[4] == 0)
9180             argument_list[4].real_reference=1.0;
9181           if (attribute_flag[0] == 0)
9182             {
9183               (void) FormatLocaleString(message,MagickPathExtent,
9184                 "%.20g,%.20g,%.20g",(double) argument_list[2].real_reference,
9185                 (double) argument_list[3].real_reference,
9186                 (double) argument_list[4].real_reference);
9187               argument_list[0].string_reference=message;
9188             }
9189           (void) GammaImage(image,StringToDouble(
9190             argument_list[0].string_reference,(char **) NULL),exception);
9191           break;
9192         }
9193         case 41:  /* Map */
9194         {
9195           QuantizeInfo
9196             *quantize_info;
9197 
9198           if (attribute_flag[0] == 0)
9199             {
9200               ThrowPerlException(exception,OptionError,"MapImageRequired",
9201                 PackageName);
9202               goto PerlException;
9203             }
9204           quantize_info=AcquireQuantizeInfo(info->image_info);
9205           if (attribute_flag[1] != 0)
9206             quantize_info->dither_method=(DitherMethod)
9207               argument_list[1].integer_reference;
9208           (void) RemapImages(quantize_info,image,
9209             argument_list[0].image_reference,exception);
9210           quantize_info=DestroyQuantizeInfo(quantize_info);
9211           break;
9212         }
9213         case 42:  /* MatteFloodfill */
9214         {
9215           DrawInfo
9216             *draw_info;
9217 
9218           MagickBooleanType
9219             invert;
9220 
9221           PixelInfo
9222             target;
9223 
9224           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9225             (DrawInfo *) NULL);
9226           if (attribute_flag[0] != 0)
9227             flags=ParsePageGeometry(image,argument_list[0].string_reference,
9228               &geometry,exception);
9229           if (attribute_flag[1] != 0)
9230             geometry.x=argument_list[1].integer_reference;
9231           if (attribute_flag[2] != 0)
9232             geometry.y=argument_list[2].integer_reference;
9233           if (image->alpha_trait == UndefinedPixelTrait)
9234             (void) SetImageAlpha(image,OpaqueAlpha,exception);
9235           (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
9236             geometry.x,geometry.y,&target,exception);
9237           if (attribute_flag[4] != 0)
9238             QueryColorCompliance(argument_list[4].string_reference,
9239               AllCompliance,&target,exception);
9240           if (attribute_flag[3] != 0)
9241             target.alpha=StringToDoubleInterval(
9242               argument_list[3].string_reference,(double) (double) QuantumRange+
9243               1.0);
9244           if (attribute_flag[5] != 0)
9245             image->fuzz=StringToDoubleInterval(
9246               argument_list[5].string_reference,(double) QuantumRange+1.0);
9247           invert=MagickFalse;
9248           if (attribute_flag[6] != 0)
9249             invert=(MagickBooleanType) argument_list[6].integer_reference;
9250           channel_mask=SetImageChannelMask(image,AlphaChannel);
9251           (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
9252             geometry.y,invert,exception);
9253           (void) SetImageChannelMask(image,channel_mask);
9254           draw_info=DestroyDrawInfo(draw_info);
9255           break;
9256         }
9257         case 43:  /* Modulate */
9258         {
9259           char
9260             modulate[MagickPathExtent];
9261 
9262           geometry_info.rho=100.0;
9263           geometry_info.sigma=100.0;
9264           geometry_info.xi=100.0;
9265           if (attribute_flag[0] != 0)
9266             (void)ParseGeometry(argument_list[0].string_reference,
9267               &geometry_info);
9268           if (attribute_flag[1] != 0)
9269             geometry_info.xi=argument_list[1].real_reference;
9270           if (attribute_flag[2] != 0)
9271             geometry_info.sigma=argument_list[2].real_reference;
9272           if (attribute_flag[3] != 0)
9273             {
9274               geometry_info.sigma=argument_list[3].real_reference;
9275               SetImageArtifact(image,"modulate:colorspace","HWB");
9276             }
9277           if (attribute_flag[4] != 0)
9278             {
9279               geometry_info.rho=argument_list[4].real_reference;
9280               SetImageArtifact(image,"modulate:colorspace","HSB");
9281             }
9282           if (attribute_flag[5] != 0)
9283             {
9284               geometry_info.sigma=argument_list[5].real_reference;
9285               SetImageArtifact(image,"modulate:colorspace","HSL");
9286             }
9287           if (attribute_flag[6] != 0)
9288             {
9289               geometry_info.rho=argument_list[6].real_reference;
9290               SetImageArtifact(image,"modulate:colorspace","HWB");
9291             }
9292           (void) FormatLocaleString(modulate,MagickPathExtent,"%.20g,%.20g,%.20g",
9293             geometry_info.rho,geometry_info.sigma,geometry_info.xi);
9294           (void) ModulateImage(image,modulate,exception);
9295           break;
9296         }
9297         case 44:  /* Negate */
9298         {
9299           if (attribute_flag[0] == 0)
9300             argument_list[0].integer_reference=0;
9301           if (attribute_flag[1] != 0)
9302             channel=(ChannelType) argument_list[1].integer_reference;
9303           channel_mask=SetImageChannelMask(image,channel);
9304           (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9305             MagickTrue : MagickFalse,exception);
9306           (void) SetImageChannelMask(image,channel_mask);
9307           break;
9308         }
9309         case 45:  /* Normalize */
9310         {
9311           if (attribute_flag[0] != 0)
9312             channel=(ChannelType) argument_list[0].integer_reference;
9313           channel_mask=SetImageChannelMask(image,channel);
9314           NormalizeImage(image,exception);
9315           (void) SetImageChannelMask(image,channel_mask);
9316           break;
9317         }
9318         case 46:  /* NumberColors */
9319           break;
9320         case 47:  /* Opaque */
9321         {
9322           MagickBooleanType
9323             invert;
9324 
9325           PixelInfo
9326             fill_color,
9327             target;
9328 
9329           (void) QueryColorCompliance("none",AllCompliance,&target,
9330              exception);
9331           (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9332             exception);
9333           if (attribute_flag[0] != 0)
9334             (void) QueryColorCompliance(argument_list[0].string_reference,
9335               AllCompliance,&target,exception);
9336           if (attribute_flag[1] != 0)
9337             (void) QueryColorCompliance(argument_list[1].string_reference,
9338               AllCompliance,&fill_color,exception);
9339           if (attribute_flag[2] != 0)
9340             image->fuzz=StringToDoubleInterval(
9341               argument_list[2].string_reference,(double) QuantumRange+1.0);
9342           if (attribute_flag[3] != 0)
9343             channel=(ChannelType) argument_list[3].integer_reference;
9344           invert=MagickFalse;
9345           if (attribute_flag[4] != 0)
9346             invert=(MagickBooleanType) argument_list[4].integer_reference;
9347           channel_mask=SetImageChannelMask(image,channel);
9348           (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9349           (void) SetImageChannelMask(image,channel_mask);
9350           break;
9351         }
9352         case 48:  /* Quantize */
9353         {
9354           QuantizeInfo
9355             *quantize_info;
9356 
9357           quantize_info=AcquireQuantizeInfo(info->image_info);
9358           if (attribute_flag[0] != 0)
9359             quantize_info->number_colors=(size_t)
9360               argument_list[0].integer_reference;
9361           if (attribute_flag[1] != 0)
9362             quantize_info->tree_depth=(size_t)
9363               argument_list[1].integer_reference;
9364           if (attribute_flag[2] != 0)
9365             quantize_info->colorspace=(ColorspaceType)
9366               argument_list[2].integer_reference;
9367           if (attribute_flag[3] != 0)
9368             quantize_info->dither_method=(DitherMethod)
9369               argument_list[3].integer_reference;
9370           if (attribute_flag[4] != 0)
9371             quantize_info->measure_error=
9372               argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
9373           if (attribute_flag[6] != 0)
9374             (void) QueryColorCompliance(argument_list[6].string_reference,
9375               AllCompliance,&image->transparent_color,exception);
9376           if (attribute_flag[7] != 0)
9377             quantize_info->dither_method=(DitherMethod)
9378               argument_list[7].integer_reference;
9379           if (attribute_flag[5] && argument_list[5].integer_reference)
9380             (void) QuantizeImages(quantize_info,image,exception);
9381           else
9382             if ((image->storage_class == DirectClass) ||
9383                (image->colors > quantize_info->number_colors) ||
9384                (quantize_info->colorspace == GRAYColorspace))
9385              (void) QuantizeImage(quantize_info,image,exception);
9386            else
9387              CompressImageColormap(image,exception);
9388           quantize_info=DestroyQuantizeInfo(quantize_info);
9389           break;
9390         }
9391         case 49:  /* Raise */
9392         {
9393           if (attribute_flag[0] != 0)
9394             flags=ParsePageGeometry(image,argument_list[0].string_reference,
9395               &geometry,exception);
9396           if (attribute_flag[1] != 0)
9397             geometry.width=argument_list[1].integer_reference;
9398           if (attribute_flag[2] != 0)
9399             geometry.height=argument_list[2].integer_reference;
9400           if (attribute_flag[3] == 0)
9401             argument_list[3].integer_reference=1;
9402           (void) RaiseImage(image,&geometry,
9403             argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9404             exception);
9405           break;
9406         }
9407         case 50:  /* Segment */
9408         {
9409           ColorspaceType
9410             colorspace;
9411 
9412           double
9413             cluster_threshold,
9414             smoothing_threshold;
9415 
9416           MagickBooleanType
9417             verbose;
9418 
9419           cluster_threshold=1.0;
9420           smoothing_threshold=1.5;
9421           colorspace=sRGBColorspace;
9422           verbose=MagickFalse;
9423           if (attribute_flag[0] != 0)
9424             {
9425               flags=ParseGeometry(argument_list[0].string_reference,
9426                 &geometry_info);
9427               cluster_threshold=geometry_info.rho;
9428               if (flags & SigmaValue)
9429                 smoothing_threshold=geometry_info.sigma;
9430             }
9431           if (attribute_flag[1] != 0)
9432             cluster_threshold=argument_list[1].real_reference;
9433           if (attribute_flag[2] != 0)
9434             smoothing_threshold=argument_list[2].real_reference;
9435           if (attribute_flag[3] != 0)
9436             colorspace=(ColorspaceType) argument_list[3].integer_reference;
9437           if (attribute_flag[4] != 0)
9438             verbose=argument_list[4].integer_reference != 0 ?
9439               MagickTrue : MagickFalse;
9440           (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9441             smoothing_threshold,exception);
9442           break;
9443         }
9444         case 51:  /* Signature */
9445         {
9446           (void) SignatureImage(image,exception);
9447           break;
9448         }
9449         case 52:  /* Solarize */
9450         {
9451           geometry_info.rho=QuantumRange/2.0;
9452           if (attribute_flag[0] != 0)
9453             flags=ParseGeometry(argument_list[0].string_reference,
9454               &geometry_info);
9455           if (attribute_flag[1] != 0)
9456             geometry_info.rho=StringToDoubleInterval(
9457               argument_list[1].string_reference,(double) QuantumRange+1.0);
9458           (void) SolarizeImage(image,geometry_info.rho,exception);
9459           break;
9460         }
9461         case 53:  /* Sync */
9462         {
9463           (void) SyncImage(image,exception);
9464           break;
9465         }
9466         case 54:  /* Texture */
9467         {
9468           if (attribute_flag[0] == 0)
9469             break;
9470           TextureImage(image,argument_list[0].image_reference,exception);
9471           break;
9472         }
9473         case 55:  /* Evalute */
9474         {
9475           MagickEvaluateOperator
9476             op;
9477 
9478           op=SetEvaluateOperator;
9479           if (attribute_flag[0] == MagickFalse)
9480             argument_list[0].real_reference=0.0;
9481           if (attribute_flag[1] != MagickFalse)
9482             op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9483           if (attribute_flag[2] != MagickFalse)
9484             channel=(ChannelType) argument_list[2].integer_reference;
9485           channel_mask=SetImageChannelMask(image,channel);
9486           (void) EvaluateImage(image,op,argument_list[0].real_reference,
9487             exception);
9488           (void) SetImageChannelMask(image,channel_mask);
9489           break;
9490         }
9491         case 56:  /* Transparent */
9492         {
9493           double
9494             opacity;
9495 
9496           MagickBooleanType
9497             invert;
9498 
9499           PixelInfo
9500             target;
9501 
9502           (void) QueryColorCompliance("none",AllCompliance,&target,
9503             exception);
9504           if (attribute_flag[0] != 0)
9505             (void) QueryColorCompliance(argument_list[0].string_reference,
9506               AllCompliance,&target,exception);
9507           opacity=TransparentAlpha;
9508           if (attribute_flag[1] != 0)
9509             opacity=StringToDoubleInterval(argument_list[1].string_reference,
9510               (double) QuantumRange+1.0);
9511           if (attribute_flag[2] != 0)
9512             image->fuzz=StringToDoubleInterval(
9513               argument_list[2].string_reference,(double) QuantumRange+1.0);
9514           if (attribute_flag[3] == 0)
9515             argument_list[3].integer_reference=0;
9516           invert=MagickFalse;
9517           if (attribute_flag[3] != 0)
9518             invert=(MagickBooleanType) argument_list[3].integer_reference;
9519           (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9520             invert,exception);
9521           break;
9522         }
9523         case 57:  /* Threshold */
9524         {
9525           double
9526             threshold;
9527 
9528           if (attribute_flag[0] == 0)
9529             argument_list[0].string_reference="50%";
9530           if (attribute_flag[1] != 0)
9531             channel=(ChannelType) argument_list[1].integer_reference;
9532           threshold=StringToDoubleInterval(argument_list[0].string_reference,
9533             (double) QuantumRange+1.0);
9534           channel_mask=SetImageChannelMask(image,channel);
9535           (void) BilevelImage(image,threshold,exception);
9536           (void) SetImageChannelMask(image,channel_mask);
9537           break;
9538         }
9539         case 58:  /* Charcoal */
9540         {
9541           if (attribute_flag[0] != 0)
9542             {
9543               flags=ParseGeometry(argument_list[0].string_reference,
9544                 &geometry_info);
9545               if ((flags & SigmaValue) == 0)
9546                 geometry_info.sigma=1.0;
9547             }
9548           if (attribute_flag[1] != 0)
9549             geometry_info.rho=argument_list[1].real_reference;
9550           if (attribute_flag[2] != 0)
9551             geometry_info.sigma=argument_list[2].real_reference;
9552           image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9553             exception);
9554           break;
9555         }
9556         case 59:  /* Trim */
9557         {
9558           if (attribute_flag[0] != 0)
9559             image->fuzz=StringToDoubleInterval(
9560               argument_list[0].string_reference,(double) QuantumRange+1.0);
9561           image=TrimImage(image,exception);
9562           break;
9563         }
9564         case 60:  /* Wave */
9565         {
9566           PixelInterpolateMethod
9567             method;
9568 
9569           if (attribute_flag[0] != 0)
9570             {
9571               flags=ParseGeometry(argument_list[0].string_reference,
9572                 &geometry_info);
9573               if ((flags & SigmaValue) == 0)
9574                 geometry_info.sigma=1.0;
9575             }
9576           if (attribute_flag[1] != 0)
9577             geometry_info.rho=argument_list[1].real_reference;
9578           if (attribute_flag[2] != 0)
9579             geometry_info.sigma=argument_list[2].real_reference;
9580           method=UndefinedInterpolatePixel;
9581           if (attribute_flag[3] != 0)
9582             method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9583           image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9584             method,exception);
9585           break;
9586         }
9587         case 61:  /* Separate */
9588         {
9589           if (attribute_flag[0] != 0)
9590             channel=(ChannelType) argument_list[0].integer_reference;
9591           image=SeparateImage(image,channel,exception);
9592           break;
9593         }
9594         case 63:  /* Stereo */
9595         {
9596           if (attribute_flag[0] == 0)
9597             {
9598               ThrowPerlException(exception,OptionError,"StereoImageRequired",
9599                 PackageName);
9600               goto PerlException;
9601             }
9602           if (attribute_flag[1] != 0)
9603             geometry.x=argument_list[1].integer_reference;
9604           if (attribute_flag[2] != 0)
9605             geometry.y=argument_list[2].integer_reference;
9606           image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9607             geometry.x,geometry.y,exception);
9608           break;
9609         }
9610         case 64:  /* Stegano */
9611         {
9612           if (attribute_flag[0] == 0)
9613             {
9614               ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9615                 PackageName);
9616               goto PerlException;
9617             }
9618           if (attribute_flag[1] == 0)
9619             argument_list[1].integer_reference=0;
9620           image->offset=argument_list[1].integer_reference;
9621           image=SteganoImage(image,argument_list[0].image_reference,exception);
9622           break;
9623         }
9624         case 65:  /* Deconstruct */
9625         {
9626           image=CompareImagesLayers(image,CompareAnyLayer,exception);
9627           break;
9628         }
9629         case 66:  /* GaussianBlur */
9630         {
9631           if (attribute_flag[0] != 0)
9632             {
9633               flags=ParseGeometry(argument_list[0].string_reference,
9634                 &geometry_info);
9635               if ((flags & SigmaValue) == 0)
9636                 geometry_info.sigma=1.0;
9637             }
9638           if (attribute_flag[1] != 0)
9639             geometry_info.rho=argument_list[1].real_reference;
9640           if (attribute_flag[2] != 0)
9641             geometry_info.sigma=argument_list[2].real_reference;
9642           if (attribute_flag[3] != 0)
9643             channel=(ChannelType) argument_list[3].integer_reference;
9644           channel_mask=SetImageChannelMask(image,channel);
9645           image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9646             exception);
9647           if (image != (Image *) NULL)
9648             (void) SetImageChannelMask(image,channel_mask);
9649           break;
9650         }
9651         case 67:  /* Convolve */
9652         {
9653           KernelInfo
9654             *kernel;
9655 
9656           kernel=(KernelInfo *) NULL;
9657           if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9658             break;
9659           if (attribute_flag[0] != 0)
9660             {
9661               AV
9662                 *av;
9663 
9664               size_t
9665                 order;
9666 
9667               kernel=AcquireKernelInfo((const char *) NULL,exception);
9668               if (kernel == (KernelInfo *) NULL)
9669                 break;
9670               av=(AV *) argument_list[0].array_reference;
9671               order=(size_t) sqrt(av_len(av)+1);
9672               kernel->width=order;
9673               kernel->height=order;
9674               kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9675                 order*sizeof(*kernel->values));
9676               if (kernel->values == (MagickRealType *) NULL)
9677                 {
9678                   kernel=DestroyKernelInfo(kernel);
9679                   ThrowPerlException(exception,ResourceLimitFatalError,
9680                     "MemoryAllocationFailed",PackageName);
9681                   goto PerlException;
9682                 }
9683               for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9684                 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9685               for ( ; j < (ssize_t) (order*order); j++)
9686                 kernel->values[j]=0.0;
9687             }
9688           if (attribute_flag[1] != 0)
9689             channel=(ChannelType) argument_list[1].integer_reference;
9690           if (attribute_flag[2] != 0)
9691             SetImageArtifact(image,"convolve:bias",
9692               argument_list[2].string_reference);
9693           if (attribute_flag[3] != 0)
9694             {
9695               kernel=AcquireKernelInfo(argument_list[3].string_reference,
9696                 exception);
9697               if (kernel == (KernelInfo *) NULL)
9698                 break;
9699             }
9700           channel_mask=SetImageChannelMask(image,channel);
9701           image=ConvolveImage(image,kernel,exception);
9702           if (image != (Image *) NULL)
9703             (void) SetImageChannelMask(image,channel_mask);
9704           kernel=DestroyKernelInfo(kernel);
9705           break;
9706         }
9707         case 68:  /* Profile */
9708         {
9709           const char
9710             *name;
9711 
9712           Image
9713             *profile_image;
9714 
9715           ImageInfo
9716             *profile_info;
9717 
9718           StringInfo
9719             *profile;
9720 
9721           name="*";
9722           if (attribute_flag[0] != 0)
9723             name=argument_list[0].string_reference;
9724           if (attribute_flag[2] != 0)
9725             image->rendering_intent=(RenderingIntent)
9726               argument_list[2].integer_reference;
9727           if (attribute_flag[3] != 0)
9728             image->black_point_compensation=
9729               argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9730           if (attribute_flag[1] != 0)
9731             {
9732               if (argument_list[1].length == 0)
9733                 {
9734                   /*
9735                     Remove a profile from the image.
9736                   */
9737                   (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9738                     exception);
9739                   break;
9740                 }
9741               /*
9742                 Associate user supplied profile with the image.
9743               */
9744               profile=AcquireStringInfo(argument_list[1].length);
9745               SetStringInfoDatum(profile,(const unsigned char *)
9746                 argument_list[1].string_reference);
9747               (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9748                 (size_t) GetStringInfoLength(profile),exception);
9749               profile=DestroyStringInfo(profile);
9750               break;
9751             }
9752           /*
9753             Associate a profile with the image.
9754           */
9755           profile_info=CloneImageInfo(info ? info->image_info :
9756             (ImageInfo *) NULL);
9757           profile_image=ReadImages(profile_info,name,exception);
9758           if (profile_image == (Image *) NULL)
9759             break;
9760           ResetImageProfileIterator(profile_image);
9761           name=GetNextImageProfile(profile_image);
9762           while (name != (const char *) NULL)
9763           {
9764             const StringInfo
9765               *profile;
9766 
9767             profile=GetImageProfile(profile_image,name);
9768             if (profile != (const StringInfo *) NULL)
9769               (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9770                 (size_t) GetStringInfoLength(profile),exception);
9771             name=GetNextImageProfile(profile_image);
9772           }
9773           profile_image=DestroyImage(profile_image);
9774           profile_info=DestroyImageInfo(profile_info);
9775           break;
9776         }
9777         case 69:  /* UnsharpMask */
9778         {
9779           if (attribute_flag[0] != 0)
9780             {
9781               flags=ParseGeometry(argument_list[0].string_reference,
9782                 &geometry_info);
9783               if ((flags & SigmaValue) == 0)
9784                 geometry_info.sigma=1.0;
9785               if ((flags & XiValue) == 0)
9786                 geometry_info.xi=1.0;
9787               if ((flags & PsiValue) == 0)
9788                 geometry_info.psi=0.5;
9789             }
9790           if (attribute_flag[1] != 0)
9791             geometry_info.rho=argument_list[1].real_reference;
9792           if (attribute_flag[2] != 0)
9793             geometry_info.sigma=argument_list[2].real_reference;
9794           if (attribute_flag[3] != 0)
9795             geometry_info.xi=argument_list[3].real_reference;
9796           if (attribute_flag[4] != 0)
9797             geometry_info.psi=argument_list[4].real_reference;
9798           if (attribute_flag[5] != 0)
9799             channel=(ChannelType) argument_list[5].integer_reference;
9800           channel_mask=SetImageChannelMask(image,channel);
9801           image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9802             geometry_info.xi,geometry_info.psi,exception);
9803           if (image != (Image *) NULL)
9804             (void) SetImageChannelMask(image,channel_mask);
9805           break;
9806         }
9807         case 70:  /* MotionBlur */
9808         {
9809           if (attribute_flag[0] != 0)
9810             {
9811               flags=ParseGeometry(argument_list[0].string_reference,
9812                 &geometry_info);
9813               if ((flags & SigmaValue) == 0)
9814                 geometry_info.sigma=1.0;
9815               if ((flags & XiValue) == 0)
9816                 geometry_info.xi=1.0;
9817             }
9818           if (attribute_flag[1] != 0)
9819             geometry_info.rho=argument_list[1].real_reference;
9820           if (attribute_flag[2] != 0)
9821             geometry_info.sigma=argument_list[2].real_reference;
9822           if (attribute_flag[3] != 0)
9823             geometry_info.xi=argument_list[3].real_reference;
9824           if (attribute_flag[4] != 0)
9825             channel=(ChannelType) argument_list[4].integer_reference;
9826           channel_mask=SetImageChannelMask(image,channel);
9827           image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9828             geometry_info.xi,exception);
9829           if (image != (Image *) NULL)
9830             (void) SetImageChannelMask(image,channel_mask);
9831           break;
9832         }
9833         case 71:  /* OrderedDither */
9834         {
9835           if (attribute_flag[0] == 0)
9836             argument_list[0].string_reference="o8x8";
9837           if (attribute_flag[1] != 0)
9838             channel=(ChannelType) argument_list[1].integer_reference;
9839           channel_mask=SetImageChannelMask(image,channel);
9840           (void) OrderedDitherImage(image,argument_list[0].string_reference,
9841             exception);
9842           (void) SetImageChannelMask(image,channel_mask);
9843           break;
9844         }
9845         case 72:  /* Shave */
9846         {
9847           if (attribute_flag[0] != 0)
9848             flags=ParsePageGeometry(image,argument_list[0].string_reference,
9849               &geometry,exception);
9850           if (attribute_flag[1] != 0)
9851             geometry.width=argument_list[1].integer_reference;
9852           if (attribute_flag[2] != 0)
9853             geometry.height=argument_list[2].integer_reference;
9854           image=ShaveImage(image,&geometry,exception);
9855           break;
9856         }
9857         case 73:  /* Level */
9858         {
9859           double
9860             black_point,
9861             gamma,
9862             white_point;
9863 
9864           black_point=0.0;
9865           white_point=(double) image->columns*image->rows;
9866           gamma=1.0;
9867           if (attribute_flag[0] != 0)
9868             {
9869               flags=ParseGeometry(argument_list[0].string_reference,
9870                 &geometry_info);
9871               black_point=geometry_info.rho;
9872               if ((flags & SigmaValue) != 0)
9873                 white_point=geometry_info.sigma;
9874               if ((flags & XiValue) != 0)
9875                 gamma=geometry_info.xi;
9876               if ((flags & PercentValue) != 0)
9877                 {
9878                   black_point*=(double) (QuantumRange/100.0);
9879                   white_point*=(double) (QuantumRange/100.0);
9880                 }
9881               if ((flags & SigmaValue) == 0)
9882                 white_point=(double) QuantumRange-black_point;
9883             }
9884           if (attribute_flag[1] != 0)
9885             black_point=argument_list[1].real_reference;
9886           if (attribute_flag[2] != 0)
9887             white_point=argument_list[2].real_reference;
9888           if (attribute_flag[3] != 0)
9889             gamma=argument_list[3].real_reference;
9890           if (attribute_flag[4] != 0)
9891             channel=(ChannelType) argument_list[4].integer_reference;
9892           if (attribute_flag[5] != 0)
9893             {
9894               argument_list[0].real_reference=argument_list[5].real_reference;
9895               attribute_flag[0]=attribute_flag[5];
9896             }
9897           channel_mask=SetImageChannelMask(image,channel);
9898           (void) LevelImage(image,black_point,white_point,gamma,exception);
9899           (void) SetImageChannelMask(image,channel_mask);
9900           break;
9901         }
9902         case 74:  /* Clip */
9903         {
9904           if (attribute_flag[0] == 0)
9905             argument_list[0].string_reference="#1";
9906           if (attribute_flag[1] == 0)
9907             argument_list[1].integer_reference=MagickTrue;
9908           (void) ClipImagePath(image,argument_list[0].string_reference,
9909             argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9910             exception);
9911           break;
9912         }
9913         case 75:  /* AffineTransform */
9914         {
9915           DrawInfo
9916             *draw_info;
9917 
9918           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9919             (DrawInfo *) NULL);
9920           if (attribute_flag[0] != 0)
9921             {
9922               AV
9923                 *av;
9924 
9925               av=(AV *) argument_list[0].array_reference;
9926               if ((av_len(av) != 3) && (av_len(av) != 5))
9927                 {
9928                   ThrowPerlException(exception,OptionError,
9929                     "affine matrix must have 4 or 6 elements",PackageName);
9930                   goto PerlException;
9931                 }
9932               draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9933               draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9934               draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9935               draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9936               if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9937                   draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9938                 {
9939                   ThrowPerlException(exception,OptionError,
9940                     "affine matrix is singular",PackageName);
9941                    goto PerlException;
9942                 }
9943               if (av_len(av) == 5)
9944                 {
9945                   draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9946                   draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9947                 }
9948             }
9949           for (j=1; j < 6; j++)
9950           {
9951             if (attribute_flag[j] == 0)
9952               continue;
9953             value=argument_list[j].string_reference;
9954             angle=argument_list[j].real_reference;
9955             current=draw_info->affine;
9956             GetAffineMatrix(&affine);
9957             switch (j)
9958             {
9959               case 1:
9960               {
9961                 /*
9962                   Translate.
9963                 */
9964                 flags=ParseGeometry(value,&geometry_info);
9965                 affine.tx=geometry_info.xi;
9966                 affine.ty=geometry_info.psi;
9967                 if ((flags & PsiValue) == 0)
9968                   affine.ty=affine.tx;
9969                 break;
9970               }
9971               case 2:
9972               {
9973                 /*
9974                   Scale.
9975                 */
9976                 flags=ParseGeometry(value,&geometry_info);
9977                 affine.sx=geometry_info.rho;
9978                 affine.sy=geometry_info.sigma;
9979                 if ((flags & SigmaValue) == 0)
9980                   affine.sy=affine.sx;
9981                 break;
9982               }
9983               case 3:
9984               {
9985                 /*
9986                   Rotate.
9987                 */
9988                 if (angle == 0.0)
9989                   break;
9990                 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9991                 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9992                 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9993                 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9994                 break;
9995               }
9996               case 4:
9997               {
9998                 /*
9999                   SkewX.
10000                 */
10001                 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
10002                 break;
10003               }
10004               case 5:
10005               {
10006                 /*
10007                   SkewY.
10008                 */
10009                 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
10010                 break;
10011               }
10012             }
10013             draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
10014             draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
10015             draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
10016             draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
10017             draw_info->affine.tx=
10018               current.sx*affine.tx+current.ry*affine.ty+current.tx;
10019             draw_info->affine.ty=
10020               current.rx*affine.tx+current.sy*affine.ty+current.ty;
10021           }
10022           if (attribute_flag[6] != 0)
10023             image->interpolate=(PixelInterpolateMethod)
10024               argument_list[6].integer_reference;
10025           if (attribute_flag[7] != 0)
10026             QueryColorCompliance(argument_list[7].string_reference,
10027               AllCompliance,&image->background_color,exception);
10028           image=AffineTransformImage(image,&draw_info->affine,exception);
10029           draw_info=DestroyDrawInfo(draw_info);
10030           break;
10031         }
10032         case 76:  /* Difference */
10033         {
10034           if (attribute_flag[0] == 0)
10035             {
10036               ThrowPerlException(exception,OptionError,
10037                 "ReferenceImageRequired",PackageName);
10038               goto PerlException;
10039             }
10040           if (attribute_flag[1] != 0)
10041             image->fuzz=StringToDoubleInterval(
10042               argument_list[1].string_reference,(double) QuantumRange+1.0);
10043           (void) SetImageColorMetric(image,argument_list[0].image_reference,
10044             exception);
10045           break;
10046         }
10047         case 77:  /* AdaptiveThreshold */
10048         {
10049           if (attribute_flag[0] != 0)
10050             {
10051               flags=ParseGeometry(argument_list[0].string_reference,
10052                 &geometry_info);
10053               if ((flags & PercentValue) != 0)
10054                 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10055             }
10056           if (attribute_flag[1] != 0)
10057             geometry_info.rho=argument_list[1].integer_reference;
10058           if (attribute_flag[2] != 0)
10059             geometry_info.sigma=argument_list[2].integer_reference;
10060           if (attribute_flag[3] != 0)
10061             geometry_info.xi=argument_list[3].integer_reference;;
10062           image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
10063             (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
10064           break;
10065         }
10066         case 78:  /* Resample */
10067         {
10068           size_t
10069             height,
10070             width;
10071 
10072           if (attribute_flag[0] != 0)
10073             {
10074               flags=ParseGeometry(argument_list[0].string_reference,
10075                 &geometry_info);
10076               if ((flags & SigmaValue) == 0)
10077                 geometry_info.sigma=geometry_info.rho;
10078             }
10079           if (attribute_flag[1] != 0)
10080             geometry_info.rho=argument_list[1].real_reference;
10081           if (attribute_flag[2] != 0)
10082             geometry_info.sigma=argument_list[2].real_reference;
10083           if (attribute_flag[3] == 0)
10084             argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
10085           if (attribute_flag[4] == 0)
10086             SetImageArtifact(image,"filter:support",
10087               argument_list[4].string_reference);
10088           width=(size_t) (geometry_info.rho*image->columns/
10089             (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
10090           height=(size_t) (geometry_info.sigma*image->rows/
10091             (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
10092           image=ResizeImage(image,width,height,(FilterType)
10093             argument_list[3].integer_reference,exception);
10094           if (image != (Image *) NULL)
10095             {
10096               image->resolution.x=geometry_info.rho;
10097               image->resolution.y=geometry_info.sigma;
10098             }
10099           break;
10100         }
10101         case 79:  /* Describe */
10102         {
10103           if (attribute_flag[0] == 0)
10104             argument_list[0].file_reference=(FILE *) NULL;
10105           if (attribute_flag[1] != 0)
10106             (void) SetImageArtifact(image,"identify:features",
10107               argument_list[1].string_reference);
10108           (void) IdentifyImage(image,argument_list[0].file_reference,
10109             MagickTrue,exception);
10110           break;
10111         }
10112         case 80:  /* BlackThreshold */
10113         {
10114           if (attribute_flag[0] == 0)
10115             argument_list[0].string_reference="50%";
10116           if (attribute_flag[2] != 0)
10117             channel=(ChannelType) argument_list[2].integer_reference;
10118           channel_mask=SetImageChannelMask(image,channel);
10119           BlackThresholdImage(image,argument_list[0].string_reference,
10120             exception);
10121           (void) SetImageChannelMask(image,channel_mask);
10122           break;
10123         }
10124         case 81:  /* WhiteThreshold */
10125         {
10126           if (attribute_flag[0] == 0)
10127             argument_list[0].string_reference="50%";
10128           if (attribute_flag[2] != 0)
10129             channel=(ChannelType) argument_list[2].integer_reference;
10130           channel_mask=SetImageChannelMask(image,channel);
10131           WhiteThresholdImage(image,argument_list[0].string_reference,
10132             exception);
10133           (void) SetImageChannelMask(image,channel_mask);
10134           break;
10135         }
10136         case 82:  /* RotationalBlur */
10137         {
10138           if (attribute_flag[0] != 0)
10139             {
10140               flags=ParseGeometry(argument_list[0].string_reference,
10141                 &geometry_info);
10142             }
10143           if (attribute_flag[1] != 0)
10144             geometry_info.rho=argument_list[1].real_reference;
10145           if (attribute_flag[2] != 0)
10146             channel=(ChannelType) argument_list[2].integer_reference;
10147           channel_mask=SetImageChannelMask(image,channel);
10148           image=RotationalBlurImage(image,geometry_info.rho,exception);
10149           if (image != (Image *) NULL)
10150             (void) SetImageChannelMask(image,channel_mask);
10151           break;
10152         }
10153         case 83:  /* Thumbnail */
10154         {
10155           if (attribute_flag[0] != 0)
10156             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10157               &geometry,exception);
10158           if (attribute_flag[1] != 0)
10159             geometry.width=argument_list[1].integer_reference;
10160           if (attribute_flag[2] != 0)
10161             geometry.height=argument_list[2].integer_reference;
10162           image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10163           break;
10164         }
10165         case 84:  /* Strip */
10166         {
10167           (void) StripImage(image,exception);
10168           break;
10169         }
10170         case 85:  /* Tint */
10171         {
10172           PixelInfo
10173             tint;
10174 
10175           GetPixelInfo(image,&tint);
10176           if (attribute_flag[0] != 0)
10177             (void) QueryColorCompliance(argument_list[0].string_reference,
10178               AllCompliance,&tint,exception);
10179           if (attribute_flag[1] == 0)
10180             argument_list[1].string_reference="100";
10181           image=TintImage(image,argument_list[1].string_reference,&tint,
10182             exception);
10183           break;
10184         }
10185         case 86:  /* Channel */
10186         {
10187           if (attribute_flag[0] != 0)
10188             channel=(ChannelType) argument_list[0].integer_reference;
10189           image=SeparateImage(image,channel,exception);
10190           break;
10191         }
10192         case 87:  /* Splice */
10193         {
10194           if (attribute_flag[7] != 0)
10195             image->gravity=(GravityType) argument_list[7].integer_reference;
10196           if (attribute_flag[0] != 0)
10197             flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10198               &geometry,exception);
10199           if (attribute_flag[1] != 0)
10200             geometry.width=argument_list[1].integer_reference;
10201           if (attribute_flag[2] != 0)
10202             geometry.height=argument_list[2].integer_reference;
10203           if (attribute_flag[3] != 0)
10204             geometry.x=argument_list[3].integer_reference;
10205           if (attribute_flag[4] != 0)
10206             geometry.y=argument_list[4].integer_reference;
10207           if (attribute_flag[5] != 0)
10208             image->fuzz=StringToDoubleInterval(
10209               argument_list[5].string_reference,(double) QuantumRange+1.0);
10210           if (attribute_flag[6] != 0)
10211             (void) QueryColorCompliance(argument_list[6].string_reference,
10212               AllCompliance,&image->background_color,exception);
10213           image=SpliceImage(image,&geometry,exception);
10214           break;
10215         }
10216         case 88:  /* Posterize */
10217         {
10218           if (attribute_flag[0] == 0)
10219             argument_list[0].integer_reference=3;
10220           if (attribute_flag[1] == 0)
10221             argument_list[1].integer_reference=0;
10222           (void) PosterizeImage(image,argument_list[0].integer_reference,
10223             argument_list[1].integer_reference ? RiemersmaDitherMethod :
10224             NoDitherMethod,exception);
10225           break;
10226         }
10227         case 89:  /* Shadow */
10228         {
10229           if (attribute_flag[0] != 0)
10230             {
10231               flags=ParseGeometry(argument_list[0].string_reference,
10232                 &geometry_info);
10233               if ((flags & SigmaValue) == 0)
10234                 geometry_info.sigma=1.0;
10235               if ((flags & XiValue) == 0)
10236                 geometry_info.xi=4.0;
10237               if ((flags & PsiValue) == 0)
10238                 geometry_info.psi=4.0;
10239             }
10240           if (attribute_flag[1] != 0)
10241             geometry_info.rho=argument_list[1].real_reference;
10242           if (attribute_flag[2] != 0)
10243             geometry_info.sigma=argument_list[2].real_reference;
10244           if (attribute_flag[3] != 0)
10245             geometry_info.xi=argument_list[3].integer_reference;
10246           if (attribute_flag[4] != 0)
10247             geometry_info.psi=argument_list[4].integer_reference;
10248           image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10249             (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10250             ceil(geometry_info.psi-0.5),exception);
10251           break;
10252         }
10253         case 90:  /* Identify */
10254         {
10255           if (attribute_flag[0] == 0)
10256             argument_list[0].file_reference=(FILE *) NULL;
10257           if (attribute_flag[1] != 0)
10258             (void) SetImageArtifact(image,"identify:features",
10259               argument_list[1].string_reference);
10260           if ((attribute_flag[2] != 0) &&
10261               (argument_list[2].integer_reference != 0))
10262             (void) SetImageArtifact(image,"identify:unique","true");
10263           (void) IdentifyImage(image,argument_list[0].file_reference,
10264             MagickTrue,exception);
10265           break;
10266         }
10267         case 91:  /* SepiaTone */
10268         {
10269           if (attribute_flag[0] == 0)
10270             argument_list[0].real_reference=80.0*QuantumRange/100.0;
10271           image=SepiaToneImage(image,argument_list[0].real_reference,
10272             exception);
10273           break;
10274         }
10275         case 92:  /* SigmoidalContrast */
10276         {
10277           MagickBooleanType
10278             sharpen;
10279 
10280           if (attribute_flag[0] != 0)
10281             {
10282               flags=ParseGeometry(argument_list[0].string_reference,
10283                 &geometry_info);
10284               if ((flags & SigmaValue) == 0)
10285                 geometry_info.sigma=QuantumRange/2.0;
10286               if ((flags & PercentValue) != 0)
10287                 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10288             }
10289           if (attribute_flag[1] != 0)
10290             geometry_info.rho=argument_list[1].real_reference;
10291           if (attribute_flag[2] != 0)
10292             geometry_info.sigma=argument_list[2].real_reference;
10293           if (attribute_flag[3] != 0)
10294             channel=(ChannelType) argument_list[3].integer_reference;
10295           sharpen=MagickTrue;
10296           if (attribute_flag[4] != 0)
10297             sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10298               MagickFalse;
10299           channel_mask=SetImageChannelMask(image,channel);
10300           (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10301             geometry_info.sigma,exception);
10302           (void) SetImageChannelMask(image,channel_mask);
10303           break;
10304         }
10305         case 93:  /* Extent */
10306         {
10307           if (attribute_flag[7] != 0)
10308             image->gravity=(GravityType) argument_list[7].integer_reference;
10309           if (attribute_flag[0] != 0)
10310             {
10311               int
10312                 flags;
10313 
10314               flags=ParseGravityGeometry(image,
10315                 argument_list[0].string_reference,&geometry,exception);
10316               (void) flags;
10317               if (geometry.width == 0)
10318                 geometry.width=image->columns;
10319               if (geometry.height == 0)
10320                 geometry.height=image->rows;
10321             }
10322           if (attribute_flag[1] != 0)
10323             geometry.width=argument_list[1].integer_reference;
10324           if (attribute_flag[2] != 0)
10325             geometry.height=argument_list[2].integer_reference;
10326           if (attribute_flag[3] != 0)
10327             geometry.x=argument_list[3].integer_reference;
10328           if (attribute_flag[4] != 0)
10329             geometry.y=argument_list[4].integer_reference;
10330           if (attribute_flag[5] != 0)
10331             image->fuzz=StringToDoubleInterval(
10332               argument_list[5].string_reference,(double) QuantumRange+1.0);
10333           if (attribute_flag[6] != 0)
10334             (void) QueryColorCompliance(argument_list[6].string_reference,
10335               AllCompliance,&image->background_color,exception);
10336           image=ExtentImage(image,&geometry,exception);
10337           break;
10338         }
10339         case 94:  /* Vignette */
10340         {
10341           if (attribute_flag[0] != 0)
10342             {
10343               flags=ParseGeometry(argument_list[0].string_reference,
10344                 &geometry_info);
10345               if ((flags & SigmaValue) == 0)
10346                 geometry_info.sigma=1.0;
10347               if ((flags & XiValue) == 0)
10348                 geometry_info.xi=0.1*image->columns;
10349               if ((flags & PsiValue) == 0)
10350                 geometry_info.psi=0.1*image->rows;
10351             }
10352           if (attribute_flag[1] != 0)
10353             geometry_info.rho=argument_list[1].real_reference;
10354           if (attribute_flag[2] != 0)
10355             geometry_info.sigma=argument_list[2].real_reference;
10356           if (attribute_flag[3] != 0)
10357             geometry_info.xi=argument_list[3].integer_reference;
10358           if (attribute_flag[4] != 0)
10359             geometry_info.psi=argument_list[4].integer_reference;
10360           if (attribute_flag[5] != 0)
10361             (void) QueryColorCompliance(argument_list[5].string_reference,
10362               AllCompliance,&image->background_color,exception);
10363           image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10364             (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10365             ceil(geometry_info.psi-0.5),exception);
10366           break;
10367         }
10368         case 95:  /* ContrastStretch */
10369         {
10370           double
10371             black_point,
10372             white_point;
10373 
10374           black_point=0.0;
10375           white_point=(double) image->columns*image->rows;
10376           if (attribute_flag[0] != 0)
10377             {
10378               flags=ParseGeometry(argument_list[0].string_reference,
10379                 &geometry_info);
10380               black_point=geometry_info.rho;
10381               white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10382                 black_point;
10383               if ((flags & PercentValue) != 0)
10384                 {
10385                   black_point*=(double) image->columns*image->rows/100.0;
10386                   white_point*=(double) image->columns*image->rows/100.0;
10387                 }
10388               white_point=(double) image->columns*image->rows-
10389                 white_point;
10390             }
10391           if (attribute_flag[1] != 0)
10392             black_point=argument_list[1].real_reference;
10393           if (attribute_flag[2] != 0)
10394             white_point=argument_list[2].real_reference;
10395           if (attribute_flag[4] != 0)
10396             channel=(ChannelType) argument_list[4].integer_reference;
10397           channel_mask=SetImageChannelMask(image,channel);
10398           (void) ContrastStretchImage(image,black_point,white_point,exception);
10399           (void) SetImageChannelMask(image,channel_mask);
10400           break;
10401         }
10402         case 96:  /* Sans0 */
10403         {
10404           break;
10405         }
10406         case 97:  /* Sans1 */
10407         {
10408           break;
10409         }
10410         case 98:  /* AdaptiveSharpen */
10411         {
10412           if (attribute_flag[0] != 0)
10413             {
10414               flags=ParseGeometry(argument_list[0].string_reference,
10415                 &geometry_info);
10416               if ((flags & SigmaValue) == 0)
10417                 geometry_info.sigma=1.0;
10418               if ((flags & XiValue) == 0)
10419                 geometry_info.xi=0.0;
10420             }
10421           if (attribute_flag[1] != 0)
10422             geometry_info.rho=argument_list[1].real_reference;
10423           if (attribute_flag[2] != 0)
10424             geometry_info.sigma=argument_list[2].real_reference;
10425           if (attribute_flag[3] != 0)
10426             geometry_info.xi=argument_list[3].real_reference;
10427           if (attribute_flag[4] != 0)
10428             channel=(ChannelType) argument_list[4].integer_reference;
10429           channel_mask=SetImageChannelMask(image,channel);
10430           image=AdaptiveSharpenImage(image,geometry_info.rho,
10431             geometry_info.sigma,exception);
10432           if (image != (Image *) NULL)
10433             (void) SetImageChannelMask(image,channel_mask);
10434           break;
10435         }
10436         case 99:  /* Transpose */
10437         {
10438           image=TransposeImage(image,exception);
10439           break;
10440         }
10441         case 100:  /* Tranverse */
10442         {
10443           image=TransverseImage(image,exception);
10444           break;
10445         }
10446         case 101:  /* AutoOrient */
10447         {
10448           image=AutoOrientImage(image,image->orientation,exception);
10449           break;
10450         }
10451         case 102:  /* AdaptiveBlur */
10452         {
10453           if (attribute_flag[0] != 0)
10454             {
10455               flags=ParseGeometry(argument_list[0].string_reference,
10456                 &geometry_info);
10457               if ((flags & SigmaValue) == 0)
10458                 geometry_info.sigma=1.0;
10459               if ((flags & XiValue) == 0)
10460                 geometry_info.xi=0.0;
10461             }
10462           if (attribute_flag[1] != 0)
10463             geometry_info.rho=argument_list[1].real_reference;
10464           if (attribute_flag[2] != 0)
10465             geometry_info.sigma=argument_list[2].real_reference;
10466           if (attribute_flag[3] != 0)
10467             channel=(ChannelType) argument_list[3].integer_reference;
10468           channel_mask=SetImageChannelMask(image,channel);
10469           image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10470             exception);
10471           if (image != (Image *) NULL)
10472             (void) SetImageChannelMask(image,channel_mask);
10473           break;
10474         }
10475         case 103:  /* Sketch */
10476         {
10477           if (attribute_flag[0] != 0)
10478             {
10479               flags=ParseGeometry(argument_list[0].string_reference,
10480                 &geometry_info);
10481               if ((flags & SigmaValue) == 0)
10482                 geometry_info.sigma=1.0;
10483               if ((flags & XiValue) == 0)
10484                 geometry_info.xi=1.0;
10485             }
10486           if (attribute_flag[1] != 0)
10487             geometry_info.rho=argument_list[1].real_reference;
10488           if (attribute_flag[2] != 0)
10489             geometry_info.sigma=argument_list[2].real_reference;
10490           if (attribute_flag[3] != 0)
10491             geometry_info.xi=argument_list[3].real_reference;
10492           image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10493             geometry_info.xi,exception);
10494           break;
10495         }
10496         case 104:  /* UniqueColors */
10497         {
10498           image=UniqueImageColors(image,exception);
10499           break;
10500         }
10501         case 105:  /* AdaptiveResize */
10502         {
10503           if (attribute_flag[0] != 0)
10504             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10505               &geometry,exception);
10506           if (attribute_flag[1] != 0)
10507             geometry.width=argument_list[1].integer_reference;
10508           if (attribute_flag[2] != 0)
10509             geometry.height=argument_list[2].integer_reference;
10510           if (attribute_flag[3] != 0)
10511             image->filter=(FilterType) argument_list[4].integer_reference;
10512           if (attribute_flag[4] != 0)
10513             SetImageArtifact(image,"filter:support",
10514               argument_list[4].string_reference);
10515           image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10516             exception);
10517           break;
10518         }
10519         case 106:  /* ClipMask */
10520         {
10521           Image
10522             *mask_image;
10523 
10524           if (attribute_flag[0] == 0)
10525             {
10526               ThrowPerlException(exception,OptionError,"MaskImageRequired",
10527                 PackageName);
10528               goto PerlException;
10529             }
10530           mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10531             exception);
10532           (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
10533           mask_image=DestroyImage(mask_image);
10534           break;
10535         }
10536         case 107:  /* LinearStretch */
10537         {
10538            double
10539              black_point,
10540              white_point;
10541 
10542            black_point=0.0;
10543            white_point=(double) image->columns*image->rows;
10544            if (attribute_flag[0] != 0)
10545              {
10546                flags=ParseGeometry(argument_list[0].string_reference,
10547                  &geometry_info);
10548                if ((flags & SigmaValue) != 0)
10549                   white_point=geometry_info.sigma;
10550                if ((flags & PercentValue) != 0)
10551                  {
10552                    black_point*=(double) image->columns*image->rows/100.0;
10553                    white_point*=(double) image->columns*image->rows/100.0;
10554                  }
10555                if ((flags & SigmaValue) == 0)
10556                  white_point=(double) image->columns*image->rows-black_point;
10557              }
10558           if (attribute_flag[1] != 0)
10559             black_point=argument_list[1].real_reference;
10560           if (attribute_flag[2] != 0)
10561             white_point=argument_list[2].real_reference;
10562           (void) LinearStretchImage(image,black_point,white_point,exception);
10563           break;
10564         }
10565         case 108:  /* ColorMatrix */
10566         {
10567           AV
10568             *av;
10569 
10570           double
10571             *color_matrix;
10572 
10573           KernelInfo
10574             *kernel_info;
10575 
10576           size_t
10577             order;
10578 
10579           if (attribute_flag[0] == 0)
10580             break;
10581           av=(AV *) argument_list[0].array_reference;
10582           order=(size_t) sqrt(av_len(av)+1);
10583           color_matrix=(double *) AcquireQuantumMemory(order,order*
10584             sizeof(*color_matrix));
10585           if (color_matrix == (double *) NULL)
10586             {
10587               ThrowPerlException(exception,ResourceLimitFatalError,
10588                 "MemoryAllocationFailed",PackageName);
10589               goto PerlException;
10590            }
10591           for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10592             color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10593           for ( ; j < (ssize_t) (order*order); j++)
10594             color_matrix[j]=0.0;
10595           kernel_info=AcquireKernelInfo((const char *) NULL,exception);
10596           if (kernel_info == (KernelInfo *) NULL)
10597             break;
10598           kernel_info->width=order;
10599           kernel_info->height=order;
10600           kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10601             order*sizeof(*kernel_info->values));
10602           if (kernel_info->values != (MagickRealType *) NULL)
10603             {
10604               for (i=0; i < (ssize_t) (order*order); i++)
10605                 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10606               image=ColorMatrixImage(image,kernel_info,exception);
10607             }
10608           kernel_info=DestroyKernelInfo(kernel_info);
10609           color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10610           break;
10611         }
10612         case 109:  /* Mask */
10613         {
10614           Image
10615             *mask_image;
10616 
10617           if (attribute_flag[0] == 0)
10618             {
10619               ThrowPerlException(exception,OptionError,"MaskImageRequired",
10620                 PackageName);
10621               goto PerlException;
10622             }
10623           mask_image=CloneImage(argument_list[0].image_reference,0,0,
10624             MagickTrue,exception);
10625           (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
10626           mask_image=DestroyImage(mask_image);
10627           break;
10628         }
10629         case 110:  /* Polaroid */
10630         {
10631           char
10632             *caption;
10633 
10634           DrawInfo
10635             *draw_info;
10636 
10637           double
10638             angle;
10639 
10640           PixelInterpolateMethod
10641             method;
10642 
10643           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10644             (DrawInfo *) NULL);
10645           caption=(char *) NULL;
10646           if (attribute_flag[0] != 0)
10647             caption=InterpretImageProperties(info ? info->image_info :
10648               (ImageInfo *) NULL,image,argument_list[0].string_reference,
10649               exception);
10650           angle=0.0;
10651           if (attribute_flag[1] != 0)
10652             angle=argument_list[1].real_reference;
10653           if (attribute_flag[2] != 0)
10654             (void) CloneString(&draw_info->font,
10655               argument_list[2].string_reference);
10656           if (attribute_flag[3] != 0)
10657             (void) QueryColorCompliance(argument_list[3].string_reference,
10658               AllCompliance,&draw_info->stroke,exception);
10659           if (attribute_flag[4] != 0)
10660             (void) QueryColorCompliance(argument_list[4].string_reference,
10661               AllCompliance,&draw_info->fill,exception);
10662           if (attribute_flag[5] != 0)
10663             draw_info->stroke_width=argument_list[5].real_reference;
10664           if (attribute_flag[6] != 0)
10665             draw_info->pointsize=argument_list[6].real_reference;
10666           if (attribute_flag[7] != 0)
10667             draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10668           if (attribute_flag[8] != 0)
10669             (void) QueryColorCompliance(argument_list[8].string_reference,
10670               AllCompliance,&image->background_color,exception);
10671           method=UndefinedInterpolatePixel;
10672           if (attribute_flag[9] != 0)
10673             method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10674           image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10675           draw_info=DestroyDrawInfo(draw_info);
10676           if (caption != (char *) NULL)
10677             caption=DestroyString(caption);
10678           break;
10679         }
10680         case 111:  /* FloodfillPaint */
10681         {
10682           DrawInfo
10683             *draw_info;
10684 
10685           MagickBooleanType
10686             invert;
10687 
10688           PixelInfo
10689             target;
10690 
10691           draw_info=CloneDrawInfo(info ? info->image_info :
10692             (ImageInfo *) NULL,(DrawInfo *) NULL);
10693           if (attribute_flag[0] != 0)
10694             flags=ParsePageGeometry(image,argument_list[0].string_reference,
10695               &geometry,exception);
10696           if (attribute_flag[1] != 0)
10697             geometry.x=argument_list[1].integer_reference;
10698           if (attribute_flag[2] != 0)
10699             geometry.y=argument_list[2].integer_reference;
10700           if (attribute_flag[3] != 0)
10701             (void) QueryColorCompliance(argument_list[3].string_reference,
10702               AllCompliance,&draw_info->fill,exception);
10703           (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10704             geometry.x,geometry.y,&target,exception);
10705           if (attribute_flag[4] != 0)
10706             QueryColorCompliance(argument_list[4].string_reference,
10707               AllCompliance,&target,exception);
10708           if (attribute_flag[5] != 0)
10709             image->fuzz=StringToDoubleInterval(
10710               argument_list[5].string_reference,(double) QuantumRange+1.0);
10711           if (attribute_flag[6] != 0)
10712             channel=(ChannelType) argument_list[6].integer_reference;
10713           invert=MagickFalse;
10714           if (attribute_flag[7] != 0)
10715             invert=(MagickBooleanType) argument_list[7].integer_reference;
10716           channel_mask=SetImageChannelMask(image,channel);
10717           (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10718             geometry.y,invert,exception);
10719           (void) SetImageChannelMask(image,channel_mask);
10720           draw_info=DestroyDrawInfo(draw_info);
10721           break;
10722         }
10723         case 112:  /* Distort */
10724         {
10725           AV
10726             *av;
10727 
10728           double
10729             *coordinates;
10730 
10731           DistortMethod
10732             method;
10733 
10734           size_t
10735             number_coordinates;
10736 
10737           VirtualPixelMethod
10738             virtual_pixel;
10739 
10740           if (attribute_flag[0] == 0)
10741             break;
10742           method=UndefinedDistortion;
10743           if (attribute_flag[1] != 0)
10744             method=(DistortMethod) argument_list[1].integer_reference;
10745           av=(AV *) argument_list[0].array_reference;
10746           number_coordinates=(size_t) av_len(av)+1;
10747           coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10748             sizeof(*coordinates));
10749           if (coordinates == (double *) NULL)
10750             {
10751               ThrowPerlException(exception,ResourceLimitFatalError,
10752                 "MemoryAllocationFailed",PackageName);
10753               goto PerlException;
10754             }
10755           for (j=0; j < (ssize_t) number_coordinates; j++)
10756             coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10757           virtual_pixel=UndefinedVirtualPixelMethod;
10758           if (attribute_flag[2] != 0)
10759             virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10760               argument_list[2].integer_reference,exception);
10761           image=DistortImage(image,method,number_coordinates,coordinates,
10762             argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10763             exception);
10764           if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10765             virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10766               exception);
10767           coordinates=(double *) RelinquishMagickMemory(coordinates);
10768           break;
10769         }
10770         case 113:  /* Clut */
10771         {
10772           PixelInterpolateMethod
10773             method;
10774 
10775           if (attribute_flag[0] == 0)
10776             {
10777               ThrowPerlException(exception,OptionError,"ClutImageRequired",
10778                 PackageName);
10779               goto PerlException;
10780             }
10781           method=UndefinedInterpolatePixel;
10782           if (attribute_flag[1] != 0)
10783             method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10784           if (attribute_flag[2] != 0)
10785             channel=(ChannelType) argument_list[2].integer_reference;
10786           channel_mask=SetImageChannelMask(image,channel);
10787           (void) ClutImage(image,argument_list[0].image_reference,method,
10788             exception);
10789           (void) SetImageChannelMask(image,channel_mask);
10790           break;
10791         }
10792         case 114:  /* LiquidRescale */
10793         {
10794           if (attribute_flag[0] != 0)
10795             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10796               &geometry,exception);
10797           if (attribute_flag[1] != 0)
10798             geometry.width=argument_list[1].integer_reference;
10799           if (attribute_flag[2] != 0)
10800             geometry.height=argument_list[2].integer_reference;
10801           if (attribute_flag[3] == 0)
10802             argument_list[3].real_reference=1.0;
10803           if (attribute_flag[4] == 0)
10804             argument_list[4].real_reference=0.0;
10805           image=LiquidRescaleImage(image,geometry.width,geometry.height,
10806             argument_list[3].real_reference,argument_list[4].real_reference,
10807             exception);
10808           break;
10809         }
10810         case 115:  /* EncipherImage */
10811         {
10812           (void) EncipherImage(image,argument_list[0].string_reference,
10813             exception);
10814           break;
10815         }
10816         case 116:  /* DecipherImage */
10817         {
10818           (void) DecipherImage(image,argument_list[0].string_reference,
10819             exception);
10820           break;
10821         }
10822         case 117:  /* Deskew */
10823         {
10824           geometry_info.rho=QuantumRange/2.0;
10825           if (attribute_flag[0] != 0)
10826             flags=ParseGeometry(argument_list[0].string_reference,
10827               &geometry_info);
10828           if (attribute_flag[1] != 0)
10829             geometry_info.rho=StringToDoubleInterval(
10830               argument_list[1].string_reference,(double) QuantumRange+1.0);
10831           image=DeskewImage(image,geometry_info.rho,exception);
10832           break;
10833         }
10834         case 118:  /* Remap */
10835         {
10836           QuantizeInfo
10837             *quantize_info;
10838 
10839           if (attribute_flag[0] == 0)
10840             {
10841               ThrowPerlException(exception,OptionError,"RemapImageRequired",
10842                 PackageName);
10843               goto PerlException;
10844             }
10845           quantize_info=AcquireQuantizeInfo(info->image_info);
10846           if (attribute_flag[1] != 0)
10847             quantize_info->dither_method=(DitherMethod)
10848               argument_list[1].integer_reference;
10849           (void) RemapImages(quantize_info,image,
10850             argument_list[0].image_reference,exception);
10851           quantize_info=DestroyQuantizeInfo(quantize_info);
10852           break;
10853         }
10854         case 119:  /* SparseColor */
10855         {
10856           AV
10857             *av;
10858 
10859           double
10860             *coordinates;
10861 
10862           SparseColorMethod
10863             method;
10864 
10865           size_t
10866             number_coordinates;
10867 
10868           VirtualPixelMethod
10869             virtual_pixel;
10870 
10871           if (attribute_flag[0] == 0)
10872             break;
10873           method=UndefinedColorInterpolate;
10874           if (attribute_flag[1] != 0)
10875             method=(SparseColorMethod) argument_list[1].integer_reference;
10876           av=(AV *) argument_list[0].array_reference;
10877           number_coordinates=(size_t) av_len(av)+1;
10878           coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10879             sizeof(*coordinates));
10880           if (coordinates == (double *) NULL)
10881             {
10882               ThrowPerlException(exception,ResourceLimitFatalError,
10883                 "MemoryAllocationFailed",PackageName);
10884               goto PerlException;
10885             }
10886           for (j=0; j < (ssize_t) number_coordinates; j++)
10887             coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10888           virtual_pixel=UndefinedVirtualPixelMethod;
10889           if (attribute_flag[2] != 0)
10890             virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10891               argument_list[2].integer_reference,exception);
10892           if (attribute_flag[3] != 0)
10893             channel=(ChannelType) argument_list[3].integer_reference;
10894           channel_mask=SetImageChannelMask(image,channel);
10895           image=SparseColorImage(image,method,number_coordinates,coordinates,
10896             exception);
10897           if (image != (Image *) NULL)
10898             (void) SetImageChannelMask(image,channel_mask);
10899           if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10900             virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10901               exception);
10902           coordinates=(double *) RelinquishMagickMemory(coordinates);
10903           break;
10904         }
10905         case 120:  /* Function */
10906         {
10907           AV
10908             *av;
10909 
10910           double
10911             *parameters;
10912 
10913           MagickFunction
10914             function;
10915 
10916           size_t
10917             number_parameters;
10918 
10919           VirtualPixelMethod
10920             virtual_pixel;
10921 
10922           if (attribute_flag[0] == 0)
10923             break;
10924           function=UndefinedFunction;
10925           if (attribute_flag[1] != 0)
10926             function=(MagickFunction) argument_list[1].integer_reference;
10927           av=(AV *) argument_list[0].array_reference;
10928           number_parameters=(size_t) av_len(av)+1;
10929           parameters=(double *) AcquireQuantumMemory(number_parameters,
10930             sizeof(*parameters));
10931           if (parameters == (double *) NULL)
10932             {
10933               ThrowPerlException(exception,ResourceLimitFatalError,
10934                 "MemoryAllocationFailed",PackageName);
10935               goto PerlException;
10936             }
10937           for (j=0; j < (ssize_t) number_parameters; j++)
10938             parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10939           virtual_pixel=UndefinedVirtualPixelMethod;
10940           if (attribute_flag[2] != 0)
10941             virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10942               argument_list[2].integer_reference,exception);
10943           (void) FunctionImage(image,function,number_parameters,parameters,
10944             exception);
10945           if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10946             virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10947               exception);
10948           parameters=(double *) RelinquishMagickMemory(parameters);
10949           break;
10950         }
10951         case 121:  /* SelectiveBlur */
10952         {
10953           if (attribute_flag[0] != 0)
10954             {
10955               flags=ParseGeometry(argument_list[0].string_reference,
10956                 &geometry_info);
10957               if ((flags & SigmaValue) == 0)
10958                 geometry_info.sigma=1.0;
10959               if ((flags & PercentValue) != 0)
10960                 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10961             }
10962           if (attribute_flag[1] != 0)
10963             geometry_info.rho=argument_list[1].real_reference;
10964           if (attribute_flag[2] != 0)
10965             geometry_info.sigma=argument_list[2].real_reference;
10966           if (attribute_flag[3] != 0)
10967             geometry_info.xi=argument_list[3].integer_reference;;
10968           if (attribute_flag[5] != 0)
10969             channel=(ChannelType) argument_list[5].integer_reference;
10970           channel_mask=SetImageChannelMask(image,channel);
10971           image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10972             geometry_info.xi,exception);
10973           if (image != (Image *) NULL)
10974             (void) SetImageChannelMask(image,channel_mask);
10975           break;
10976         }
10977         case 122:  /* HaldClut */
10978         {
10979           if (attribute_flag[0] == 0)
10980             {
10981               ThrowPerlException(exception,OptionError,"ClutImageRequired",
10982                 PackageName);
10983               goto PerlException;
10984             }
10985           if (attribute_flag[1] != 0)
10986             channel=(ChannelType) argument_list[1].integer_reference;
10987           channel_mask=SetImageChannelMask(image,channel);
10988           (void) HaldClutImage(image,argument_list[0].image_reference,
10989             exception);
10990           (void) SetImageChannelMask(image,channel_mask);
10991           break;
10992         }
10993         case 123:  /* BlueShift */
10994         {
10995           if (attribute_flag[0] != 0)
10996             (void) ParseGeometry(argument_list[0].string_reference,
10997               &geometry_info);
10998           image=BlueShiftImage(image,geometry_info.rho,exception);
10999           break;
11000         }
11001         case 124:  /* ForwardFourierTransformImage */
11002         {
11003           image=ForwardFourierTransformImage(image,
11004             argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
11005             exception);
11006           break;
11007         }
11008         case 125:  /* InverseFourierTransformImage */
11009         {
11010           image=InverseFourierTransformImage(image,image->next,
11011             argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
11012             exception);
11013           break;
11014         }
11015         case 126:  /* ColorDecisionList */
11016         {
11017           if (attribute_flag[0] == 0)
11018             argument_list[0].string_reference=(char *) NULL;
11019           (void) ColorDecisionListImage(image,
11020             argument_list[0].string_reference,exception);
11021           break;
11022         }
11023         case 127:  /* AutoGamma */
11024         {
11025           if (attribute_flag[0] != 0)
11026             channel=(ChannelType) argument_list[0].integer_reference;
11027           channel_mask=SetImageChannelMask(image,channel);
11028           (void) AutoGammaImage(image,exception);
11029           (void) SetImageChannelMask(image,channel_mask);
11030           break;
11031         }
11032         case 128:  /* AutoLevel */
11033         {
11034           if (attribute_flag[0] != 0)
11035             channel=(ChannelType) argument_list[0].integer_reference;
11036           channel_mask=SetImageChannelMask(image,channel);
11037           (void) AutoLevelImage(image,exception);
11038           (void) SetImageChannelMask(image,channel_mask);
11039           break;
11040         }
11041         case 129:  /* LevelColors */
11042         {
11043           PixelInfo
11044             black_point,
11045             white_point;
11046 
11047           (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
11048             exception);
11049           (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
11050             exception);
11051           if (attribute_flag[1] != 0)
11052              (void) QueryColorCompliance(
11053                argument_list[1].string_reference,AllCompliance,&black_point,
11054                exception);
11055           if (attribute_flag[2] != 0)
11056              (void) QueryColorCompliance(
11057                argument_list[2].string_reference,AllCompliance,&white_point,
11058                exception);
11059           if (attribute_flag[3] != 0)
11060             channel=(ChannelType) argument_list[3].integer_reference;
11061           channel_mask=SetImageChannelMask(image,channel);
11062           (void) LevelImageColors(image,&black_point,&white_point,
11063             argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
11064             exception);
11065           (void) SetImageChannelMask(image,channel_mask);
11066           break;
11067         }
11068         case 130:  /* Clamp */
11069         {
11070           if (attribute_flag[0] != 0)
11071             channel=(ChannelType) argument_list[0].integer_reference;
11072           channel_mask=SetImageChannelMask(image,channel);
11073           (void) ClampImage(image,exception);
11074           (void) SetImageChannelMask(image,channel_mask);
11075           break;
11076         }
11077         case 131:  /* BrightnessContrast */
11078         {
11079           double
11080             brightness,
11081             contrast;
11082 
11083           brightness=0.0;
11084           contrast=0.0;
11085           if (attribute_flag[0] != 0)
11086             {
11087               flags=ParseGeometry(argument_list[0].string_reference,
11088                 &geometry_info);
11089               brightness=geometry_info.rho;
11090               if ((flags & SigmaValue) == 0)
11091                 contrast=geometry_info.sigma;
11092             }
11093           if (attribute_flag[1] != 0)
11094             brightness=argument_list[1].real_reference;
11095           if (attribute_flag[2] != 0)
11096             contrast=argument_list[2].real_reference;
11097           if (attribute_flag[4] != 0)
11098             channel=(ChannelType) argument_list[4].integer_reference;
11099           channel_mask=SetImageChannelMask(image,channel);
11100           (void) BrightnessContrastImage(image,brightness,contrast,exception);
11101           (void) SetImageChannelMask(image,channel_mask);
11102           break;
11103         }
11104         case 132:  /* Morphology */
11105         {
11106           KernelInfo
11107             *kernel;
11108 
11109           MorphologyMethod
11110             method;
11111 
11112           ssize_t
11113             iterations;
11114 
11115           if (attribute_flag[0] == 0)
11116             break;
11117           kernel=AcquireKernelInfo(argument_list[0].string_reference,exception);
11118           if (kernel == (KernelInfo *) NULL)
11119             break;
11120           if (attribute_flag[1] != 0)
11121             channel=(ChannelType) argument_list[1].integer_reference;
11122           method=UndefinedMorphology;
11123           if (attribute_flag[2] != 0)
11124             method=argument_list[2].integer_reference;
11125           iterations=1;
11126           if (attribute_flag[3] != 0)
11127             iterations=argument_list[3].integer_reference;
11128           channel_mask=SetImageChannelMask(image,channel);
11129           image=MorphologyImage(image,method,iterations,kernel,exception);
11130           if (image != (Image *) NULL)
11131             (void) SetImageChannelMask(image,channel_mask);
11132           kernel=DestroyKernelInfo(kernel);
11133           break;
11134         }
11135         case 133:  /* Mode */
11136         {
11137           if (attribute_flag[0] != 0)
11138             {
11139               flags=ParseGeometry(argument_list[0].string_reference,
11140                 &geometry_info);
11141               if ((flags & SigmaValue) == 0)
11142                 geometry_info.sigma=1.0;
11143             }
11144           if (attribute_flag[1] != 0)
11145             geometry_info.rho=argument_list[1].real_reference;
11146           if (attribute_flag[2] != 0)
11147             geometry_info.sigma=argument_list[2].real_reference;
11148           if (attribute_flag[3] != 0)
11149             channel=(ChannelType) argument_list[3].integer_reference;
11150           channel_mask=SetImageChannelMask(image,channel);
11151           image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11152             (size_t) geometry_info.sigma,exception);
11153           if (image != (Image *) NULL)
11154             (void) SetImageChannelMask(image,channel_mask);
11155           break;
11156         }
11157         case 134:  /* Statistic */
11158         {
11159           StatisticType
11160             statistic;
11161 
11162           statistic=UndefinedStatistic;
11163           if (attribute_flag[0] != 0)
11164             {
11165               flags=ParseGeometry(argument_list[0].string_reference,
11166                 &geometry_info);
11167               if ((flags & SigmaValue) == 0)
11168                 geometry_info.sigma=1.0;
11169             }
11170           if (attribute_flag[1] != 0)
11171             geometry_info.rho=argument_list[1].real_reference;
11172           if (attribute_flag[2] != 0)
11173             geometry_info.sigma=argument_list[2].real_reference;
11174           if (attribute_flag[3] != 0)
11175             channel=(ChannelType) argument_list[3].integer_reference;
11176           if (attribute_flag[4] != 0)
11177             statistic=(StatisticType) argument_list[4].integer_reference;
11178           channel_mask=SetImageChannelMask(image,channel);
11179           image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11180             (size_t) geometry_info.sigma,exception);
11181           if (image != (Image *) NULL)
11182             (void) SetImageChannelMask(image,channel_mask);
11183           break;
11184         }
11185         case 135:  /* Perceptible */
11186         {
11187           double
11188             epsilon;
11189 
11190           epsilon=MagickEpsilon;
11191           if (attribute_flag[0] != 0)
11192             epsilon=argument_list[0].real_reference;
11193           if (attribute_flag[1] != 0)
11194             channel=(ChannelType) argument_list[1].integer_reference;
11195           channel_mask=SetImageChannelMask(image,channel);
11196           (void) PerceptibleImage(image,epsilon,exception);
11197           (void) SetImageChannelMask(image,channel_mask);
11198           break;
11199         }
11200         case 136:  /* Poly */
11201         {
11202           AV
11203             *av;
11204 
11205           double
11206             *terms;
11207 
11208           size_t
11209             number_terms;
11210 
11211           if (attribute_flag[0] == 0)
11212             break;
11213           if (attribute_flag[1] != 0)
11214             channel=(ChannelType) argument_list[1].integer_reference;
11215           av=(AV *) argument_list[0].array_reference;
11216           number_terms=(size_t) av_len(av);
11217           terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11218           if (terms == (double *) NULL)
11219             {
11220               ThrowPerlException(exception,ResourceLimitFatalError,
11221                 "MemoryAllocationFailed",PackageName);
11222               goto PerlException;
11223             }
11224           for (j=0; j < av_len(av); j++)
11225             terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11226           image=PolynomialImage(image,number_terms >> 1,terms,exception);
11227           terms=(double *) RelinquishMagickMemory(terms);
11228           break;
11229         }
11230         case 137:  /* Grayscale */
11231         {
11232           PixelIntensityMethod
11233             method;
11234 
11235           method=UndefinedPixelIntensityMethod;
11236           if (attribute_flag[0] != 0)
11237             method=(PixelIntensityMethod) argument_list[0].integer_reference;
11238           (void) GrayscaleImage(image,method,exception);
11239           break;
11240         }
11241         case 138:  /* Canny */
11242         {
11243           if (attribute_flag[0] != 0)
11244             {
11245               flags=ParseGeometry(argument_list[0].string_reference,
11246                 &geometry_info);
11247               if ((flags & SigmaValue) == 0)
11248                 geometry_info.sigma=1.0;
11249               if ((flags & XiValue) == 0)
11250                 geometry_info.xi=0.10;
11251               if ((flags & PsiValue) == 0)
11252                 geometry_info.psi=0.30;
11253               if ((flags & PercentValue) != 0)
11254                 {
11255                   geometry_info.xi/=100.0;
11256                   geometry_info.psi/=100.0;
11257                 }
11258             }
11259           if (attribute_flag[1] != 0)
11260             geometry_info.rho=argument_list[1].real_reference;
11261           if (attribute_flag[2] != 0)
11262             geometry_info.sigma=argument_list[2].real_reference;
11263           if (attribute_flag[3] != 0)
11264             geometry_info.xi=argument_list[3].real_reference;
11265           if (attribute_flag[4] != 0)
11266             geometry_info.psi=argument_list[4].real_reference;
11267           if (attribute_flag[5] != 0)
11268             channel=(ChannelType) argument_list[5].integer_reference;
11269           channel_mask=SetImageChannelMask(image,channel);
11270           image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11271             geometry_info.xi,geometry_info.psi,exception);
11272           if (image != (Image *) NULL)
11273             (void) SetImageChannelMask(image,channel_mask);
11274           break;
11275         }
11276         case 139:  /* HoughLine */
11277         {
11278           if (attribute_flag[0] != 0)
11279             {
11280               flags=ParseGeometry(argument_list[0].string_reference,
11281                 &geometry_info);
11282               if ((flags & SigmaValue) == 0)
11283                 geometry_info.sigma=geometry_info.rho;
11284               if ((flags & XiValue) == 0)
11285                 geometry_info.xi=40;
11286             }
11287           if (attribute_flag[1] != 0)
11288             geometry_info.rho=(double) argument_list[1].integer_reference;
11289           if (attribute_flag[2] != 0)
11290             geometry_info.sigma=(double) argument_list[2].integer_reference;
11291           if (attribute_flag[3] != 0)
11292             geometry_info.xi=(double) argument_list[3].integer_reference;
11293           image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t)
11294             geometry_info.sigma,(size_t) geometry_info.xi,exception);
11295           break;
11296         }
11297         case 140:  /* MeanShift */
11298         {
11299           if (attribute_flag[0] != 0)
11300             {
11301               flags=ParseGeometry(argument_list[0].string_reference,
11302                 &geometry_info);
11303               if ((flags & SigmaValue) == 0)
11304                 geometry_info.sigma=geometry_info.rho;
11305               if ((flags & XiValue) == 0)
11306                 geometry_info.xi=0.10*QuantumRange;
11307               if ((flags & PercentValue) != 0)
11308                 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
11309             }
11310           if (attribute_flag[1] != 0)
11311             geometry_info.rho=(double) argument_list[1].integer_reference;
11312           if (attribute_flag[2] != 0)
11313             geometry_info.sigma=(double) argument_list[2].integer_reference;
11314           if (attribute_flag[3] != 0)
11315             geometry_info.xi=(double) argument_list[3].integer_reference;
11316           image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t)
11317             geometry_info.sigma,geometry_info.xi,exception);
11318           break;
11319         }
11320         case 141:  /* Kuwahara */
11321         {
11322           if (attribute_flag[0] != 0)
11323             {
11324               flags=ParseGeometry(argument_list[0].string_reference,
11325                 &geometry_info);
11326               if ((flags & SigmaValue) == 0)
11327                 geometry_info.sigma=geometry_info.rho-0.5;
11328             }
11329           if (attribute_flag[1] != 0)
11330             geometry_info.rho=argument_list[1].real_reference;
11331           if (attribute_flag[2] != 0)
11332             geometry_info.sigma=argument_list[2].real_reference;
11333           if (attribute_flag[3] != 0)
11334             channel=(ChannelType) argument_list[3].integer_reference;
11335           channel_mask=SetImageChannelMask(image,channel);
11336           image=KuwaharaImage(image,geometry_info.rho,geometry_info.sigma,
11337             exception);
11338           if (image != (Image *) NULL)
11339             (void) SetImageChannelMask(image,channel_mask);
11340           break;
11341         }
11342         case 142:  /* ConnectedComponents */
11343         {
11344           size_t
11345             connectivity;
11346 
11347           connectivity=4;
11348           if (attribute_flag[0] != 0)
11349             connectivity=argument_list[0].integer_reference;
11350           image=ConnectedComponentsImage(image,connectivity,
11351             (CCObjectInfo **) NULL,exception);
11352           break;
11353         }
11354         case 143:  /* Copy */
11355         {
11356           Image
11357             *source_image;
11358 
11359           OffsetInfo
11360             offset;
11361 
11362           RectangleInfo
11363             offset_geometry;
11364 
11365           source_image=image;
11366           if (attribute_flag[0] != 0)
11367             source_image=argument_list[0].image_reference;
11368           SetGeometry(source_image,&geometry);
11369           if (attribute_flag[1] != 0)
11370             flags=ParseGravityGeometry(source_image,
11371               argument_list[1].string_reference,&geometry,exception);
11372           if (attribute_flag[2] != 0)
11373             geometry.width=argument_list[2].integer_reference;
11374           if (attribute_flag[3] != 0)
11375             geometry.height=argument_list[3].integer_reference;
11376           if (attribute_flag[4] != 0)
11377             geometry.x=argument_list[4].integer_reference;
11378           if (attribute_flag[5] != 0)
11379             geometry.y=argument_list[5].integer_reference;
11380           if (attribute_flag[6] != 0)
11381             image->gravity=(GravityType) argument_list[6].integer_reference;
11382           SetGeometry(image,&offset_geometry);
11383           if (attribute_flag[7] != 0)
11384             flags=ParseGravityGeometry(image,argument_list[7].string_reference,
11385               &offset_geometry,exception);
11386           offset.x=offset_geometry.x;
11387           offset.y=offset_geometry.y;
11388           if (attribute_flag[8] != 0)
11389             offset.x=argument_list[8].integer_reference;
11390           if (attribute_flag[9] != 0)
11391             offset.y=argument_list[9].integer_reference;
11392           (void) CopyImagePixels(image,source_image,&geometry,&offset,
11393             exception);
11394           break;
11395         }
11396         case 144:  /* Color */
11397         {
11398           PixelInfo
11399             color;
11400 
11401           (void) QueryColorCompliance("none",AllCompliance,&color,exception);
11402           if (attribute_flag[0] != 0)
11403             (void) QueryColorCompliance(argument_list[0].string_reference,
11404               AllCompliance,&color,exception);
11405           (void) SetImageColor(image,&color,exception);
11406           break;
11407         }
11408         case 145:  /* WaveletDenoise */
11409         {
11410           if (attribute_flag[0] != 0)
11411             {
11412               flags=ParseGeometry(argument_list[0].string_reference,
11413                 &geometry_info);
11414               if ((flags & PercentValue) != 0)
11415                 {
11416                   geometry_info.rho=QuantumRange*geometry_info.rho/100.0;
11417                   geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
11418                 }
11419               if ((flags & SigmaValue) == 0)
11420                 geometry_info.sigma=0.0;
11421             }
11422           if (attribute_flag[1] != 0)
11423             geometry_info.rho=argument_list[1].real_reference;
11424           if (attribute_flag[2] != 0)
11425             geometry_info.sigma=argument_list[2].real_reference;
11426           if (attribute_flag[3] != 0)
11427             channel=(ChannelType) argument_list[3].integer_reference;
11428           channel_mask=SetImageChannelMask(image,channel);
11429           image=WaveletDenoiseImage(image,geometry_info.rho,geometry_info.sigma,
11430             exception);
11431           if (image != (Image *) NULL)
11432             (void) SetImageChannelMask(image,channel_mask);
11433           break;
11434         }
11435         case 146:  /* Colorspace */
11436         {
11437           ColorspaceType
11438             colorspace;
11439 
11440           colorspace=sRGBColorspace;
11441           if (attribute_flag[0] != 0)
11442             colorspace=(ColorspaceType) argument_list[0].integer_reference;
11443           (void) TransformImageColorspace(image,colorspace,exception);
11444           break;
11445         }
11446         case 147:  /* AutoThreshold */
11447         {
11448           AutoThresholdMethod
11449             method;
11450 
11451           method=UndefinedThresholdMethod;
11452           if (attribute_flag[0] != 0)
11453             method=(AutoThresholdMethod) argument_list[0].integer_reference;
11454           (void) AutoThresholdImage(image,method,exception);
11455           break;
11456         }
11457         case 148:  /* RangeThreshold */
11458         {
11459           if (attribute_flag[0] != 0)
11460             {
11461               flags=ParseGeometry(argument_list[0].string_reference,
11462                 &geometry_info);
11463               if ((flags & SigmaValue) == 0)
11464                 geometry_info.sigma=geometry_info.rho;
11465               if ((flags & XiValue) == 0)
11466                 geometry_info.xi=geometry_info.sigma;
11467               if ((flags & PsiValue) == 0)
11468                 geometry_info.psi=geometry_info.xi;
11469             }
11470           if (attribute_flag[1] != 0)
11471             geometry_info.rho=argument_list[1].real_reference;
11472           if (attribute_flag[2] != 0)
11473             geometry_info.sigma=argument_list[2].real_reference;
11474           if (attribute_flag[3] != 0)
11475             geometry_info.xi=argument_list[3].real_reference;
11476           if (attribute_flag[4] != 0)
11477             geometry_info.psi=argument_list[4].real_reference;
11478           if (attribute_flag[5] != 0)
11479             channel=(ChannelType) argument_list[5].integer_reference;
11480           channel_mask=SetImageChannelMask(image,channel);
11481           (void) RangeThresholdImage(image,geometry_info.rho,
11482             geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
11483           if (image != (Image *) NULL)
11484             (void) SetImageChannelMask(image,channel_mask);
11485           break;
11486         }
11487         case 149:  /* CLAHE */
11488         {
11489           if (attribute_flag[0] != 0)
11490             {
11491               flags=ParseGeometry(argument_list[0].string_reference,
11492                 &geometry_info);
11493               flags=ParseRegionGeometry(image,argument_list[0].string_reference,
11494                 &geometry,exception);
11495             }
11496           if (attribute_flag[1] != 0)
11497             geometry.width=argument_list[1].integer_reference;
11498           if (attribute_flag[2] != 0)
11499             geometry.height=argument_list[2].integer_reference;
11500           if (attribute_flag[3] != 0)
11501             geometry.x=argument_list[3].integer_reference;
11502           if (attribute_flag[4] != 0)
11503             geometry_info.psi=argument_list[4].real_reference;
11504           (void) CLAHEImage(image,geometry.width,geometry.height,geometry.x,
11505             geometry_info.psi,exception);
11506           break;
11507         }
11508         case 150:  /* Kmeans */
11509         {
11510           if (attribute_flag[0] != 0)
11511             {
11512               flags=ParseGeometry(argument_list[0].string_reference,
11513                 &geometry_info);
11514               if ((flags & SigmaValue) == 0)
11515                 geometry_info.sigma=100.0;
11516               if ((flags & XiValue) == 0)
11517                 geometry_info.xi=0.01;
11518             }
11519           if (attribute_flag[1] != 0)
11520             geometry_info.rho=argument_list[1].integer_reference;
11521           if (attribute_flag[2] != 0)
11522             geometry_info.sigma=argument_list[2].integer_reference;
11523           if (attribute_flag[3] != 0)
11524             geometry_info.xi=(ChannelType) argument_list[3].real_reference;
11525           (void) KmeansImage(image,geometry_info.rho,geometry_info.sigma,
11526             geometry_info.xi,exception);
11527           break;
11528         }
11529       }
11530       if (next != (Image *) NULL)
11531         (void) CatchImageException(next);
11532       if ((region_info.width*region_info.height) != 0)
11533         (void) SetImageRegionMask(image,WritePixelMask,
11534           (const RectangleInfo *) NULL,exception);
11535       if (image != (Image *) NULL)
11536         {
11537           number_images++;
11538           if (next && (next != image))
11539             {
11540               image->next=next->next;
11541               if (image->next != (Image *) NULL)
11542                 image->next->previous=image;
11543               DeleteImageFromRegistry(*pv,next);
11544             }
11545           sv_setiv(*pv,PTR2IV(image));
11546           next=image;
11547         }
11548       if (*pv)
11549         pv++;
11550     }
11551 
11552   PerlException:
11553     if (reference_vector)
11554       reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11555     InheritPerlException(exception,perl_exception);
11556     exception=DestroyExceptionInfo(exception);
11557     sv_setiv(perl_exception,(IV) number_images);
11558     SvPOK_on(perl_exception);
11559     ST(0)=sv_2mortal(perl_exception);
11560     XSRETURN(1);
11561   }
11562 
11563 #
11564 ###############################################################################
11565 #                                                                             #
11566 #                                                                             #
11567 #                                                                             #
11568 #   M o n t a g e                                                             #
11569 #                                                                             #
11570 #                                                                             #
11571 #                                                                             #
11572 ###############################################################################
11573 #
11574 #
11575 void
Montage(ref,...)11576 Montage(ref,...)
11577   Image::Magick ref=NO_INIT
11578   ALIAS:
11579     MontageImage  = 1
11580     montage       = 2
11581     montageimage  = 3
11582   PPCODE:
11583   {
11584     AV
11585       *av;
11586 
11587     char
11588       *attribute;
11589 
11590     ExceptionInfo
11591       *exception;
11592 
11593     HV
11594       *hv;
11595 
11596     Image
11597       *image,
11598       *next;
11599 
11600     PixelInfo
11601       transparent_color;
11602 
11603     MontageInfo
11604       *montage_info;
11605 
11606     register ssize_t
11607       i;
11608 
11609     ssize_t
11610       sp;
11611 
11612     struct PackageInfo
11613       *info;
11614 
11615     SV
11616       *av_reference,
11617       *perl_exception,
11618       *reference,
11619       *rv,
11620       *sv;
11621 
11622     PERL_UNUSED_VAR(ref);
11623     PERL_UNUSED_VAR(ix);
11624     exception=AcquireExceptionInfo();
11625     perl_exception=newSVpv("",0);
11626     sv=NULL;
11627     attribute=NULL;
11628     if (sv_isobject(ST(0)) == 0)
11629       {
11630         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11631           PackageName);
11632         goto PerlException;
11633       }
11634     reference=SvRV(ST(0));
11635     hv=SvSTASH(reference);
11636     av=newAV();
11637     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11638     SvREFCNT_dec(av);
11639     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11640     if (image == (Image *) NULL)
11641       {
11642         ThrowPerlException(exception,OptionError,"NoImagesDefined",
11643           PackageName);
11644         goto PerlException;
11645       }
11646     /*
11647       Get options.
11648     */
11649     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11650     montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11651     (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11652       exception);
11653     for (i=2; i < items; i+=2)
11654     {
11655       attribute=(char *) SvPV(ST(i-1),na);
11656       switch (*attribute)
11657       {
11658         case 'B':
11659         case 'b':
11660         {
11661           if (LocaleCompare(attribute,"background") == 0)
11662             {
11663               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11664                 &montage_info->background_color,exception);
11665               for (next=image; next; next=next->next)
11666                 next->background_color=montage_info->background_color;
11667               break;
11668             }
11669           if (LocaleCompare(attribute,"border") == 0)
11670             {
11671               montage_info->border_width=SvIV(ST(i));
11672               break;
11673             }
11674           if (LocaleCompare(attribute,"bordercolor") == 0)
11675             {
11676               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11677                 &montage_info->border_color,exception);
11678               for (next=image; next; next=next->next)
11679                 next->border_color=montage_info->border_color;
11680               break;
11681             }
11682           if (LocaleCompare(attribute,"borderwidth") == 0)
11683             {
11684               montage_info->border_width=SvIV(ST(i));
11685               break;
11686             }
11687           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11688             attribute);
11689           break;
11690         }
11691         case 'C':
11692         case 'c':
11693         {
11694           if (LocaleCompare(attribute,"compose") == 0)
11695             {
11696               sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11697                 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11698               if (sp < 0)
11699                 {
11700                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
11701                     SvPV(ST(i),na));
11702                   break;
11703                 }
11704               for (next=image; next; next=next->next)
11705                 next->compose=(CompositeOperator) sp;
11706               break;
11707             }
11708           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11709             attribute);
11710           break;
11711         }
11712         case 'F':
11713         case 'f':
11714         {
11715           if (LocaleCompare(attribute,"fill") == 0)
11716             {
11717               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11718                 &montage_info->fill,exception);
11719               break;
11720             }
11721           if (LocaleCompare(attribute,"font") == 0)
11722             {
11723               (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11724               break;
11725             }
11726           if (LocaleCompare(attribute,"frame") == 0)
11727             {
11728               char
11729                 *p;
11730 
11731               p=SvPV(ST(i),na);
11732               if (IsGeometry(p) == MagickFalse)
11733                 {
11734                   ThrowPerlException(exception,OptionError,"MissingGeometry",
11735                     p);
11736                   break;
11737                 }
11738               (void) CloneString(&montage_info->frame,p);
11739               if (*p == '\0')
11740                 montage_info->frame=(char *) NULL;
11741               break;
11742             }
11743           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11744             attribute);
11745           break;
11746         }
11747         case 'G':
11748         case 'g':
11749         {
11750           if (LocaleCompare(attribute,"geometry") == 0)
11751             {
11752               char
11753                 *p;
11754 
11755               p=SvPV(ST(i),na);
11756               if (IsGeometry(p) == MagickFalse)
11757                 {
11758                   ThrowPerlException(exception,OptionError,"MissingGeometry",
11759                     p);
11760                   break;
11761                 }
11762              (void) CloneString(&montage_info->geometry,p);
11763              if (*p == '\0')
11764                montage_info->geometry=(char *) NULL;
11765              break;
11766            }
11767          if (LocaleCompare(attribute,"gravity") == 0)
11768            {
11769              ssize_t
11770                in;
11771 
11772              in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11773                MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11774              if (in < 0)
11775                {
11776                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
11777                    SvPV(ST(i),na));
11778                  return;
11779                }
11780              montage_info->gravity=(GravityType) in;
11781              for (next=image; next; next=next->next)
11782                next->gravity=(GravityType) in;
11783              break;
11784            }
11785           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11786             attribute);
11787           break;
11788         }
11789         case 'L':
11790         case 'l':
11791         {
11792           if (LocaleCompare(attribute,"label") == 0)
11793             {
11794               for (next=image; next; next=next->next)
11795                 (void) SetImageProperty(next,"label",InterpretImageProperties(
11796                   info ? info->image_info : (ImageInfo *) NULL,next,
11797                   SvPV(ST(i),na),exception),exception);
11798               break;
11799             }
11800           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11801             attribute);
11802           break;
11803         }
11804         case 'M':
11805         case 'm':
11806         {
11807           if (LocaleCompare(attribute,"mattecolor") == 0)
11808             {
11809               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11810                 &montage_info->alpha_color,exception);
11811               for (next=image; next; next=next->next)
11812                 next->alpha_color=montage_info->alpha_color;
11813               break;
11814             }
11815           if (LocaleCompare(attribute,"mode") == 0)
11816             {
11817               ssize_t
11818                 in;
11819 
11820               in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11821                 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11822               switch (in)
11823               {
11824                 default:
11825                 {
11826                   ThrowPerlException(exception,OptionError,
11827                     "UnrecognizedModeType",SvPV(ST(i),na));
11828                   break;
11829                 }
11830                 case FrameMode:
11831                 {
11832                   (void) CloneString(&montage_info->frame,"15x15+3+3");
11833                   montage_info->shadow=MagickTrue;
11834                   break;
11835                 }
11836                 case UnframeMode:
11837                 {
11838                   montage_info->frame=(char *) NULL;
11839                   montage_info->shadow=MagickFalse;
11840                   montage_info->border_width=0;
11841                   break;
11842                 }
11843                 case ConcatenateMode:
11844                 {
11845                   montage_info->frame=(char *) NULL;
11846                   montage_info->shadow=MagickFalse;
11847                   (void) CloneString(&montage_info->geometry,"+0+0");
11848                   montage_info->border_width=0;
11849                 }
11850               }
11851               break;
11852             }
11853           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11854             attribute);
11855           break;
11856         }
11857         case 'P':
11858         case 'p':
11859         {
11860           if (LocaleCompare(attribute,"pointsize") == 0)
11861             {
11862               montage_info->pointsize=SvIV(ST(i));
11863               break;
11864             }
11865           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11866             attribute);
11867           break;
11868         }
11869         case 'S':
11870         case 's':
11871         {
11872           if (LocaleCompare(attribute,"shadow") == 0)
11873             {
11874               sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11875                 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11876               if (sp < 0)
11877                 {
11878                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
11879                     SvPV(ST(i),na));
11880                   break;
11881                 }
11882              montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11883              break;
11884             }
11885           if (LocaleCompare(attribute,"stroke") == 0)
11886             {
11887               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11888                 &montage_info->stroke,exception);
11889               break;
11890             }
11891           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11892             attribute);
11893           break;
11894         }
11895         case 'T':
11896         case 't':
11897         {
11898           if (LocaleCompare(attribute,"texture") == 0)
11899             {
11900               (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11901               break;
11902             }
11903           if (LocaleCompare(attribute,"tile") == 0)
11904             {
11905               char *p=SvPV(ST(i),na);
11906               if (IsGeometry(p) == MagickFalse)
11907                 {
11908                   ThrowPerlException(exception,OptionError,"MissingGeometry",
11909                     p);
11910                   break;
11911                 }
11912               (void) CloneString(&montage_info->tile,p);
11913               if (*p == '\0')
11914                 montage_info->tile=(char *) NULL;
11915               break;
11916             }
11917           if (LocaleCompare(attribute,"title") == 0)
11918             {
11919               (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11920               break;
11921             }
11922           if (LocaleCompare(attribute,"transparent") == 0)
11923             {
11924               PixelInfo
11925                 transparent_color;
11926 
11927               QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11928                 &transparent_color,exception);
11929               for (next=image; next; next=next->next)
11930                 (void) TransparentPaintImage(next,&transparent_color,
11931                   TransparentAlpha,MagickFalse,exception);
11932               break;
11933             }
11934           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11935             attribute);
11936           break;
11937         }
11938         default:
11939         {
11940           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11941             attribute);
11942           break;
11943         }
11944       }
11945     }
11946     image=MontageImageList(info->image_info,montage_info,image,exception);
11947     montage_info=DestroyMontageInfo(montage_info);
11948     if (image == (Image *) NULL)
11949       goto PerlException;
11950     if (transparent_color.alpha != TransparentAlpha)
11951       for (next=image; next; next=next->next)
11952         (void) TransparentPaintImage(next,&transparent_color,
11953           TransparentAlpha,MagickFalse,exception);
11954     for (  ; image; image=image->next)
11955     {
11956       AddImageToRegistry(sv,image);
11957       rv=newRV(sv);
11958       av_push(av,sv_bless(rv,hv));
11959       SvREFCNT_dec(sv);
11960     }
11961     exception=DestroyExceptionInfo(exception);
11962     ST(0)=av_reference;
11963     SvREFCNT_dec(perl_exception);
11964     XSRETURN(1);
11965 
11966   PerlException:
11967     InheritPerlException(exception,perl_exception);
11968     exception=DestroyExceptionInfo(exception);
11969     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11970     SvPOK_on(perl_exception);
11971     ST(0)=sv_2mortal(perl_exception);
11972     XSRETURN(1);
11973   }
11974 
11975 #
11976 ###############################################################################
11977 #                                                                             #
11978 #                                                                             #
11979 #                                                                             #
11980 #   M o r p h                                                                 #
11981 #                                                                             #
11982 #                                                                             #
11983 #                                                                             #
11984 ###############################################################################
11985 #
11986 #
11987 void
Morph(ref,...)11988 Morph(ref,...)
11989   Image::Magick ref=NO_INIT
11990   ALIAS:
11991     MorphImage  = 1
11992     morph       = 2
11993     morphimage  = 3
11994   PPCODE:
11995   {
11996     AV
11997       *av;
11998 
11999     char
12000       *attribute;
12001 
12002     ExceptionInfo
12003       *exception;
12004 
12005     HV
12006       *hv;
12007 
12008     Image
12009       *image;
12010 
12011     register ssize_t
12012       i;
12013 
12014     ssize_t
12015       number_frames;
12016 
12017     struct PackageInfo
12018       *info;
12019 
12020     SV
12021       *av_reference,
12022       *perl_exception,
12023       *reference,
12024       *rv,
12025       *sv;
12026 
12027     PERL_UNUSED_VAR(ref);
12028     PERL_UNUSED_VAR(ix);
12029     exception=AcquireExceptionInfo();
12030     perl_exception=newSVpv("",0);
12031     sv=NULL;
12032     av=NULL;
12033     attribute=NULL;
12034     if (sv_isobject(ST(0)) == 0)
12035       {
12036         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12037           PackageName);
12038         goto PerlException;
12039       }
12040     reference=SvRV(ST(0));
12041     hv=SvSTASH(reference);
12042     av=newAV();
12043     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12044     SvREFCNT_dec(av);
12045     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12046     if (image == (Image *) NULL)
12047       {
12048         ThrowPerlException(exception,OptionError,"NoImagesDefined",
12049           PackageName);
12050         goto PerlException;
12051       }
12052     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12053     /*
12054       Get attribute.
12055     */
12056     number_frames=30;
12057     for (i=2; i < items; i+=2)
12058     {
12059       attribute=(char *) SvPV(ST(i-1),na);
12060       switch (*attribute)
12061       {
12062         case 'F':
12063         case 'f':
12064         {
12065           if (LocaleCompare(attribute,"frames") == 0)
12066             {
12067               number_frames=SvIV(ST(i));
12068               break;
12069             }
12070           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12071             attribute);
12072           break;
12073         }
12074         default:
12075         {
12076           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12077             attribute);
12078           break;
12079         }
12080       }
12081     }
12082     image=MorphImages(image,number_frames,exception);
12083     if (image == (Image *) NULL)
12084       goto PerlException;
12085     for ( ; image; image=image->next)
12086     {
12087       AddImageToRegistry(sv,image);
12088       rv=newRV(sv);
12089       av_push(av,sv_bless(rv,hv));
12090       SvREFCNT_dec(sv);
12091     }
12092     exception=DestroyExceptionInfo(exception);
12093     ST(0)=av_reference;
12094     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
12095     XSRETURN(1);
12096 
12097   PerlException:
12098     InheritPerlException(exception,perl_exception);
12099     exception=DestroyExceptionInfo(exception);
12100     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12101     SvPOK_on(perl_exception);
12102     ST(0)=sv_2mortal(perl_exception);
12103     XSRETURN(1);
12104   }
12105 
12106 #
12107 ###############################################################################
12108 #                                                                             #
12109 #                                                                             #
12110 #                                                                             #
12111 #   M o s a i c                                                               #
12112 #                                                                             #
12113 #                                                                             #
12114 #                                                                             #
12115 ###############################################################################
12116 #
12117 #
12118 void
Mosaic(ref)12119 Mosaic(ref)
12120   Image::Magick ref=NO_INIT
12121   ALIAS:
12122     MosaicImage   = 1
12123     mosaic        = 2
12124     mosaicimage   = 3
12125   PPCODE:
12126   {
12127     AV
12128       *av;
12129 
12130     ExceptionInfo
12131       *exception;
12132 
12133     HV
12134       *hv;
12135 
12136     Image
12137       *image;
12138 
12139     struct PackageInfo
12140       *info;
12141 
12142     SV
12143       *perl_exception,
12144       *reference,
12145       *rv,
12146       *sv;
12147 
12148     PERL_UNUSED_VAR(ref);
12149     PERL_UNUSED_VAR(ix);
12150     exception=AcquireExceptionInfo();
12151     perl_exception=newSVpv("",0);
12152     sv=NULL;
12153     if (sv_isobject(ST(0)) == 0)
12154       {
12155         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12156           PackageName);
12157         goto PerlException;
12158       }
12159     reference=SvRV(ST(0));
12160     hv=SvSTASH(reference);
12161     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12162     if (image == (Image *) NULL)
12163       {
12164         ThrowPerlException(exception,OptionError,"NoImagesDefined",
12165           PackageName);
12166         goto PerlException;
12167       }
12168     image=MergeImageLayers(image,MosaicLayer,exception);
12169     /*
12170       Create blessed Perl array for the returned image.
12171     */
12172     av=newAV();
12173     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12174     SvREFCNT_dec(av);
12175     AddImageToRegistry(sv,image);
12176     rv=newRV(sv);
12177     av_push(av,sv_bless(rv,hv));
12178     SvREFCNT_dec(sv);
12179     (void) CopyMagickString(info->image_info->filename,image->filename,
12180       MagickPathExtent);
12181     SetImageInfo(info->image_info,0,exception);
12182     exception=DestroyExceptionInfo(exception);
12183     SvREFCNT_dec(perl_exception);
12184     XSRETURN(1);
12185 
12186   PerlException:
12187     InheritPerlException(exception,perl_exception);
12188     exception=DestroyExceptionInfo(exception);
12189     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12190     SvPOK_on(perl_exception);  /* return messages in string context */
12191     ST(0)=sv_2mortal(perl_exception);
12192     XSRETURN(1);
12193   }
12194 
12195 #
12196 ###############################################################################
12197 #                                                                             #
12198 #                                                                             #
12199 #                                                                             #
12200 #   P i n g                                                                   #
12201 #                                                                             #
12202 #                                                                             #
12203 #                                                                             #
12204 ###############################################################################
12205 #
12206 #
12207 void
Ping(ref,...)12208 Ping(ref,...)
12209   Image::Magick ref=NO_INIT
12210   ALIAS:
12211     PingImage  = 1
12212     ping       = 2
12213     pingimage  = 3
12214   PPCODE:
12215   {
12216     AV
12217       *av;
12218 
12219     char
12220       **keep,
12221       **list;
12222 
12223     ExceptionInfo
12224       *exception;
12225 
12226     Image
12227       *image,
12228       *next;
12229 
12230     int
12231       n;
12232 
12233     MagickBooleanType
12234       status;
12235 
12236     register char
12237       **p;
12238 
12239     register ssize_t
12240       i;
12241 
12242     ssize_t
12243       ac;
12244 
12245     STRLEN
12246       *length;
12247 
12248     struct PackageInfo
12249       *info,
12250       *package_info;
12251 
12252     SV
12253       *perl_exception,
12254       *reference;
12255 
12256     size_t
12257       count;
12258 
12259     PERL_UNUSED_VAR(ref);
12260     PERL_UNUSED_VAR(ix);
12261     exception=AcquireExceptionInfo();
12262     perl_exception=newSVpv("",0);
12263     package_info=(struct PackageInfo *) NULL;
12264     ac=(items < 2) ? 1 : items-1;
12265     list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12266     keep=list;
12267     length=(STRLEN *) NULL;
12268     if (list == (char **) NULL)
12269       {
12270         ThrowPerlException(exception,ResourceLimitError,
12271           "MemoryAllocationFailed",PackageName);
12272         goto PerlException;
12273       }
12274     keep=list;
12275     length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12276     if (length == (STRLEN *) NULL)
12277       {
12278         ThrowPerlException(exception,ResourceLimitError,
12279           "MemoryAllocationFailed",PackageName);
12280         goto PerlException;
12281       }
12282     if (sv_isobject(ST(0)) == 0)
12283       {
12284         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12285           PackageName);
12286         goto PerlException;
12287       }
12288     reference=SvRV(ST(0));
12289     if (SvTYPE(reference) != SVt_PVAV)
12290       {
12291         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12292           PackageName);
12293         goto PerlException;
12294       }
12295     av=(AV *) reference;
12296     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12297       exception);
12298     package_info=ClonePackageInfo(info,exception);
12299     n=1;
12300     if (items <= 1)
12301       *list=(char *) (*package_info->image_info->filename ?
12302         package_info->image_info->filename : "XC:black");
12303     else
12304       for (n=0, i=0; i < ac; i++)
12305       {
12306         list[n]=(char *) SvPV(ST(i+1),length[n]);
12307         if ((items >= 3) && strEQcase(list[n],"blob"))
12308           {
12309             void
12310               *blob;
12311 
12312             i++;
12313             blob=(void *) (SvPV(ST(i+1),length[n]));
12314             SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12315           }
12316         if ((items >= 3) && strEQcase(list[n],"filename"))
12317           continue;
12318         if ((items >= 3) && strEQcase(list[n],"file"))
12319           {
12320             FILE
12321               *file;
12322 
12323             PerlIO
12324               *io_info;
12325 
12326             i++;
12327             io_info=IoIFP(sv_2io(ST(i+1)));
12328             if (io_info == (PerlIO *) NULL)
12329               {
12330                 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12331                   PackageName);
12332                 continue;
12333               }
12334             file=PerlIO_findFILE(io_info);
12335             if (file == (FILE *) NULL)
12336               {
12337                 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12338                   PackageName);
12339                 continue;
12340               }
12341             SetImageInfoFile(package_info->image_info,file);
12342           }
12343         if ((items >= 3) && strEQcase(list[n],"magick"))
12344           continue;
12345         n++;
12346       }
12347     list[n]=(char *) NULL;
12348     keep=list;
12349     status=ExpandFilenames(&n,&list);
12350     if (status == MagickFalse)
12351       {
12352         ThrowPerlException(exception,ResourceLimitError,
12353           "MemoryAllocationFailed",PackageName);
12354         goto PerlException;
12355       }
12356     count=0;
12357     for (i=0; i < n; i++)
12358     {
12359       (void) CopyMagickString(package_info->image_info->filename,list[i],
12360         MagickPathExtent);
12361       image=PingImage(package_info->image_info,exception);
12362       if (image == (Image *) NULL)
12363         break;
12364       if ((package_info->image_info->file != (FILE *) NULL) ||
12365           (package_info->image_info->blob != (void *) NULL))
12366         DisassociateImageStream(image);
12367       count+=GetImageListLength(image);
12368       EXTEND(sp,4*count);
12369       for (next=image; next; next=next->next)
12370       {
12371         PUSHs(sv_2mortal(newSViv(next->columns)));
12372         PUSHs(sv_2mortal(newSViv(next->rows)));
12373         PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
12374         PUSHs(sv_2mortal(newSVpv(next->magick,0)));
12375       }
12376       image=DestroyImageList(image);
12377     }
12378     /*
12379       Free resources.
12380     */
12381     for (i=0; i < n; i++)
12382       if (list[i] != (char *) NULL)
12383         for (p=keep; list[i] != *p++; )
12384           if (*p == NULL)
12385             {
12386               list[i]=(char *) RelinquishMagickMemory(list[i]);
12387               break;
12388             }
12389 
12390   PerlException:
12391     if (package_info != (struct PackageInfo *) NULL)
12392       DestroyPackageInfo(package_info);
12393     if (list && (list != keep))
12394       list=(char **) RelinquishMagickMemory(list);
12395     if (keep)
12396       keep=(char **) RelinquishMagickMemory(keep);
12397     if (length)
12398       length=(STRLEN *) RelinquishMagickMemory(length);
12399     InheritPerlException(exception,perl_exception);
12400     exception=DestroyExceptionInfo(exception);
12401     SvREFCNT_dec(perl_exception);  /* throw away all errors */
12402   }
12403 
12404 #
12405 ###############################################################################
12406 #                                                                             #
12407 #                                                                             #
12408 #                                                                             #
12409 #   P r e v i e w                                                             #
12410 #                                                                             #
12411 #                                                                             #
12412 #                                                                             #
12413 ###############################################################################
12414 #
12415 #
12416 void
Preview(ref,...)12417 Preview(ref,...)
12418   Image::Magick ref=NO_INIT
12419   ALIAS:
12420     PreviewImage = 1
12421     preview      = 2
12422     previewimage = 3
12423   PPCODE:
12424   {
12425     AV
12426       *av;
12427 
12428     ExceptionInfo
12429       *exception;
12430 
12431     HV
12432       *hv;
12433 
12434     Image
12435       *image,
12436       *preview_image;
12437 
12438     PreviewType
12439       preview_type;
12440 
12441     struct PackageInfo
12442       *info;
12443 
12444     SV
12445       *av_reference,
12446       *perl_exception,
12447       *reference,
12448       *rv,
12449       *sv;
12450 
12451     PERL_UNUSED_VAR(ref);
12452     PERL_UNUSED_VAR(ix);
12453     exception=AcquireExceptionInfo();
12454     perl_exception=newSVpv("",0);
12455     sv=NULL;
12456     av=NULL;
12457     if (sv_isobject(ST(0)) == 0)
12458       {
12459         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12460           PackageName);
12461         goto PerlException;
12462       }
12463     reference=SvRV(ST(0));
12464     hv=SvSTASH(reference);
12465     av=newAV();
12466     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12467     SvREFCNT_dec(av);
12468     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12469     if (image == (Image *) NULL)
12470       {
12471         ThrowPerlException(exception,OptionError,"NoImagesDefined",
12472           PackageName);
12473         goto PerlException;
12474       }
12475     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12476     preview_type=GammaPreview;
12477     if (items > 1)
12478       preview_type=(PreviewType)
12479         ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12480     for ( ; image; image=image->next)
12481     {
12482       preview_image=PreviewImage(image,preview_type,exception);
12483       if (preview_image == (Image *) NULL)
12484         goto PerlException;
12485       AddImageToRegistry(sv,preview_image);
12486       rv=newRV(sv);
12487       av_push(av,sv_bless(rv,hv));
12488       SvREFCNT_dec(sv);
12489     }
12490     exception=DestroyExceptionInfo(exception);
12491     ST(0)=av_reference;
12492     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
12493     XSRETURN(1);
12494 
12495   PerlException:
12496     InheritPerlException(exception,perl_exception);
12497     exception=DestroyExceptionInfo(exception);
12498     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12499     SvPOK_on(perl_exception);
12500     ST(0)=sv_2mortal(perl_exception);
12501     XSRETURN(1);
12502   }
12503 
12504 #
12505 ###############################################################################
12506 #                                                                             #
12507 #                                                                             #
12508 #                                                                             #
12509 #   Q u e r y C o l o r                                                       #
12510 #                                                                             #
12511 #                                                                             #
12512 #                                                                             #
12513 ###############################################################################
12514 #
12515 #
12516 void
QueryColor(ref,...)12517 QueryColor(ref,...)
12518   Image::Magick ref=NO_INIT
12519   ALIAS:
12520     querycolor = 1
12521   PPCODE:
12522   {
12523     char
12524       *name;
12525 
12526     ExceptionInfo
12527       *exception;
12528 
12529     PixelInfo
12530       color;
12531 
12532     register ssize_t
12533       i;
12534 
12535     SV
12536       *perl_exception;
12537 
12538     PERL_UNUSED_VAR(ref);
12539     PERL_UNUSED_VAR(ix);
12540     exception=AcquireExceptionInfo();
12541     perl_exception=newSVpv("",0);
12542     if (items == 1)
12543       {
12544         const ColorInfo
12545           **colorlist;
12546 
12547         size_t
12548           colors;
12549 
12550         colorlist=GetColorInfoList("*",&colors,exception);
12551         EXTEND(sp,colors);
12552         for (i=0; i < (ssize_t) colors; i++)
12553         {
12554           PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12555         }
12556         colorlist=(const ColorInfo **)
12557           RelinquishMagickMemory((ColorInfo **) colorlist);
12558         goto PerlException;
12559       }
12560     EXTEND(sp,5*items);
12561     for (i=1; i < items; i++)
12562     {
12563       name=(char *) SvPV(ST(i),na);
12564       if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12565         {
12566           PUSHs(&sv_undef);
12567           continue;
12568         }
12569       PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12570       PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12571       PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12572       if (color.colorspace == CMYKColorspace)
12573         PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
12574       if (color.alpha_trait != UndefinedPixelTrait)
12575         PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12576     }
12577 
12578   PerlException:
12579     InheritPerlException(exception,perl_exception);
12580     exception=DestroyExceptionInfo(exception);
12581     SvREFCNT_dec(perl_exception);
12582   }
12583 
12584 #
12585 ###############################################################################
12586 #                                                                             #
12587 #                                                                             #
12588 #                                                                             #
12589 #   Q u e r y C o l o r N a m e                                               #
12590 #                                                                             #
12591 #                                                                             #
12592 #                                                                             #
12593 ###############################################################################
12594 #
12595 #
12596 void
QueryColorname(ref,...)12597 QueryColorname(ref,...)
12598   Image::Magick ref=NO_INIT
12599   ALIAS:
12600     querycolorname = 1
12601   PPCODE:
12602   {
12603     AV
12604       *av;
12605 
12606     char
12607       message[MagickPathExtent];
12608 
12609     ExceptionInfo
12610       *exception;
12611 
12612     Image
12613       *image;
12614 
12615     PixelInfo
12616       target_color;
12617 
12618     register ssize_t
12619       i;
12620 
12621     struct PackageInfo
12622       *info;
12623 
12624     SV
12625       *perl_exception,
12626       *reference;  /* reference is the SV* of ref=SvIV(reference) */
12627 
12628     PERL_UNUSED_VAR(ref);
12629     PERL_UNUSED_VAR(ix);
12630     exception=AcquireExceptionInfo();
12631     perl_exception=newSVpv("",0);
12632     reference=SvRV(ST(0));
12633     av=(AV *) reference;
12634     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12635       exception);
12636     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12637     if (image == (Image *) NULL)
12638       {
12639         ThrowPerlException(exception,OptionError,"NoImagesDefined",
12640           PackageName);
12641         goto PerlException;
12642       }
12643     EXTEND(sp,items);
12644     for (i=1; i < items; i++)
12645     {
12646       (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12647         exception);
12648       (void) QueryColorname(image,&target_color,SVGCompliance,message,
12649         exception);
12650       PUSHs(sv_2mortal(newSVpv(message,0)));
12651     }
12652 
12653   PerlException:
12654     InheritPerlException(exception,perl_exception);
12655     exception=DestroyExceptionInfo(exception);
12656     SvREFCNT_dec(perl_exception);
12657   }
12658 
12659 #
12660 ###############################################################################
12661 #                                                                             #
12662 #                                                                             #
12663 #                                                                             #
12664 #   Q u e r y F o n t                                                         #
12665 #                                                                             #
12666 #                                                                             #
12667 #                                                                             #
12668 ###############################################################################
12669 #
12670 #
12671 void
QueryFont(ref,...)12672 QueryFont(ref,...)
12673   Image::Magick ref=NO_INIT
12674   ALIAS:
12675     queryfont = 1
12676   PPCODE:
12677   {
12678     char
12679       *name,
12680       message[MagickPathExtent];
12681 
12682     ExceptionInfo
12683       *exception;
12684 
12685     register ssize_t
12686       i;
12687 
12688     SV
12689       *perl_exception;
12690 
12691     volatile const TypeInfo
12692       *type_info;
12693 
12694     PERL_UNUSED_VAR(ref);
12695     PERL_UNUSED_VAR(ix);
12696     exception=AcquireExceptionInfo();
12697     perl_exception=newSVpv("",0);
12698     if (items == 1)
12699       {
12700         const TypeInfo
12701           **typelist;
12702 
12703         size_t
12704           types;
12705 
12706         typelist=GetTypeInfoList("*",&types,exception);
12707         EXTEND(sp,types);
12708         for (i=0; i < (ssize_t) types; i++)
12709         {
12710           PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12711         }
12712         typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12713           typelist);
12714         goto PerlException;
12715       }
12716     EXTEND(sp,10*items);
12717     for (i=1; i < items; i++)
12718     {
12719       name=(char *) SvPV(ST(i),na);
12720       type_info=GetTypeInfo(name,exception);
12721       if (type_info == (TypeInfo *) NULL)
12722         {
12723           PUSHs(&sv_undef);
12724           continue;
12725         }
12726       if (type_info->name == (char *) NULL)
12727         PUSHs(&sv_undef);
12728       else
12729         PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12730       if (type_info->description == (char *) NULL)
12731         PUSHs(&sv_undef);
12732       else
12733         PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12734       if (type_info->family == (char *) NULL)
12735         PUSHs(&sv_undef);
12736       else
12737         PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12738       if (type_info->style == UndefinedStyle)
12739         PUSHs(&sv_undef);
12740       else
12741         PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12742           type_info->style),0)));
12743       if (type_info->stretch == UndefinedStretch)
12744         PUSHs(&sv_undef);
12745       else
12746         PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12747           type_info->stretch),0)));
12748       (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
12749         type_info->weight);
12750       PUSHs(sv_2mortal(newSVpv(message,0)));
12751       if (type_info->encoding == (char *) NULL)
12752         PUSHs(&sv_undef);
12753       else
12754         PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12755       if (type_info->foundry == (char *) NULL)
12756         PUSHs(&sv_undef);
12757       else
12758         PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12759       if (type_info->format == (char *) NULL)
12760         PUSHs(&sv_undef);
12761       else
12762         PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12763       if (type_info->metrics == (char *) NULL)
12764         PUSHs(&sv_undef);
12765       else
12766         PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12767       if (type_info->glyphs == (char *) NULL)
12768         PUSHs(&sv_undef);
12769       else
12770         PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12771     }
12772 
12773   PerlException:
12774     InheritPerlException(exception,perl_exception);
12775     exception=DestroyExceptionInfo(exception);
12776     SvREFCNT_dec(perl_exception);
12777   }
12778 
12779 #
12780 ###############################################################################
12781 #                                                                             #
12782 #                                                                             #
12783 #                                                                             #
12784 #   Q u e r y F o n t M e t r i c s                                           #
12785 #                                                                             #
12786 #                                                                             #
12787 #                                                                             #
12788 ###############################################################################
12789 #
12790 #
12791 void
QueryFontMetrics(ref,...)12792 QueryFontMetrics(ref,...)
12793   Image::Magick ref=NO_INIT
12794   ALIAS:
12795     queryfontmetrics = 1
12796   PPCODE:
12797   {
12798     AffineMatrix
12799       affine,
12800       current;
12801 
12802     AV
12803       *av;
12804 
12805     char
12806       *attribute;
12807 
12808     double
12809       x,
12810       y;
12811 
12812     DrawInfo
12813       *draw_info;
12814 
12815     ExceptionInfo
12816       *exception;
12817 
12818     GeometryInfo
12819       geometry_info;
12820 
12821     Image
12822       *image;
12823 
12824     MagickBooleanType
12825       status;
12826 
12827     MagickStatusType
12828       flags;
12829 
12830     register ssize_t
12831       i;
12832 
12833     ssize_t
12834       type;
12835 
12836     struct PackageInfo
12837       *info,
12838       *package_info;
12839 
12840     SV
12841       *perl_exception,
12842       *reference;  /* reference is the SV* of ref=SvIV(reference) */
12843 
12844     TypeMetric
12845       metrics;
12846 
12847     PERL_UNUSED_VAR(ref);
12848     PERL_UNUSED_VAR(ix);
12849     exception=AcquireExceptionInfo();
12850     package_info=(struct PackageInfo *) NULL;
12851     perl_exception=newSVpv("",0);
12852     reference=SvRV(ST(0));
12853     av=(AV *) reference;
12854     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12855       exception);
12856     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12857     if (image == (Image *) NULL)
12858       {
12859         ThrowPerlException(exception,OptionError,"NoImagesDefined",
12860           PackageName);
12861         goto PerlException;
12862       }
12863     package_info=ClonePackageInfo(info,exception);
12864     draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12865     CloneString(&draw_info->text,"");
12866     current=draw_info->affine;
12867     GetAffineMatrix(&affine);
12868     x=0.0;
12869     y=0.0;
12870     EXTEND(sp,7*items);
12871     for (i=2; i < items; i+=2)
12872     {
12873       attribute=(char *) SvPV(ST(i-1),na);
12874       switch (*attribute)
12875       {
12876         case 'A':
12877         case 'a':
12878         {
12879           if (LocaleCompare(attribute,"antialias") == 0)
12880             {
12881               type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12882                 SvPV(ST(i),na));
12883               if (type < 0)
12884                 {
12885                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
12886                     SvPV(ST(i),na));
12887                   break;
12888                 }
12889               draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12890               break;
12891             }
12892           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12893             attribute);
12894           break;
12895         }
12896         case 'd':
12897         case 'D':
12898         {
12899           if (LocaleCompare(attribute,"density") == 0)
12900             {
12901               CloneString(&draw_info->density,SvPV(ST(i),na));
12902               break;
12903             }
12904           if (LocaleCompare(attribute,"direction") == 0)
12905             {
12906               draw_info->direction=(DirectionType) ParseCommandOption(
12907                 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12908               break;
12909             }
12910           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12911             attribute);
12912           break;
12913         }
12914         case 'e':
12915         case 'E':
12916         {
12917           if (LocaleCompare(attribute,"encoding") == 0)
12918             {
12919               CloneString(&draw_info->encoding,SvPV(ST(i),na));
12920               break;
12921             }
12922           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12923             attribute);
12924           break;
12925         }
12926         case 'f':
12927         case 'F':
12928         {
12929           if (LocaleCompare(attribute,"family") == 0)
12930             {
12931               CloneString(&draw_info->family,SvPV(ST(i),na));
12932               break;
12933             }
12934           if (LocaleCompare(attribute,"fill") == 0)
12935             {
12936               if (info)
12937                 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12938                   &draw_info->fill,exception);
12939               break;
12940             }
12941           if (LocaleCompare(attribute,"font") == 0)
12942             {
12943               CloneString(&draw_info->font,SvPV(ST(i),na));
12944               break;
12945             }
12946           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12947             attribute);
12948           break;
12949         }
12950         case 'g':
12951         case 'G':
12952         {
12953           if (LocaleCompare(attribute,"geometry") == 0)
12954             {
12955               CloneString(&draw_info->geometry,SvPV(ST(i),na));
12956               break;
12957             }
12958           if (LocaleCompare(attribute,"gravity") == 0)
12959             {
12960               draw_info->gravity=(GravityType) ParseCommandOption(
12961                 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12962               break;
12963             }
12964           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12965             attribute);
12966           break;
12967         }
12968         case 'i':
12969         case 'I':
12970         {
12971           if (LocaleCompare(attribute,"interline-spacing") == 0)
12972             {
12973               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12974               draw_info->interline_spacing=geometry_info.rho;
12975               break;
12976             }
12977           if (LocaleCompare(attribute,"interword-spacing") == 0)
12978             {
12979               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12980               draw_info->interword_spacing=geometry_info.rho;
12981               break;
12982             }
12983           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12984             attribute);
12985           break;
12986         }
12987         case 'k':
12988         case 'K':
12989         {
12990           if (LocaleCompare(attribute,"kerning") == 0)
12991             {
12992               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12993               draw_info->kerning=geometry_info.rho;
12994               break;
12995             }
12996           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12997             attribute);
12998           break;
12999         }
13000         case 'p':
13001         case 'P':
13002         {
13003           if (LocaleCompare(attribute,"pointsize") == 0)
13004             {
13005               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13006               draw_info->pointsize=geometry_info.rho;
13007               break;
13008             }
13009           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13010             attribute);
13011           break;
13012         }
13013         case 'r':
13014         case 'R':
13015         {
13016           if (LocaleCompare(attribute,"rotate") == 0)
13017             {
13018               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13019               affine.rx=geometry_info.rho;
13020               affine.ry=geometry_info.sigma;
13021               if ((flags & SigmaValue) == 0)
13022                 affine.ry=affine.rx;
13023               break;
13024             }
13025           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13026             attribute);
13027           break;
13028         }
13029         case 's':
13030         case 'S':
13031         {
13032           if (LocaleCompare(attribute,"scale") == 0)
13033             {
13034               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13035               affine.sx=geometry_info.rho;
13036               affine.sy=geometry_info.sigma;
13037               if ((flags & SigmaValue) == 0)
13038                 affine.sy=affine.sx;
13039               break;
13040             }
13041           if (LocaleCompare(attribute,"skew") == 0)
13042             {
13043               double
13044                 x_angle,
13045                 y_angle;
13046 
13047               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13048               x_angle=geometry_info.rho;
13049               y_angle=geometry_info.sigma;
13050               if ((flags & SigmaValue) == 0)
13051                 y_angle=x_angle;
13052               affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13053               affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13054               break;
13055             }
13056           if (LocaleCompare(attribute,"stroke") == 0)
13057             {
13058               if (info)
13059                 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13060                   &draw_info->stroke,exception);
13061               break;
13062             }
13063           if (LocaleCompare(attribute,"style") == 0)
13064             {
13065               type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13066                 SvPV(ST(i),na));
13067               if (type < 0)
13068                 {
13069                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
13070                     SvPV(ST(i),na));
13071                   break;
13072                 }
13073               draw_info->style=(StyleType) type;
13074               break;
13075             }
13076           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13077             attribute);
13078           break;
13079         }
13080         case 't':
13081         case 'T':
13082         {
13083           if (LocaleCompare(attribute,"text") == 0)
13084             {
13085               CloneString(&draw_info->text,SvPV(ST(i),na));
13086               break;
13087             }
13088           if (LocaleCompare(attribute,"translate") == 0)
13089             {
13090               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13091               affine.tx=geometry_info.rho;
13092               affine.ty=geometry_info.sigma;
13093               if ((flags & SigmaValue) == 0)
13094                 affine.ty=affine.tx;
13095               break;
13096             }
13097           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13098             attribute);
13099           break;
13100         }
13101         case 'w':
13102         case 'W':
13103         {
13104           if (LocaleCompare(attribute,"weight") == 0)
13105             {
13106               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13107               draw_info->weight=(size_t) geometry_info.rho;
13108               break;
13109             }
13110           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13111             attribute);
13112           break;
13113         }
13114         case 'x':
13115         case 'X':
13116         {
13117           if (LocaleCompare(attribute,"x") == 0)
13118             {
13119               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13120               x=geometry_info.rho;
13121               break;
13122             }
13123           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13124             attribute);
13125           break;
13126         }
13127         case 'y':
13128         case 'Y':
13129         {
13130           if (LocaleCompare(attribute,"y") == 0)
13131             {
13132               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13133               y=geometry_info.rho;
13134               break;
13135             }
13136           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13137             attribute);
13138           break;
13139         }
13140         default:
13141         {
13142           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13143             attribute);
13144           break;
13145         }
13146       }
13147     }
13148     draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13149     draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13150     draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13151     draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13152     draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13153     draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13154     if (draw_info->geometry == (char *) NULL)
13155       {
13156         draw_info->geometry=AcquireString((char *) NULL);
13157         (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
13158           "%.20g,%.20g",x,y);
13159       }
13160     status=GetTypeMetrics(image,draw_info,&metrics,exception);
13161     (void) CatchImageException(image);
13162     if (status == MagickFalse)
13163       PUSHs(&sv_undef);
13164     else
13165       {
13166         PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13167         PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13168         PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13169         PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13170         PUSHs(sv_2mortal(newSVnv(metrics.width)));
13171         PUSHs(sv_2mortal(newSVnv(metrics.height)));
13172         PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13173         PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13174         PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13175         PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13176         PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13177         PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13178         PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13179       }
13180     draw_info=DestroyDrawInfo(draw_info);
13181 
13182   PerlException:
13183     if (package_info != (struct PackageInfo *) NULL)
13184       DestroyPackageInfo(package_info);
13185     InheritPerlException(exception,perl_exception);
13186     exception=DestroyExceptionInfo(exception);
13187     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
13188   }
13189 
13190 #
13191 ###############################################################################
13192 #                                                                             #
13193 #                                                                             #
13194 #                                                                             #
13195 #   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                         #
13196 #                                                                             #
13197 #                                                                             #
13198 #                                                                             #
13199 ###############################################################################
13200 #
13201 #
13202 void
QueryMultilineFontMetrics(ref,...)13203 QueryMultilineFontMetrics(ref,...)
13204   Image::Magick ref=NO_INIT
13205   ALIAS:
13206     querymultilinefontmetrics = 1
13207   PPCODE:
13208   {
13209     AffineMatrix
13210       affine,
13211       current;
13212 
13213     AV
13214       *av;
13215 
13216     char
13217       *attribute;
13218 
13219     double
13220       x,
13221       y;
13222 
13223     DrawInfo
13224       *draw_info;
13225 
13226     ExceptionInfo
13227       *exception;
13228 
13229     GeometryInfo
13230       geometry_info;
13231 
13232     Image
13233       *image;
13234 
13235     MagickBooleanType
13236       status;
13237 
13238     MagickStatusType
13239       flags;
13240 
13241     register ssize_t
13242       i;
13243 
13244     ssize_t
13245       type;
13246 
13247     struct PackageInfo
13248       *info,
13249       *package_info;
13250 
13251     SV
13252       *perl_exception,
13253       *reference;  /* reference is the SV* of ref=SvIV(reference) */
13254 
13255     TypeMetric
13256       metrics;
13257 
13258     PERL_UNUSED_VAR(ref);
13259     PERL_UNUSED_VAR(ix);
13260     exception=AcquireExceptionInfo();
13261     package_info=(struct PackageInfo *) NULL;
13262     perl_exception=newSVpv("",0);
13263     reference=SvRV(ST(0));
13264     av=(AV *) reference;
13265     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13266       exception);
13267     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13268     if (image == (Image *) NULL)
13269       {
13270         ThrowPerlException(exception,OptionError,"NoImagesDefined",
13271           PackageName);
13272         goto PerlException;
13273       }
13274     package_info=ClonePackageInfo(info,exception);
13275     draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
13276     CloneString(&draw_info->text,"");
13277     current=draw_info->affine;
13278     GetAffineMatrix(&affine);
13279     x=0.0;
13280     y=0.0;
13281     EXTEND(sp,7*items);
13282     for (i=2; i < items; i+=2)
13283     {
13284       attribute=(char *) SvPV(ST(i-1),na);
13285       switch (*attribute)
13286       {
13287         case 'A':
13288         case 'a':
13289         {
13290           if (LocaleCompare(attribute,"antialias") == 0)
13291             {
13292               type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13293                 SvPV(ST(i),na));
13294               if (type < 0)
13295                 {
13296                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
13297                     SvPV(ST(i),na));
13298                   break;
13299                 }
13300               draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
13301               break;
13302             }
13303           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13304             attribute);
13305           break;
13306         }
13307         case 'd':
13308         case 'D':
13309         {
13310           if (LocaleCompare(attribute,"density") == 0)
13311             {
13312               CloneString(&draw_info->density,SvPV(ST(i),na));
13313               break;
13314             }
13315           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13316             attribute);
13317           break;
13318         }
13319         case 'e':
13320         case 'E':
13321         {
13322           if (LocaleCompare(attribute,"encoding") == 0)
13323             {
13324               CloneString(&draw_info->encoding,SvPV(ST(i),na));
13325               break;
13326             }
13327           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13328             attribute);
13329           break;
13330         }
13331         case 'f':
13332         case 'F':
13333         {
13334           if (LocaleCompare(attribute,"family") == 0)
13335             {
13336               CloneString(&draw_info->family,SvPV(ST(i),na));
13337               break;
13338             }
13339           if (LocaleCompare(attribute,"fill") == 0)
13340             {
13341               if (info)
13342                 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13343                   &draw_info->fill,exception);
13344               break;
13345             }
13346           if (LocaleCompare(attribute,"font") == 0)
13347             {
13348               CloneString(&draw_info->font,SvPV(ST(i),na));
13349               break;
13350             }
13351           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13352             attribute);
13353           break;
13354         }
13355         case 'g':
13356         case 'G':
13357         {
13358           if (LocaleCompare(attribute,"geometry") == 0)
13359             {
13360               CloneString(&draw_info->geometry,SvPV(ST(i),na));
13361               break;
13362             }
13363           if (LocaleCompare(attribute,"gravity") == 0)
13364             {
13365               draw_info->gravity=(GravityType) ParseCommandOption(
13366                 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13367               break;
13368             }
13369           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13370             attribute);
13371           break;
13372         }
13373         case 'p':
13374         case 'P':
13375         {
13376           if (LocaleCompare(attribute,"pointsize") == 0)
13377             {
13378               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13379               draw_info->pointsize=geometry_info.rho;
13380               break;
13381             }
13382           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13383             attribute);
13384           break;
13385         }
13386         case 'r':
13387         case 'R':
13388         {
13389           if (LocaleCompare(attribute,"rotate") == 0)
13390             {
13391               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13392               affine.rx=geometry_info.rho;
13393               affine.ry=geometry_info.sigma;
13394               if ((flags & SigmaValue) == 0)
13395                 affine.ry=affine.rx;
13396               break;
13397             }
13398           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13399             attribute);
13400           break;
13401         }
13402         case 's':
13403         case 'S':
13404         {
13405           if (LocaleCompare(attribute,"scale") == 0)
13406             {
13407               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13408               affine.sx=geometry_info.rho;
13409               affine.sy=geometry_info.sigma;
13410               if ((flags & SigmaValue) == 0)
13411                 affine.sy=affine.sx;
13412               break;
13413             }
13414           if (LocaleCompare(attribute,"skew") == 0)
13415             {
13416               double
13417                 x_angle,
13418                 y_angle;
13419 
13420               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13421               x_angle=geometry_info.rho;
13422               y_angle=geometry_info.sigma;
13423               if ((flags & SigmaValue) == 0)
13424                 y_angle=x_angle;
13425               affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13426               affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13427               break;
13428             }
13429           if (LocaleCompare(attribute,"stroke") == 0)
13430             {
13431               if (info)
13432                 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13433                   &draw_info->stroke,exception);
13434               break;
13435             }
13436           if (LocaleCompare(attribute,"style") == 0)
13437             {
13438               type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13439                 SvPV(ST(i),na));
13440               if (type < 0)
13441                 {
13442                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
13443                     SvPV(ST(i),na));
13444                   break;
13445                 }
13446               draw_info->style=(StyleType) type;
13447               break;
13448             }
13449           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13450             attribute);
13451           break;
13452         }
13453         case 't':
13454         case 'T':
13455         {
13456           if (LocaleCompare(attribute,"text") == 0)
13457             {
13458               CloneString(&draw_info->text,SvPV(ST(i),na));
13459               break;
13460             }
13461           if (LocaleCompare(attribute,"translate") == 0)
13462             {
13463               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13464               affine.tx=geometry_info.rho;
13465               affine.ty=geometry_info.sigma;
13466               if ((flags & SigmaValue) == 0)
13467                 affine.ty=affine.tx;
13468               break;
13469             }
13470           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13471             attribute);
13472           break;
13473         }
13474         case 'w':
13475         case 'W':
13476         {
13477           if (LocaleCompare(attribute,"weight") == 0)
13478             {
13479               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13480               draw_info->weight=(size_t) geometry_info.rho;
13481               break;
13482             }
13483           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13484             attribute);
13485           break;
13486         }
13487         case 'x':
13488         case 'X':
13489         {
13490           if (LocaleCompare(attribute,"x") == 0)
13491             {
13492               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13493               x=geometry_info.rho;
13494               break;
13495             }
13496           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13497             attribute);
13498           break;
13499         }
13500         case 'y':
13501         case 'Y':
13502         {
13503           if (LocaleCompare(attribute,"y") == 0)
13504             {
13505               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13506               y=geometry_info.rho;
13507               break;
13508             }
13509           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13510             attribute);
13511           break;
13512         }
13513         default:
13514         {
13515           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13516             attribute);
13517           break;
13518         }
13519       }
13520     }
13521     draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13522     draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13523     draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13524     draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13525     draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13526     draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13527     if (draw_info->geometry == (char *) NULL)
13528       {
13529         draw_info->geometry=AcquireString((char *) NULL);
13530         (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
13531           "%.20g,%.20g",x,y);
13532       }
13533     status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13534     (void) CatchException(exception);
13535     if (status == MagickFalse)
13536       PUSHs(&sv_undef);
13537     else
13538       {
13539         PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13540         PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13541         PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13542         PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13543         PUSHs(sv_2mortal(newSVnv(metrics.width)));
13544         PUSHs(sv_2mortal(newSVnv(metrics.height)));
13545         PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13546         PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13547         PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13548         PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13549         PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13550         PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13551         PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13552       }
13553     draw_info=DestroyDrawInfo(draw_info);
13554 
13555   PerlException:
13556     if (package_info != (struct PackageInfo *) NULL)
13557       DestroyPackageInfo(package_info);
13558     InheritPerlException(exception,perl_exception);
13559     exception=DestroyExceptionInfo(exception);
13560     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
13561   }
13562 
13563 #
13564 ###############################################################################
13565 #                                                                             #
13566 #                                                                             #
13567 #                                                                             #
13568 #   Q u e r y F o r m a t                                                     #
13569 #                                                                             #
13570 #                                                                             #
13571 #                                                                             #
13572 ###############################################################################
13573 #
13574 #
13575 void
QueryFormat(ref,...)13576 QueryFormat(ref,...)
13577   Image::Magick ref=NO_INIT
13578   ALIAS:
13579     queryformat = 1
13580   PPCODE:
13581   {
13582     char
13583       *name;
13584 
13585     ExceptionInfo
13586       *exception;
13587 
13588     register ssize_t
13589       i;
13590 
13591     SV
13592       *perl_exception;
13593 
13594     volatile const MagickInfo
13595       *magick_info;
13596 
13597     PERL_UNUSED_VAR(ref);
13598     PERL_UNUSED_VAR(ix);
13599     exception=AcquireExceptionInfo();
13600     perl_exception=newSVpv("",0);
13601     if (items == 1)
13602       {
13603         char
13604           format[MagickPathExtent];
13605 
13606         const MagickInfo
13607           **format_list;
13608 
13609         size_t
13610           types;
13611 
13612         format_list=GetMagickInfoList("*",&types,exception);
13613         EXTEND(sp,types);
13614         for (i=0; i < (ssize_t) types; i++)
13615         {
13616           (void) CopyMagickString(format,format_list[i]->name,MagickPathExtent);
13617           LocaleLower(format);
13618           PUSHs(sv_2mortal(newSVpv(format,0)));
13619         }
13620         format_list=(const MagickInfo **)
13621           RelinquishMagickMemory((MagickInfo *) format_list);
13622         goto PerlException;
13623       }
13624     EXTEND(sp,8*items);
13625     for (i=1; i < items; i++)
13626     {
13627       name=(char *) SvPV(ST(i),na);
13628       magick_info=GetMagickInfo(name,exception);
13629       if (magick_info == (const MagickInfo *) NULL)
13630         {
13631           PUSHs(&sv_undef);
13632           continue;
13633         }
13634       if (magick_info->description == (char *) NULL)
13635         PUSHs(&sv_undef);
13636       else
13637         PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13638       if (magick_info->magick_module == (char *) NULL)
13639         PUSHs(&sv_undef);
13640       else
13641         PUSHs(sv_2mortal(newSVpv(magick_info->magick_module,0)));
13642     }
13643 
13644   PerlException:
13645     InheritPerlException(exception,perl_exception);
13646     exception=DestroyExceptionInfo(exception);
13647     SvREFCNT_dec(perl_exception);
13648   }
13649 
13650 #
13651 ###############################################################################
13652 #                                                                             #
13653 #                                                                             #
13654 #                                                                             #
13655 #   Q u e r y O p t i o n                                                     #
13656 #                                                                             #
13657 #                                                                             #
13658 #                                                                             #
13659 ###############################################################################
13660 #
13661 #
13662 void
QueryOption(ref,...)13663 QueryOption(ref,...)
13664   Image::Magick ref=NO_INIT
13665   ALIAS:
13666     queryoption = 1
13667   PPCODE:
13668   {
13669     char
13670       **options;
13671 
13672     ExceptionInfo
13673       *exception;
13674 
13675     register ssize_t
13676       i;
13677 
13678     ssize_t
13679       j,
13680       option;
13681 
13682     SV
13683       *perl_exception;
13684 
13685     PERL_UNUSED_VAR(ref);
13686     PERL_UNUSED_VAR(ix);
13687     exception=AcquireExceptionInfo();
13688     perl_exception=newSVpv("",0);
13689     EXTEND(sp,8*items);
13690     for (i=1; i < items; i++)
13691     {
13692       option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13693         SvPV(ST(i),na));
13694       options=GetCommandOptions((CommandOption) option);
13695       if (options == (char **) NULL)
13696         PUSHs(&sv_undef);
13697       else
13698         {
13699           for (j=0; options[j] != (char *) NULL; j++)
13700             PUSHs(sv_2mortal(newSVpv(options[j],0)));
13701           options=DestroyStringList(options);
13702         }
13703     }
13704 
13705     InheritPerlException(exception,perl_exception);
13706     exception=DestroyExceptionInfo(exception);
13707     SvREFCNT_dec(perl_exception);
13708   }
13709 
13710 #
13711 ###############################################################################
13712 #                                                                             #
13713 #                                                                             #
13714 #                                                                             #
13715 #   R e a d                                                                   #
13716 #                                                                             #
13717 #                                                                             #
13718 #                                                                             #
13719 ###############################################################################
13720 #
13721 #
13722 void
Read(ref,...)13723 Read(ref,...)
13724   Image::Magick ref=NO_INIT
13725   ALIAS:
13726     ReadImage  = 1
13727     read       = 2
13728     readimage  = 3
13729   PPCODE:
13730   {
13731     AV
13732       *av;
13733 
13734     char
13735       **keep,
13736       **list;
13737 
13738     ExceptionInfo
13739       *exception;
13740 
13741     HV
13742       *hv;
13743 
13744     Image
13745       *image;
13746 
13747     int
13748       n;
13749 
13750     MagickBooleanType
13751       status;
13752 
13753     register char
13754       **p;
13755 
13756     register ssize_t
13757       i;
13758 
13759     ssize_t
13760       ac,
13761       number_images;
13762 
13763     STRLEN
13764       *length;
13765 
13766     struct PackageInfo
13767       *info,
13768       *package_info;
13769 
13770     SV
13771       *perl_exception,  /* Perl variable for storing messages */
13772       *reference,
13773       *rv,
13774       *sv;
13775 
13776     PERL_UNUSED_VAR(ref);
13777     PERL_UNUSED_VAR(ix);
13778     exception=AcquireExceptionInfo();
13779     perl_exception=newSVpv("",0);
13780     sv=NULL;
13781     package_info=(struct PackageInfo *) NULL;
13782     number_images=0;
13783     ac=(items < 2) ? 1 : items-1;
13784     list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13785     keep=list;
13786     length=(STRLEN *) NULL;
13787     if (list == (char **) NULL)
13788       {
13789         ThrowPerlException(exception,ResourceLimitError,
13790           "MemoryAllocationFailed",PackageName);
13791         goto PerlException;
13792       }
13793     length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13794     if (length == (STRLEN *) NULL)
13795       {
13796         ThrowPerlException(exception,ResourceLimitError,
13797           "MemoryAllocationFailed",PackageName);
13798         goto PerlException;
13799       }
13800     if (sv_isobject(ST(0)) == 0)
13801       {
13802         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13803           PackageName);
13804         goto PerlException;
13805       }
13806     reference=SvRV(ST(0));
13807     hv=SvSTASH(reference);
13808     if (SvTYPE(reference) != SVt_PVAV)
13809       {
13810         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13811           PackageName);
13812         goto PerlException;
13813       }
13814     av=(AV *) reference;
13815     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13816       exception);
13817     package_info=ClonePackageInfo(info,exception);
13818     n=1;
13819     if (items <= 1)
13820       *list=(char *) (*package_info->image_info->filename ?
13821         package_info->image_info->filename : "XC:black");
13822     else
13823       for (n=0, i=0; i < ac; i++)
13824       {
13825         list[n]=(char *) SvPV(ST(i+1),length[n]);
13826         if ((items >= 3) && strEQcase(list[n],"blob"))
13827           {
13828             void
13829               *blob;
13830 
13831             i++;
13832             blob=(void *) (SvPV(ST(i+1),length[n]));
13833             SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13834           }
13835         if ((items >= 3) && strEQcase(list[n],"filename"))
13836           continue;
13837         if ((items >= 3) && strEQcase(list[n],"file"))
13838           {
13839             FILE
13840               *file;
13841 
13842             PerlIO
13843               *io_info;
13844 
13845             i++;
13846             io_info=IoIFP(sv_2io(ST(i+1)));
13847             if (io_info == (PerlIO *) NULL)
13848               {
13849                 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13850                   PackageName);
13851                 continue;
13852               }
13853             file=PerlIO_findFILE(io_info);
13854             if (file == (FILE *) NULL)
13855               {
13856                 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13857                   PackageName);
13858                 continue;
13859               }
13860             SetImageInfoFile(package_info->image_info,file);
13861           }
13862         if ((items >= 3) && strEQcase(list[n],"magick"))
13863           continue;
13864         n++;
13865       }
13866     list[n]=(char *) NULL;
13867     keep=list;
13868     status=ExpandFilenames(&n,&list);
13869     if (status == MagickFalse)
13870       {
13871         ThrowPerlException(exception,ResourceLimitError,
13872           "MemoryAllocationFailed",PackageName);
13873         goto PerlException;
13874       }
13875     number_images=0;
13876     for (i=0; i < n; i++)
13877     {
13878       if ((package_info->image_info->file == (FILE *) NULL) &&
13879           (package_info->image_info->blob == (void *) NULL))
13880         image=ReadImages(package_info->image_info,list[i],exception);
13881       else
13882         {
13883           image=ReadImages(package_info->image_info,
13884             package_info->image_info->filename,exception);
13885           if (image != (Image *) NULL)
13886             DisassociateImageStream(image);
13887         }
13888       if (image == (Image *) NULL)
13889         break;
13890       for ( ; image; image=image->next)
13891       {
13892         AddImageToRegistry(sv,image);
13893         rv=newRV(sv);
13894         av_push(av,sv_bless(rv,hv));
13895         SvREFCNT_dec(sv);
13896         number_images++;
13897       }
13898     }
13899     /*
13900       Free resources.
13901     */
13902     for (i=0; i < n; i++)
13903       if (list[i] != (char *) NULL)
13904         for (p=keep; list[i] != *p++; )
13905           if (*p == (char *) NULL)
13906             {
13907               list[i]=(char *) RelinquishMagickMemory(list[i]);
13908               break;
13909             }
13910 
13911   PerlException:
13912     if (package_info != (struct PackageInfo *) NULL)
13913       DestroyPackageInfo(package_info);
13914     if (list && (list != keep))
13915       list=(char **) RelinquishMagickMemory(list);
13916     if (keep)
13917       keep=(char **) RelinquishMagickMemory(keep);
13918     if (length)
13919       length=(STRLEN *) RelinquishMagickMemory(length);
13920     InheritPerlException(exception,perl_exception);
13921     exception=DestroyExceptionInfo(exception);
13922     sv_setiv(perl_exception,(IV) number_images);
13923     SvPOK_on(perl_exception);
13924     ST(0)=sv_2mortal(perl_exception);
13925     XSRETURN(1);
13926   }
13927 
13928 #
13929 ###############################################################################
13930 #                                                                             #
13931 #                                                                             #
13932 #                                                                             #
13933 #   R e m o t e                                                               #
13934 #                                                                             #
13935 #                                                                             #
13936 #                                                                             #
13937 ###############################################################################
13938 #
13939 #
13940 void
Remote(ref,...)13941 Remote(ref,...)
13942   Image::Magick ref=NO_INIT
13943   ALIAS:
13944     RemoteCommand  = 1
13945     remote         = 2
13946     remoteCommand  = 3
13947   PPCODE:
13948   {
13949     AV
13950       *av;
13951 
13952     ExceptionInfo
13953       *exception;
13954 
13955     register ssize_t
13956       i;
13957 
13958     SV
13959       *perl_exception,
13960       *reference;
13961 
13962     struct PackageInfo
13963       *info;
13964 
13965     PERL_UNUSED_VAR(ref);
13966     PERL_UNUSED_VAR(ix);
13967     exception=AcquireExceptionInfo();
13968     perl_exception=newSVpv("",0);
13969     reference=SvRV(ST(0));
13970     av=(AV *) reference;
13971     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13972       exception);
13973     for (i=1; i < items; i++)
13974       (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13975         SvPV(ST(i),na),exception);
13976     InheritPerlException(exception,perl_exception);
13977     exception=DestroyExceptionInfo(exception);
13978     SvREFCNT_dec(perl_exception);    /* throw away all errors */
13979   }
13980 
13981 #
13982 ###############################################################################
13983 #                                                                             #
13984 #                                                                             #
13985 #                                                                             #
13986 #   S e t                                                                     #
13987 #                                                                             #
13988 #                                                                             #
13989 #                                                                             #
13990 ###############################################################################
13991 #
13992 #
13993 void
Set(ref,...)13994 Set(ref,...)
13995   Image::Magick ref=NO_INIT
13996   ALIAS:
13997     SetAttributes  = 1
13998     SetAttribute   = 2
13999     set            = 3
14000     setattributes  = 4
14001     setattribute   = 5
14002   PPCODE:
14003   {
14004     ExceptionInfo
14005       *exception;
14006 
14007     Image
14008       *image;
14009 
14010     register ssize_t
14011       i;
14012 
14013     struct PackageInfo
14014       *info;
14015 
14016     SV
14017       *perl_exception,
14018       *reference;  /* reference is the SV* of ref=SvIV(reference) */
14019 
14020     PERL_UNUSED_VAR(ref);
14021     PERL_UNUSED_VAR(ix);
14022     exception=AcquireExceptionInfo();
14023     perl_exception=newSVpv("",0);
14024     if (sv_isobject(ST(0)) == 0)
14025       {
14026         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14027           PackageName);
14028         goto PerlException;
14029       }
14030     reference=SvRV(ST(0));
14031     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14032     if (items == 2)
14033       SetAttribute(aTHX_ info,image,"size",ST(1),exception);
14034     else
14035       for (i=2; i < items; i+=2)
14036         SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
14037 
14038   PerlException:
14039     InheritPerlException(exception,perl_exception);
14040     exception=DestroyExceptionInfo(exception);
14041     sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
14042     SvPOK_on(perl_exception);
14043     ST(0)=sv_2mortal(perl_exception);
14044     XSRETURN(1);
14045   }
14046 
14047 #
14048 ###############################################################################
14049 #                                                                             #
14050 #                                                                             #
14051 #                                                                             #
14052 #   S e t P i x e l                                                           #
14053 #                                                                             #
14054 #                                                                             #
14055 #                                                                             #
14056 ###############################################################################
14057 #
14058 #
14059 void
SetPixel(ref,...)14060 SetPixel(ref,...)
14061   Image::Magick ref=NO_INIT
14062   ALIAS:
14063     setpixel = 1
14064     setPixel = 2
14065   PPCODE:
14066   {
14067     AV
14068       *av;
14069 
14070     char
14071       *attribute;
14072 
14073     ChannelType
14074       channel,
14075       channel_mask;
14076 
14077     ExceptionInfo
14078       *exception;
14079 
14080     Image
14081       *image;
14082 
14083     MagickBooleanType
14084       normalize;
14085 
14086     RectangleInfo
14087       region;
14088 
14089     register ssize_t
14090       i;
14091 
14092     register Quantum
14093       *q;
14094 
14095     ssize_t
14096       option;
14097 
14098     struct PackageInfo
14099       *info;
14100 
14101     SV
14102       *perl_exception,
14103       *reference;  /* reference is the SV* of ref=SvIV(reference) */
14104 
14105     PERL_UNUSED_VAR(ref);
14106     PERL_UNUSED_VAR(ix);
14107     exception=AcquireExceptionInfo();
14108     perl_exception=newSVpv("",0);
14109     reference=SvRV(ST(0));
14110     av=(AV *) reference;
14111     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
14112       exception);
14113     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14114     if (image == (Image *) NULL)
14115       {
14116         ThrowPerlException(exception,OptionError,"NoImagesDefined",
14117           PackageName);
14118         goto PerlException;
14119       }
14120     av=(AV *) NULL;
14121     normalize=MagickTrue;
14122     region.x=0;
14123     region.y=0;
14124     region.width=image->columns;
14125     region.height=1;
14126     if (items == 1)
14127       (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
14128     channel=DefaultChannels;
14129     for (i=2; i < items; i+=2)
14130     {
14131       attribute=(char *) SvPV(ST(i-1),na);
14132       switch (*attribute)
14133       {
14134         case 'C':
14135         case 'c':
14136         {
14137           if (LocaleCompare(attribute,"channel") == 0)
14138             {
14139               ssize_t
14140                 option;
14141 
14142               option=ParseChannelOption(SvPV(ST(i),na));
14143               if (option < 0)
14144                 {
14145                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
14146                     SvPV(ST(i),na));
14147                   return;
14148                 }
14149               channel=(ChannelType) option;
14150               break;
14151             }
14152           if (LocaleCompare(attribute,"color") == 0)
14153             {
14154               if (SvTYPE(ST(i)) != SVt_RV)
14155                 {
14156                   char
14157                     message[MagickPathExtent];
14158 
14159                   (void) FormatLocaleString(message,MagickPathExtent,
14160                     "invalid %.60s value",attribute);
14161                   ThrowPerlException(exception,OptionError,message,
14162                     SvPV(ST(i),na));
14163                 }
14164               av=(AV *) SvRV(ST(i));
14165               break;
14166             }
14167           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14168             attribute);
14169           break;
14170         }
14171         case 'g':
14172         case 'G':
14173         {
14174           if (LocaleCompare(attribute,"geometry") == 0)
14175             {
14176               (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
14177               break;
14178             }
14179           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14180             attribute);
14181           break;
14182         }
14183         case 'N':
14184         case 'n':
14185         {
14186           if (LocaleCompare(attribute,"normalize") == 0)
14187             {
14188               option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14189                 SvPV(ST(i),na));
14190               if (option < 0)
14191                 {
14192                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
14193                     SvPV(ST(i),na));
14194                   break;
14195                 }
14196              normalize=option != 0 ? MagickTrue : MagickFalse;
14197              break;
14198             }
14199           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14200             attribute);
14201           break;
14202         }
14203         case 'x':
14204         case 'X':
14205         {
14206           if (LocaleCompare(attribute,"x") == 0)
14207             {
14208               region.x=SvIV(ST(i));
14209               break;
14210             }
14211           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14212             attribute);
14213           break;
14214         }
14215         case 'y':
14216         case 'Y':
14217         {
14218           if (LocaleCompare(attribute,"y") == 0)
14219             {
14220               region.y=SvIV(ST(i));
14221               break;
14222             }
14223           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14224             attribute);
14225           break;
14226         }
14227         default:
14228         {
14229           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14230             attribute);
14231           break;
14232         }
14233       }
14234     }
14235     (void) SetImageStorageClass(image,DirectClass,exception);
14236     channel_mask=SetImageChannelMask(image,channel);
14237     q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
14238     if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14239         (SvTYPE(av) != SVt_PVAV))
14240       PUSHs(&sv_undef);
14241     else
14242       {
14243         double
14244           scale;
14245 
14246         register ssize_t
14247           i;
14248 
14249         i=0;
14250         scale=1.0;
14251         if (normalize != MagickFalse)
14252           scale=QuantumRange;
14253         if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14254             (i <= av_len(av)))
14255           {
14256             SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14257               av_fetch(av,i,0)))),q);
14258             i++;
14259           }
14260         if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14261             (i <= av_len(av)))
14262           {
14263             SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14264               av_fetch(av,i,0)))),q);
14265             i++;
14266           }
14267         if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14268             (i <= av_len(av)))
14269           {
14270             SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14271               av_fetch(av,i,0)))),q);
14272             i++;
14273           }
14274         if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14275             (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14276           {
14277             SetPixelBlack(image,ClampToQuantum(scale*
14278               SvNV(*(av_fetch(av,i,0)))),q);
14279             i++;
14280           }
14281         if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14282             (i <= av_len(av)))
14283           {
14284             SetPixelAlpha(image,ClampToQuantum(scale*
14285               SvNV(*(av_fetch(av,i,0)))),q);
14286             i++;
14287           }
14288         (void) SyncAuthenticPixels(image,exception);
14289       }
14290     (void) SetImageChannelMask(image,channel_mask);
14291 
14292   PerlException:
14293     InheritPerlException(exception,perl_exception);
14294     exception=DestroyExceptionInfo(exception);
14295     SvREFCNT_dec(perl_exception);
14296   }
14297 
14298 #
14299 ###############################################################################
14300 #                                                                             #
14301 #                                                                             #
14302 #                                                                             #
14303 #   S e t P i x e l s                                                         #
14304 #                                                                             #
14305 #                                                                             #
14306 #                                                                             #
14307 ###############################################################################
14308 #
14309 #
14310 void
SetPixels(ref,...)14311 SetPixels(ref,...)
14312   Image::Magick ref=NO_INIT
14313   ALIAS:
14314     setpixels = 1
14315     setPixels = 2
14316   PPCODE:
14317   {
14318     AV
14319       *av;
14320 
14321     char
14322       *attribute;
14323 
14324     ChannelType
14325       channel,
14326       channel_mask;
14327 
14328     ExceptionInfo
14329       *exception;
14330 
14331     Image
14332       *image;
14333 
14334     RectangleInfo
14335       region;
14336 
14337     register ssize_t
14338       i;
14339 
14340     register Quantum
14341       *q;
14342 
14343     struct PackageInfo
14344       *info;
14345 
14346     SV
14347       *perl_exception,
14348       *reference;  /* reference is the SV* of ref=SvIV(reference) */
14349 
14350     PERL_UNUSED_VAR(ref);
14351     PERL_UNUSED_VAR(ix);
14352     exception=AcquireExceptionInfo();
14353     perl_exception=newSVpv("",0);
14354     reference=SvRV(ST(0));
14355     av=(AV *) reference;
14356     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
14357       exception);
14358     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14359     if (image == (Image *) NULL)
14360       {
14361         ThrowPerlException(exception,OptionError,"NoImagesDefined",
14362           PackageName);
14363         goto PerlException;
14364       }
14365     av=(AV *) NULL;
14366     region.x=0;
14367     region.y=0;
14368     region.width=image->columns;
14369     region.height=1;
14370     if (items == 1)
14371       (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
14372     channel=DefaultChannels;
14373     for (i=2; i < items; i+=2)
14374     {
14375       attribute=(char *) SvPV(ST(i-1),na);
14376       switch (*attribute)
14377       {
14378         case 'C':
14379         case 'c':
14380         {
14381           if (LocaleCompare(attribute,"channel") == 0)
14382             {
14383               ssize_t
14384                 option;
14385 
14386               option=ParseChannelOption(SvPV(ST(i),na));
14387               if (option < 0)
14388                 {
14389                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
14390                     SvPV(ST(i),na));
14391                   return;
14392                 }
14393               channel=(ChannelType) option;
14394               break;
14395             }
14396           if (LocaleCompare(attribute,"color") == 0)
14397             {
14398               if (SvTYPE(ST(i)) != SVt_RV)
14399                 {
14400                   char
14401                     message[MagickPathExtent];
14402 
14403                   (void) FormatLocaleString(message,MagickPathExtent,
14404                     "invalid %.60s value",attribute);
14405                   ThrowPerlException(exception,OptionError,message,
14406                     SvPV(ST(i),na));
14407                 }
14408               av=(AV *) SvRV(ST(i));
14409               break;
14410             }
14411           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14412             attribute);
14413           break;
14414         }
14415         case 'g':
14416         case 'G':
14417         {
14418           if (LocaleCompare(attribute,"geometry") == 0)
14419             {
14420               (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
14421               break;
14422             }
14423           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14424             attribute);
14425           break;
14426         }
14427         case 'h':
14428         case 'H':
14429         {
14430           if (LocaleCompare(attribute,"height") == 0)
14431             {
14432               region.height=SvIV(ST(i));
14433               break;
14434             }
14435           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14436             attribute);
14437           break;
14438         }
14439         case 'w':
14440         case 'W':
14441         {
14442           if (LocaleCompare(attribute,"width") == 0)
14443             {
14444               region.width=SvIV(ST(i));
14445               break;
14446             }
14447           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14448             attribute);
14449           break;
14450         }
14451         case 'x':
14452         case 'X':
14453         {
14454           if (LocaleCompare(attribute,"x") == 0)
14455             {
14456               region.x=SvIV(ST(i));
14457               break;
14458             }
14459           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14460             attribute);
14461           break;
14462         }
14463         case 'y':
14464         case 'Y':
14465         {
14466           if (LocaleCompare(attribute,"y") == 0)
14467             {
14468               region.y=SvIV(ST(i));
14469               break;
14470             }
14471           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14472             attribute);
14473           break;
14474         }
14475         default:
14476         {
14477           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14478             attribute);
14479           break;
14480         }
14481       }
14482     }
14483     (void) SetImageStorageClass(image,DirectClass,exception);
14484     channel_mask=SetImageChannelMask(image,channel);
14485     q=GetAuthenticPixels(image,region.x,region.y,region.width,region.height,
14486       exception);
14487     if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14488         (SvTYPE(av) != SVt_PVAV))
14489       PUSHs(&sv_undef);
14490     else
14491       {
14492         double
14493           scale;
14494 
14495         register ssize_t
14496           i,
14497           n,
14498           number_pixels;
14499 
14500         i=0;
14501         n=0;
14502         scale=(double) QuantumRange;
14503         number_pixels=region.width*region.height;
14504         while ((n < number_pixels) && (i < av_len(av)))
14505         {
14506           if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14507               (i <= av_len(av)))
14508             {
14509               SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14510                 av_fetch(av,i,0)))),q);
14511               i++;
14512             }
14513           if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14514               (i <= av_len(av)))
14515             {
14516               SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14517                 av_fetch(av,i,0)))),q);
14518               i++;
14519             }
14520           if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14521               (i <= av_len(av)))
14522             {
14523               SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14524                 av_fetch(av,i,0)))),q);
14525               i++;
14526             }
14527           if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14528               (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14529             {
14530              SetPixelBlack(image,ClampToQuantum(scale*
14531                 SvNV(*(av_fetch(av,i,0)))),q);
14532               i++;
14533             }
14534           if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14535               (i <= av_len(av)))
14536             {
14537               SetPixelAlpha(image,ClampToQuantum(scale*
14538                 SvNV(*(av_fetch(av,i,0)))),q);
14539               i++;
14540             }
14541          	n++;
14542          	q+=image->number_channels;
14543         }
14544         (void) SyncAuthenticPixels(image,exception);
14545       }
14546     (void) SetImageChannelMask(image,channel_mask);
14547 
14548   PerlException:
14549     InheritPerlException(exception,perl_exception);
14550     exception=DestroyExceptionInfo(exception);
14551     SvREFCNT_dec(perl_exception);
14552   }
14553 
14554 #
14555 ###############################################################################
14556 #                                                                             #
14557 #                                                                             #
14558 #                                                                             #
14559 #   S m u s h                                                                 #
14560 #                                                                             #
14561 #                                                                             #
14562 #                                                                             #
14563 ###############################################################################
14564 #
14565 #
14566 void
Smush(ref,...)14567 Smush(ref,...)
14568   Image::Magick ref=NO_INIT
14569   ALIAS:
14570     SmushImage  = 1
14571     smush       = 2
14572     smushimage  = 3
14573   PPCODE:
14574   {
14575     AV
14576       *av;
14577 
14578     char
14579       *attribute;
14580 
14581     ExceptionInfo
14582       *exception;
14583 
14584     HV
14585       *hv;
14586 
14587     Image
14588       *image;
14589 
14590     register ssize_t
14591       i;
14592 
14593     ssize_t
14594       offset,
14595       stack;
14596 
14597     struct PackageInfo
14598       *info;
14599 
14600     SV
14601       *av_reference,
14602       *perl_exception,
14603       *reference,
14604       *rv,
14605       *sv;
14606 
14607     PERL_UNUSED_VAR(ref);
14608     PERL_UNUSED_VAR(ix);
14609     exception=AcquireExceptionInfo();
14610     perl_exception=newSVpv("",0);
14611     sv=NULL;
14612     attribute=NULL;
14613     av=NULL;
14614     if (sv_isobject(ST(0)) == 0)
14615       {
14616         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14617           PackageName);
14618         goto PerlException;
14619       }
14620     reference=SvRV(ST(0));
14621     hv=SvSTASH(reference);
14622     av=newAV();
14623     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14624     SvREFCNT_dec(av);
14625     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14626     if (image == (Image *) NULL)
14627       {
14628         ThrowPerlException(exception,OptionError,"NoImagesDefined",
14629           PackageName);
14630         goto PerlException;
14631       }
14632     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14633     /*
14634       Get options.
14635     */
14636     offset=0;
14637     stack=MagickTrue;
14638     for (i=2; i < items; i+=2)
14639     {
14640       attribute=(char *) SvPV(ST(i-1),na);
14641       switch (*attribute)
14642       {
14643         case 'O':
14644         case 'o':
14645         {
14646           if (LocaleCompare(attribute,"offset") == 0)
14647             {
14648               offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14649               break;
14650             }
14651           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14652             attribute);
14653           break;
14654         }
14655         case 'S':
14656         case 's':
14657         {
14658           if (LocaleCompare(attribute,"stack") == 0)
14659             {
14660               stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14661                 SvPV(ST(i),na));
14662               if (stack < 0)
14663                 {
14664                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
14665                     SvPV(ST(i),na));
14666                   return;
14667                 }
14668               break;
14669             }
14670           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14671             attribute);
14672           break;
14673         }
14674         default:
14675         {
14676           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14677             attribute);
14678           break;
14679         }
14680       }
14681     }
14682     image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14683       exception);
14684     if (image == (Image *) NULL)
14685       goto PerlException;
14686     for ( ; image; image=image->next)
14687     {
14688       AddImageToRegistry(sv,image);
14689       rv=newRV(sv);
14690       av_push(av,sv_bless(rv,hv));
14691       SvREFCNT_dec(sv);
14692     }
14693     exception=DestroyExceptionInfo(exception);
14694     ST(0)=av_reference;
14695     SvREFCNT_dec(perl_exception);
14696     XSRETURN(1);
14697 
14698   PerlException:
14699     InheritPerlException(exception,perl_exception);
14700     exception=DestroyExceptionInfo(exception);
14701     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14702     SvPOK_on(perl_exception);
14703     ST(0)=sv_2mortal(perl_exception);
14704     XSRETURN(1);
14705   }
14706 
14707 #
14708 ###############################################################################
14709 #                                                                             #
14710 #                                                                             #
14711 #                                                                             #
14712 #   S t a t i s t i c s                                                       #
14713 #                                                                             #
14714 #                                                                             #
14715 #                                                                             #
14716 ###############################################################################
14717 #
14718 #
14719 void
Statistics(ref,...)14720 Statistics(ref,...)
14721   Image::Magick ref=NO_INIT
14722   ALIAS:
14723     StatisticsImage = 1
14724     statistics      = 2
14725     statisticsimage = 3
14726   PPCODE:
14727   {
14728 #define ChannelStatistics(channel) \
14729 { \
14730   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
14731     (double) channel_statistics[channel].depth); \
14732   PUSHs(sv_2mortal(newSVpv(message,0))); \
14733   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
14734     channel_statistics[channel].minima/QuantumRange); \
14735   PUSHs(sv_2mortal(newSVpv(message,0))); \
14736   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
14737     channel_statistics[channel].maxima/QuantumRange); \
14738   PUSHs(sv_2mortal(newSVpv(message,0))); \
14739   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
14740     channel_statistics[channel].mean/QuantumRange); \
14741   PUSHs(sv_2mortal(newSVpv(message,0))); \
14742   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
14743     channel_statistics[channel].standard_deviation/QuantumRange); \
14744   PUSHs(sv_2mortal(newSVpv(message,0))); \
14745   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
14746     channel_statistics[channel].kurtosis); \
14747   PUSHs(sv_2mortal(newSVpv(message,0))); \
14748   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
14749     channel_statistics[channel].skewness); \
14750   PUSHs(sv_2mortal(newSVpv(message,0))); \
14751   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
14752     channel_statistics[channel].entropy); \
14753   PUSHs(sv_2mortal(newSVpv(message,0))); \
14754 }
14755 
14756     AV
14757       *av;
14758 
14759     char
14760       message[MagickPathExtent];
14761 
14762     ChannelStatistics
14763       *channel_statistics;
14764 
14765     ExceptionInfo
14766       *exception;
14767 
14768     Image
14769       *image;
14770 
14771     ssize_t
14772       count;
14773 
14774     struct PackageInfo
14775       *info;
14776 
14777     SV
14778       *perl_exception,
14779       *reference;
14780 
14781     PERL_UNUSED_VAR(ref);
14782     PERL_UNUSED_VAR(ix);
14783     exception=AcquireExceptionInfo();
14784     perl_exception=newSVpv("",0);
14785     av=NULL;
14786     if (sv_isobject(ST(0)) == 0)
14787       {
14788         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14789           PackageName);
14790         goto PerlException;
14791       }
14792     reference=SvRV(ST(0));
14793     av=newAV();
14794     SvREFCNT_dec(av);
14795     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14796     if (image == (Image *) NULL)
14797       {
14798         ThrowPerlException(exception,OptionError,"NoImagesDefined",
14799           PackageName);
14800         goto PerlException;
14801       }
14802     count=0;
14803     for ( ; image; image=image->next)
14804     {
14805       register size_t
14806         i;
14807 
14808       channel_statistics=GetImageStatistics(image,exception);
14809       if (channel_statistics == (ChannelStatistics *) NULL)
14810         continue;
14811       count++;
14812       for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
14813       {
14814         PixelChannel channel=GetPixelChannelChannel(image,i);
14815         PixelTrait traits=GetPixelChannelTraits(image,channel);
14816         if (traits == UndefinedPixelTrait)
14817           continue;
14818         EXTEND(sp,8*(i+1)*count);
14819         ChannelStatistics(channel);
14820       }
14821       EXTEND(sp,8*(i+1)*count);
14822       ChannelStatistics(CompositePixelChannel);
14823       channel_statistics=(ChannelStatistics *)
14824         RelinquishMagickMemory(channel_statistics);
14825     }
14826 
14827   PerlException:
14828     InheritPerlException(exception,perl_exception);
14829     exception=DestroyExceptionInfo(exception);
14830     SvREFCNT_dec(perl_exception);
14831   }
14832 
14833 #
14834 ###############################################################################
14835 #                                                                             #
14836 #                                                                             #
14837 #                                                                             #
14838 #   S y n c A u t h e n t i c P i x e l s                                     #
14839 #                                                                             #
14840 #                                                                             #
14841 #                                                                             #
14842 ###############################################################################
14843 #
14844 #
14845 void
SyncAuthenticPixels(ref,...)14846 SyncAuthenticPixels(ref,...)
14847   Image::Magick ref = NO_INIT
14848   ALIAS:
14849     Syncauthenticpixels = 1
14850     SyncImagePixels = 2
14851     syncimagepixels = 3
14852   CODE:
14853   {
14854     ExceptionInfo
14855       *exception;
14856 
14857     Image
14858       *image;
14859 
14860     MagickBooleanType
14861       status;
14862 
14863     struct PackageInfo
14864       *info;
14865 
14866     SV
14867       *perl_exception,
14868       *reference;
14869 
14870     PERL_UNUSED_VAR(ref);
14871     PERL_UNUSED_VAR(ix);
14872     exception=AcquireExceptionInfo();
14873     perl_exception=newSVpv("",0);
14874     if (sv_isobject(ST(0)) == 0)
14875       {
14876         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14877           PackageName);
14878         goto PerlException;
14879       }
14880 
14881     reference=SvRV(ST(0));
14882     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14883     if (image == (Image *) NULL)
14884       {
14885         ThrowPerlException(exception,OptionError,"NoImagesDefined",
14886           PackageName);
14887         goto PerlException;
14888       }
14889 
14890     status=SyncAuthenticPixels(image,exception);
14891     if (status != MagickFalse)
14892       return;
14893 
14894   PerlException:
14895     InheritPerlException(exception,perl_exception);
14896     exception=DestroyExceptionInfo(exception);
14897     SvREFCNT_dec(perl_exception);  /* throw away all errors */
14898   }
14899 
14900 #
14901 ###############################################################################
14902 #                                                                             #
14903 #                                                                             #
14904 #                                                                             #
14905 #   W r i t e                                                                 #
14906 #                                                                             #
14907 #                                                                             #
14908 #                                                                             #
14909 ###############################################################################
14910 #
14911 #
14912 void
Write(ref,...)14913 Write(ref,...)
14914   Image::Magick ref=NO_INIT
14915   ALIAS:
14916     WriteImage    = 1
14917     write         = 2
14918     writeimage    = 3
14919   PPCODE:
14920   {
14921     char
14922       filename[MagickPathExtent];
14923 
14924     ExceptionInfo
14925       *exception;
14926 
14927     Image
14928       *image,
14929       *next;
14930 
14931     register ssize_t
14932       i;
14933 
14934     ssize_t
14935       number_images,
14936       scene;
14937 
14938     struct PackageInfo
14939       *info,
14940       *package_info;
14941 
14942     SV
14943       *perl_exception,
14944       *reference;
14945 
14946     PERL_UNUSED_VAR(ref);
14947     PERL_UNUSED_VAR(ix);
14948     exception=AcquireExceptionInfo();
14949     perl_exception=newSVpv("",0);
14950     number_images=0;
14951     package_info=(struct PackageInfo *) NULL;
14952     if (sv_isobject(ST(0)) == 0)
14953       {
14954         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14955           PackageName);
14956         goto PerlException;
14957       }
14958     reference=SvRV(ST(0));
14959     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14960     if (image == (Image *) NULL)
14961       {
14962         ThrowPerlException(exception,OptionError,"NoImagesDefined",
14963           PackageName);
14964         goto PerlException;
14965       }
14966     scene=0;
14967     for (next=image; next; next=next->next)
14968       next->scene=scene++;
14969     package_info=ClonePackageInfo(info,exception);
14970     if (items == 2)
14971       SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14972     else
14973       if (items > 2)
14974         for (i=2; i < items; i+=2)
14975           SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14976             exception);
14977     (void) CopyMagickString(filename,package_info->image_info->filename,
14978       MagickPathExtent);
14979     for (next=image; next; next=next->next)
14980       (void) CopyMagickString(next->filename,filename,MagickPathExtent);
14981     *package_info->image_info->magick='\0';
14982     SetImageInfo(package_info->image_info,(unsigned int)
14983       GetImageListLength(image),exception);
14984     for (next=image; next; next=next->next)
14985     {
14986       (void) WriteImage(package_info->image_info,next,exception);
14987       number_images++;
14988       if (package_info->image_info->adjoin)
14989         break;
14990     }
14991 
14992   PerlException:
14993     if (package_info != (struct PackageInfo *) NULL)
14994       DestroyPackageInfo(package_info);
14995     InheritPerlException(exception,perl_exception);
14996     exception=DestroyExceptionInfo(exception);
14997     sv_setiv(perl_exception,(IV) number_images);
14998     SvPOK_on(perl_exception);
14999     ST(0)=sv_2mortal(perl_exception);
15000     XSRETURN(1);
15001   }
15002