]> granicus.if.org Git - imagemagick/blob - PerlMagick/quantum/quantum.xs.in
(no commit message)
[imagemagick] / PerlMagick / quantum / quantum.xs.in
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 %                              John Cristy                                    %
23 %                             February 1997                                   %
24 %                                                                             %
25 %                                                                             %
26 %  Copyright 1999-2013 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 %    http://www.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 \f
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 "EXTERN.h"
57 #include "perl.h"
58 #include "XSUB.h"
59 #include <math.h>
60 #include <MagickCore/MagickCore.h>
61 #undef tainted
62
63 #if defined(__cplusplus) || defined(c_plusplus)
64 }
65 #endif
66 \f
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 MaxArguments  33
78 #ifndef na
79 #define na  PL_na
80 #endif
81 #define NumberOf(array)  (sizeof(array)/sizeof(*array))
82 #define PackageName   "Image::Magick::@MAGICK_ABI_NAME@"
83 #if PERL_VERSION <= 6
84 #define PerlIO  FILE
85 #define PerlIO_importFILE(f, fl)  (f)
86 #define PerlIO_findFILE(f)  NULL
87 #endif
88 #ifndef sv_undef
89 #define sv_undef  PL_sv_undef
90 #endif
91
92 #define AddImageToRegistry(sv,image) \
93 { \
94   if (magick_registry != (SplayTreeInfo *) NULL) \
95     { \
96       (void) AddValueToSplayTree(magick_registry,image,image); \
97       (sv)=newSViv(PTR2IV(image)); \
98     } \
99 }
100
101 #define DeleteImageFromRegistry(reference,image) \
102 { \
103   if (magick_registry != (SplayTreeInfo *) NULL) \
104     { \
105       if (GetImageReferenceCount(image) == 1) \
106        (void) DeleteNodeByValueFromSplayTree(magick_registry,image); \
107       image=DestroyImage(image); \
108       sv_setiv(reference,0); \
109     } \
110 }
111
112 #define InheritPerlException(exception,perl_exception) \
113 { \
114   char \
115     message[MaxTextExtent]; \
116  \
117   if ((exception)->severity != UndefinedException) \
118     { \
119       (void) FormatLocaleString(message,MaxTextExtent,"Exception %d: %s%s%s%s",\
120         (exception)->severity, (exception)->reason ? \
121         GetLocaleExceptionMessage((exception)->severity,(exception)->reason) : \
122         "Unknown", (exception)->description ? " (" : "", \
123         (exception)->description ? GetLocaleExceptionMessage( \
124         (exception)->severity,(exception)->description) : "", \
125         (exception)->description ? ")" : ""); \
126       if ((perl_exception) != (SV *) NULL) \
127         { \
128           if (SvCUR(perl_exception)) \
129             sv_catpv(perl_exception,"\n"); \
130           sv_catpv(perl_exception,message); \
131         } \
132     } \
133 }
134
135 #define ThrowPerlException(exception,severity,tag,reason) \
136   (void) ThrowMagickException(exception,GetMagickModule(),severity, \
137     tag,"`%s'",reason); \
138 \f
139 /*
140   Typedef and structure declarations.
141 */
142 typedef enum
143 {
144   ArrayReference = (~0),
145   RealReference = (~0)-1,
146   FileReference = (~0)-2,
147   ImageReference = (~0)-3,
148   IntegerReference = (~0)-4,
149   StringReference = (~0)-5
150 } MagickReference;
151
152 typedef struct _Arguments
153 {
154   const char
155     *method;
156
157   ssize_t
158     type;
159 } Arguments;
160
161 struct ArgumentList
162 {
163   ssize_t
164     integer_reference;
165
166   double
167     real_reference;
168
169   const char
170     *string_reference;
171
172   Image
173     *image_reference;
174
175   SV
176     *array_reference;
177
178   FILE
179     *file_reference;
180
181   size_t
182     length;
183 };
184
185 struct PackageInfo
186 {
187   ImageInfo
188     *image_info;
189 };
190
191 typedef void
192   *Image__Magick__@MAGICK_ABI_SUFFIX@;  /* data type for the Image::Magick::@MAGICK_ABI_NAME@ package */
193 \f
194 /*
195   Static declarations.
196 */
197 static struct
198   Methods
199   {
200     const char
201       *name;
202
203     Arguments
204       arguments[MaxArguments];
205   } Methods[] =
206   {
207     { "Comment", { {"comment", StringReference} } },
208     { "Label", { {"label", StringReference} } },
209     { "AddNoise", { {"noise", MagickNoiseOptions}, {"attenuate", RealReference},
210       {"channel", MagickChannelOptions} } },
211     { "Colorize", { {"fill", StringReference}, {"blend", StringReference} } },
212     { "Border", { {"geometry", StringReference}, {"width", IntegerReference},
213       {"height", IntegerReference}, {"fill", StringReference},
214       {"bordercolor", StringReference}, {"color", StringReference},
215       {"compose", MagickComposeOptions} } },
216     { "Blur", { {"geometry", StringReference}, {"radius", RealReference},
217       {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
218     { "Chop", { {"geometry", StringReference}, {"width", IntegerReference},
219       {"height", IntegerReference}, {"x", IntegerReference},
220       {"y", IntegerReference} } },
221     { "Crop", { {"geometry", StringReference}, {"width", IntegerReference},
222       {"height", IntegerReference}, {"x", IntegerReference},
223       {"y", IntegerReference}, {"fuzz", StringReference},
224       {"gravity", MagickGravityOptions} } },
225     { "Despeckle", },
226     { "Edge", { {"radius", RealReference} } },
227     { "Emboss", { {"geometry", StringReference}, {"radius", RealReference},
228       {"sigma", RealReference} } },
229     { "Enhance", },
230     { "Flip", },
231     { "Flop", },
232     { "Frame", { {"geometry", StringReference}, {"width", IntegerReference},
233       {"height", IntegerReference}, {"inner", IntegerReference},
234       {"outer", IntegerReference}, {"fill", StringReference},
235       {"color", StringReference}, {"compose", MagickComposeOptions} } },
236     { "Implode", { {"amount", RealReference},
237       {"interpolate", MagickInterpolateOptions} } },
238     { "Magnify", },
239     { "MedianFilter", { {"geometry", StringReference},
240       {"width", IntegerReference}, {"height", IntegerReference},
241       {"channel", MagickChannelOptions} } },
242     { "Minify", },
243     { "OilPaint", { {"radius", RealReference}, {"sigma", RealReference} } },
244     { "ReduceNoise", { {"geometry", StringReference},
245       {"width", IntegerReference},{"height", IntegerReference},
246       {"channel", MagickChannelOptions} } },
247     { "Roll", { {"geometry", StringReference}, {"x", IntegerReference},
248       {"y", IntegerReference} } },
249     { "Rotate", { {"degrees", RealReference}, 
250       {"background", StringReference} } },
251     { "Sample", { {"geometry", StringReference}, {"width", IntegerReference},
252       {"height", IntegerReference} } },
253     { "Scale", { {"geometry", StringReference}, {"width", IntegerReference},
254       {"height", IntegerReference} } },
255     { "Shade", { {"geometry", StringReference}, {"azimuth", RealReference},
256       {"elevation", RealReference}, {"gray", MagickBooleanOptions} } },
257     { "Sharpen", { {"geometry", StringReference}, {"radius", RealReference},
258       {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
259     { "Shear", { {"geometry", StringReference}, {"x", RealReference},
260       {"y", RealReference}, { "fill", StringReference},
261       {"color", StringReference} } },
262     { "Spread", { {"radius", RealReference},
263       {"interpolate", MagickInterpolateOptions} } },
264     { "Swirl", { {"degrees", RealReference},
265       {"interpolate", MagickInterpolateOptions} } },
266     { "Resize", { {"geometry", StringReference}, {"width", IntegerReference},
267       {"height", IntegerReference}, {"filter", MagickFilterOptions},
268       {"support", StringReference } } },
269     { "Zoom", { {"geometry", StringReference}, {"width", IntegerReference},
270       {"height", IntegerReference}, {"filter", MagickFilterOptions},
271       {"support", RealReference } } },
272     { "Annotate", { {"text", StringReference}, {"font", StringReference},
273       {"pointsize", RealReference}, {"density", StringReference},
274       {"undercolor", StringReference}, {"stroke", StringReference},
275       {"fill", StringReference}, {"geometry", StringReference},
276       {"sans", StringReference}, {"x", RealReference},
277       {"y", RealReference}, {"gravity", MagickGravityOptions},
278       {"translate", StringReference}, {"scale", StringReference},
279       {"rotate", RealReference}, {"skewX", RealReference},
280       {"skewY", RealReference}, {"strokewidth", RealReference},
281       {"antialias", MagickBooleanOptions}, {"family", StringReference},
282       {"style", MagickStyleOptions}, {"stretch", MagickStretchOptions},
283       {"weight", IntegerReference}, {"align", MagickAlignOptions},
284       {"encoding", StringReference}, {"affine", ArrayReference},
285       {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
286       {"tile", ImageReference}, {"kerning", RealReference},
287       {"interline-spacing", RealReference},
288       {"interword-spacing", RealReference},
289       {"direction", MagickDirectionOptions} } },
290     { "ColorFloodfill", { {"geometry", StringReference},
291       {"x", IntegerReference}, {"y", IntegerReference},
292       {"fill", StringReference}, {"bordercolor", StringReference},
293       {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
294     { "Composite", { {"image", ImageReference},
295       {"compose", MagickComposeOptions}, {"geometry", StringReference},
296       {"x", IntegerReference}, {"y", IntegerReference},
297       {"gravity", MagickGravityOptions}, {"opacity", StringReference},
298       {"tile", MagickBooleanOptions}, {"rotate", RealReference},
299       {"color", StringReference}, {"mask", ImageReference},
300       {"channel", MagickChannelOptions},
301       {"interpolate", MagickInterpolateOptions}, {"args", StringReference},
302       {"blend", StringReference}, {"crop-to-self", MagickBooleanOptions} } },
303     { "Contrast", { {"sharpen", MagickBooleanOptions} } },
304     { "CycleColormap", { {"display", IntegerReference} } },
305     { "Draw", { {"primitive", MagickPrimitiveOptions},
306       {"points", StringReference}, {"method", MagickMethodOptions},
307       {"stroke", StringReference}, {"fill", StringReference},
308       {"strokewidth", RealReference}, {"font", StringReference},
309       {"bordercolor", StringReference}, {"x", RealReference},
310       {"y", RealReference}, {"translate", StringReference},
311       {"scale", StringReference}, {"rotate", RealReference},
312       {"skewX", RealReference}, {"skewY", RealReference},
313       {"tile", ImageReference}, {"pointsize", RealReference},
314       {"antialias", MagickBooleanOptions}, {"density", StringReference},
315       {"linewidth", RealReference}, {"affine", ArrayReference},
316       {"stroke-dashoffset", RealReference},
317       {"stroke-dasharray", ArrayReference},
318       {"interpolate", MagickInterpolateOptions},
319       {"origin", StringReference}, {"text", StringReference},
320       {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
321       {"vector-graphics", StringReference}, {"kerning", RealReference},
322       {"interline-spacing", RealReference},
323       {"interword-spacing", RealReference},
324       {"direction", MagickDirectionOptions} } },
325     { "Equalize", { {"channel", MagickChannelOptions} } },
326     { "Gamma", { {"gamma", StringReference}, {"channel", MagickChannelOptions},
327       {"red", RealReference}, {"green", RealReference},
328       {"blue", RealReference} } },
329     { "Map", { {"image", ImageReference},
330       {"dither-method", MagickDitherOptions} } },
331     { "MatteFloodfill", { {"geometry", StringReference},
332       {"x", IntegerReference}, {"y", IntegerReference},
333       {"opacity", StringReference}, {"bordercolor", StringReference},
334       {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
335     { "Modulate", { {"factor", StringReference}, {"hue", RealReference},
336       {"saturation", RealReference}, {"whiteness", RealReference},
337       {"brightness", RealReference}, {"lightness", RealReference},
338       {"blackness", RealReference} } },
339     { "Negate", { {"gray", MagickBooleanOptions},
340       {"channel", MagickChannelOptions} } },
341     { "Normalize", { {"channel", MagickChannelOptions} } },
342     { "NumberColors", },
343     { "Opaque", { {"color", StringReference}, {"fill", StringReference},
344       {"fuzz", StringReference}, {"channel", MagickChannelOptions},
345       {"invert", MagickBooleanOptions} } },
346     { "Quantize", { {"colors", IntegerReference},
347       {"treedepth", IntegerReference}, {"colorspace", MagickColorspaceOptions},
348       {"dither", MagickDitherOptions}, {"measure", MagickBooleanOptions},
349       {"global", MagickBooleanOptions}, {"transparent-color", StringReference},
350       {"dither-method", MagickDitherOptions} } },
351     { "Raise", { {"geometry", StringReference}, {"width", IntegerReference},
352       {"height", IntegerReference}, {"raise", MagickBooleanOptions} } },
353     { "Segment", { {"geometry", StringReference},
354       {"cluster-threshold", RealReference},
355       {"smoothing-threshold", RealReference},
356       {"colorspace", MagickColorspaceOptions},
357       {"verbose", MagickBooleanOptions} } },
358     { "Signature", },
359     { "Solarize", { {"geometry", StringReference},
360       {"threshold", StringReference} } },
361     { "Sync", },
362     { "Texture", { {"texture", ImageReference} } },
363     { "Evaluate", { {"value", RealReference},
364       {"operator", MagickEvaluateOptions},
365       {"channel", MagickChannelOptions} } },
366     { "Transparent", { {"color", StringReference}, {"opacity", StringReference},
367       {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
368     { "Threshold", { {"threshold", StringReference},
369       {"channel", MagickChannelOptions} } },
370     { "Charcoal", { {"geometry", StringReference}, {"radius", RealReference},
371       {"sigma", RealReference} } },
372     { "Trim", { {"fuzz", StringReference} } },
373     { "Wave", { {"geometry", StringReference}, {"amplitude", RealReference},
374       {"wavelength", RealReference},
375       {"interpolate", MagickInterpolateOptions} } },
376     { "Separate", { {"channel", MagickChannelOptions} } },
377     { "Condense", },
378     { "Stereo", { {"image", ImageReference}, {"x", IntegerReference},
379       {"y", IntegerReference} } },
380     { "Stegano", { {"image", ImageReference}, {"offset", IntegerReference} } },
381     { "Deconstruct", },
382     { "GaussianBlur", { {"geometry", StringReference},
383       {"radius", RealReference}, {"sigma", RealReference},
384       {"channel", MagickChannelOptions} } },
385     { "Convolve", { {"coefficients", ArrayReference},
386       {"channel", MagickChannelOptions}, {"bias", StringReference},
387       {"kernel", StringReference} } },
388     { "Profile", { {"name", StringReference}, {"profile", StringReference},
389       { "rendering-intent", MagickIntentOptions},
390       { "black-point-compensation", MagickBooleanOptions} } },
391     { "UnsharpMask", { {"geometry", StringReference},
392       {"radius", RealReference}, {"sigma", RealReference},
393       {"gain", RealReference}, {"threshold", RealReference},
394       {"channel", MagickChannelOptions} } },
395     { "MotionBlur", { {"geometry", StringReference},
396       {"radius", RealReference}, {"sigma", RealReference},
397       {"angle", RealReference}, {"channel", MagickChannelOptions} } },
398     { "OrderedDither", { {"threshold", StringReference},
399       {"channel", MagickChannelOptions} } },
400     { "Shave", { {"geometry", StringReference}, {"width", IntegerReference},
401       {"height", IntegerReference} } },
402     { "Level", { {"levels", StringReference}, {"black-point", RealReference},
403       {"white-point", RealReference}, {"gamma", RealReference},
404       {"channel", MagickChannelOptions}, {"level", StringReference} } },
405     { "Clip", { {"id", StringReference}, {"inside", MagickBooleanOptions} } },
406     { "AffineTransform", { {"affine", ArrayReference},
407       {"translate", StringReference}, {"scale", StringReference},
408       {"rotate", RealReference}, {"skewX", RealReference},
409       {"skewY", RealReference}, {"interpolate", MagickInterpolateOptions},
410       {"background", StringReference} } },
411     { "Difference", { {"image", ImageReference}, {"fuzz", StringReference} } },
412     { "AdaptiveThreshold", { {"geometry", StringReference},
413       {"width", IntegerReference}, {"height", IntegerReference} } },
414     { "Resample", { {"density", StringReference}, {"x", RealReference},
415       {"y", RealReference}, {"filter", MagickFilterOptions},
416       {"support", RealReference } } },
417     { "Describe", { {"file", FileReference} } },
418     { "BlackThreshold", { {"threshold", StringReference},
419       {"channel", MagickChannelOptions} } },
420     { "WhiteThreshold", { {"threshold", StringReference},
421       {"channel", MagickChannelOptions} } },
422     { "RadialBlur", { {"geometry", StringReference}, {"angle", RealReference},
423       {"channel", MagickChannelOptions} } },
424     { "Thumbnail", { {"geometry", StringReference}, {"width", IntegerReference},
425       {"height", IntegerReference} } },
426     { "Strip", },
427     { "Tint", { {"fill", StringReference}, {"blend", StringReference} } },
428     { "Channel", { {"channel", MagickChannelOptions} } },
429     { "Splice", { {"geometry", StringReference}, {"width", IntegerReference},
430       {"height", IntegerReference}, {"x", IntegerReference},
431       {"y", IntegerReference}, {"fuzz", StringReference},
432       {"background", StringReference}, {"gravity", MagickGravityOptions} } },
433     { "Posterize", { {"levels", IntegerReference},
434       {"dither", MagickBooleanOptions} } },
435     { "Shadow", { {"geometry", StringReference}, {"alpha", RealReference},
436       {"sigma", RealReference}, {"x", IntegerReference},
437       {"y", IntegerReference} } },
438     { "Identify", { {"file", FileReference}, {"features", StringReference},
439       {"unique", MagickBooleanOptions} } },
440     { "SepiaTone", { {"threshold", RealReference} } },
441     { "SigmoidalContrast", { {"geometry", StringReference},
442       {"contrast", RealReference}, {"mid-point", RealReference},
443       {"channel", MagickChannelOptions}, {"sharpen", MagickBooleanOptions} } },
444     { "Extent", { {"geometry", StringReference}, {"width", IntegerReference},
445       {"height", IntegerReference}, {"x", IntegerReference},
446       {"y", IntegerReference}, {"fuzz", StringReference},
447       {"background", StringReference}, {"gravity", MagickGravityOptions} } },
448     { "Vignette", { {"geometry", StringReference}, {"radius", RealReference},
449       {"sigma", RealReference}, {"x", IntegerReference},
450       {"y", IntegerReference}, {"background", StringReference} } },
451     { "ContrastStretch", { {"levels", StringReference},
452       {"black-point", RealReference},{"white-point", RealReference},
453       {"channel", MagickChannelOptions} } },
454     { "Sans0", },
455     { "Sans1", },
456     { "AdaptiveSharpen", { {"geometry", StringReference},
457       {"radius", RealReference}, {"sigma", RealReference},
458       {"bias", RealReference}, {"channel", MagickChannelOptions} } },
459     { "Transpose", },
460     { "Transverse", },
461     { "AutoOrient", },
462     { "AdaptiveBlur", { {"geometry", StringReference},
463       {"radius", RealReference}, {"sigma", RealReference},
464       {"channel", MagickChannelOptions} } },
465     { "Sketch", { {"geometry", StringReference},
466       {"radius", RealReference}, {"sigma", RealReference},
467       {"angle", RealReference} } },
468     { "UniqueColors", },
469     { "AdaptiveResize", { {"geometry", StringReference},
470       {"width", IntegerReference}, {"height", IntegerReference},
471       {"filter", MagickFilterOptions}, {"support", StringReference },
472       {"blur", RealReference } } },
473     { "ClipMask", { {"mask", ImageReference} } },
474     { "LinearStretch", { {"levels", StringReference},
475       {"black-point", RealReference},{"white-point", RealReference} } },
476     { "ColorMatrix", { {"matrix", ArrayReference} } },
477     { "Mask", { {"mask", ImageReference} } },
478     { "Polaroid", { {"caption", StringReference}, {"angle", RealReference},
479       {"font", StringReference}, {"stroke", StringReference},
480       {"fill", StringReference}, {"strokewidth", RealReference},
481       {"pointsize", RealReference}, {"gravity", MagickGravityOptions},
482       {"background", StringReference},
483       {"interpolate", MagickInterpolateOptions} } },
484     { "FloodfillPaint", { {"geometry", StringReference},
485       {"x", IntegerReference}, {"y", IntegerReference},
486       {"fill", StringReference}, {"bordercolor", StringReference},
487       {"fuzz", StringReference}, {"channel", MagickChannelOptions},
488       {"invert", MagickBooleanOptions} } },
489     { "Distort", { {"points", ArrayReference}, {"method", MagickDistortOptions},
490       {"virtual-pixel", MagickVirtualPixelOptions},
491       {"best-fit", MagickBooleanOptions} } },
492     { "Clut", { {"image", ImageReference},
493       {"interpolate", MagickInterpolateOptions},
494       {"channel", MagickChannelOptions} } },
495     { "LiquidRescale", { {"geometry", StringReference},
496       {"width", IntegerReference}, {"height", IntegerReference},
497       {"delta-x", RealReference}, {"rigidity", RealReference } } },
498     { "Encipher", { {"passphrase", StringReference} } },
499     { "Decipher", { {"passphrase", StringReference} } },
500     { "Deskew", { {"geometry", StringReference},
501       {"threshold", StringReference} } },
502     { "Remap", { {"image", ImageReference},
503       {"dither-method", MagickDitherOptions} } },
504     { "SparseColor", { {"points", ArrayReference},
505       {"method", MagickSparseColorOptions},
506       {"virtual-pixel", MagickVirtualPixelOptions},
507       {"channel", MagickChannelOptions} } },
508     { "Function", { {"parameters", ArrayReference},
509       {"function", MagickFunctionOptions},
510       {"virtual-pixel", MagickVirtualPixelOptions} } },
511     { "SelectiveBlur", { {"geometry", StringReference},
512       {"radius", RealReference}, {"sigma", RealReference},
513       {"threshold", RealReference}, {"channel", MagickChannelOptions} } },
514     { "HaldClut", { {"image", ImageReference},
515       {"channel", MagickChannelOptions} } },
516     { "BlueShift", { {"factor", StringReference} } },
517     { "ForwardFourierTransform", { {"magnitude", MagickBooleanOptions} } },
518     { "InverseFourierTransform", { {"magnitude", MagickBooleanOptions} } },
519     { "ColorDecisionList", {
520       {"color-correction-collection", StringReference} } },
521     { "AutoGamma", { {"channel", MagickChannelOptions} } },
522     { "AutoLevel", { {"channel", MagickChannelOptions} } },
523     { "LevelColors", { {"invert", MagickBooleanOptions},
524       {"black-point", StringReference}, {"white-point", StringReference},
525       {"channel", MagickChannelOptions}, {"invert", MagickBooleanOptions} } },
526     { "Clamp", { {"channel", MagickChannelOptions} } },
527     { "BrightnessContrast", { {"levels", StringReference},
528       {"brightness", RealReference},{"contrast", RealReference},
529       {"channel", MagickChannelOptions} } },
530     { "Morphology", { {"kernel", StringReference},
531       {"channel", MagickChannelOptions}, {"method", MagickMorphologyOptions},
532       {"iterations", IntegerReference} } },
533     { "Sans", { {"matrix", ArrayReference} } },
534     { "Color", { {"color", StringReference} } },
535     { "Mode", { {"geometry", StringReference},
536       {"width", IntegerReference},{"height", IntegerReference},
537       {"channel", MagickChannelOptions} } },
538     { "Statistic", { {"geometry", StringReference},
539       {"width", IntegerReference},{"height", IntegerReference},
540       {"channel", MagickChannelOptions}, {"type", MagickStatisticOptions} } },
541     { "Perceptible", { {"epsilon", RealReference},
542       {"channel", MagickChannelOptions} } },
543     { "Poly", { {"terms", ArrayReference},
544       {"channel", MagickChannelOptions} } }
545   };
546
547 static SplayTreeInfo
548   *magick_registry = (SplayTreeInfo *) NULL;
549 \f
550 /*
551   Forward declarations.
552 */
553 static Image
554   *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
555
556 static ssize_t
557   strEQcase(const char *,const char *);
558 \f
559 /*
560 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
561 %                                                                             %
562 %                                                                             %
563 %                                                                             %
564 %   C l o n e P a c k a g e I n f o                                           %
565 %                                                                             %
566 %                                                                             %
567 %                                                                             %
568 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
569 %
570 %  ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
571 %  a new one.
572 %
573 %  The format of the ClonePackageInfo routine is:
574 %
575 %      struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
576 %        exception)
577 %
578 %  A description of each parameter follows:
579 %
580 %    o info: a structure of type info.
581 %
582 %    o exception: Return any errors or warnings in this structure.
583 %
584 */
585 static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
586   ExceptionInfo *exception)
587 {
588   struct PackageInfo
589     *clone_info;
590
591   clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
592   if (clone_info == (struct PackageInfo *) NULL)
593     {
594       ThrowPerlException(exception,ResourceLimitError,
595         "UnableToClonePackageInfo",PackageName);
596       return((struct PackageInfo *) NULL);
597     }
598   if (info == (struct PackageInfo *) NULL)
599     {
600       clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
601       return(clone_info);
602     }
603   *clone_info=(*info);
604   clone_info->image_info=CloneImageInfo(info->image_info);
605   return(clone_info);
606 }
607 \f
608 /*
609 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
610 %                                                                             %
611 %                                                                             %
612 %                                                                             %
613 %   c o n s t a n t                                                           %
614 %                                                                             %
615 %                                                                             %
616 %                                                                             %
617 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
618 %
619 %  constant() returns a double value for the specified name.
620 %
621 %  The format of the constant routine is:
622 %
623 %      double constant(char *name,ssize_t sans)
624 %
625 %  A description of each parameter follows:
626 %
627 %    o value: Method constant returns a double value for the specified name.
628 %
629 %    o name: The name of the constant.
630 %
631 %    o sans: This integer value is not used.
632 %
633 */
634 static double constant(char *name,ssize_t sans)
635 {
636   (void) sans;
637   errno=0;
638   switch (*name)
639   {
640     case 'B':
641     {
642       if (strEQ(name,"BlobError"))
643         return(BlobError);
644       if (strEQ(name,"BlobWarning"))
645         return(BlobWarning);
646       break;
647     }
648     case 'C':
649     {
650       if (strEQ(name,"CacheError"))
651         return(CacheError);
652       if (strEQ(name,"CacheWarning"))
653         return(CacheWarning);
654       if (strEQ(name,"CoderError"))
655         return(CoderError);
656       if (strEQ(name,"CoderWarning"))
657         return(CoderWarning);
658       if (strEQ(name,"ConfigureError"))
659         return(ConfigureError);
660       if (strEQ(name,"ConfigureWarning"))
661         return(ConfigureWarning);
662       if (strEQ(name,"CorruptImageError"))
663         return(CorruptImageError);
664       if (strEQ(name,"CorruptImageWarning"))
665         return(CorruptImageWarning);
666       break;
667     }
668     case 'D':
669     {
670       if (strEQ(name,"DelegateError"))
671         return(DelegateError);
672       if (strEQ(name,"DelegateWarning"))
673         return(DelegateWarning);
674       if (strEQ(name,"DrawError"))
675         return(DrawError);
676       if (strEQ(name,"DrawWarning"))
677         return(DrawWarning);
678       break;
679     }
680     case 'E':
681     {
682       if (strEQ(name,"ErrorException"))
683         return(ErrorException);
684       if (strEQ(name,"ExceptionError"))
685         return(CoderError);
686       if (strEQ(name,"ExceptionWarning"))
687         return(CoderWarning);
688       break;
689     }
690     case 'F':
691     {
692       if (strEQ(name,"FatalErrorException"))
693         return(FatalErrorException);
694       if (strEQ(name,"FileOpenError"))
695         return(FileOpenError);
696       if (strEQ(name,"FileOpenWarning"))
697         return(FileOpenWarning);
698       break;
699     }
700     case 'I':
701     {
702       if (strEQ(name,"ImageError"))
703         return(ImageError);
704       if (strEQ(name,"ImageWarning"))
705         return(ImageWarning);
706       break;
707     }
708     case 'M':
709     {
710       if (strEQ(name,"MaxRGB"))
711         return(QuantumRange);
712       if (strEQ(name,"MissingDelegateError"))
713         return(MissingDelegateError);
714       if (strEQ(name,"MissingDelegateWarning"))
715         return(MissingDelegateWarning);
716       if (strEQ(name,"ModuleError"))
717         return(ModuleError);
718       if (strEQ(name,"ModuleWarning"))
719         return(ModuleWarning);
720       break;
721     }
722     case 'O':
723     {
724       if (strEQ(name,"Opaque"))
725         return(OpaqueAlpha);
726       if (strEQ(name,"OptionError"))
727         return(OptionError);
728       if (strEQ(name,"OptionWarning"))
729         return(OptionWarning);
730       break;
731     }
732     case 'Q':
733     {
734       if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
735         return(MAGICKCORE_QUANTUM_DEPTH);
736       if (strEQ(name,"QuantumDepth"))
737         return(MAGICKCORE_QUANTUM_DEPTH);
738       if (strEQ(name,"QuantumRange"))
739         return(QuantumRange);
740       break;
741     }
742     case 'R':
743     {
744       if (strEQ(name,"ResourceLimitError"))
745         return(ResourceLimitError);
746       if (strEQ(name,"ResourceLimitWarning"))
747         return(ResourceLimitWarning);
748       if (strEQ(name,"RegistryError"))
749         return(RegistryError);
750       if (strEQ(name,"RegistryWarning"))
751         return(RegistryWarning);
752       break;
753     }
754     case 'S':
755     {
756       if (strEQ(name,"StreamError"))
757         return(StreamError);
758       if (strEQ(name,"StreamWarning"))
759         return(StreamWarning);
760       if (strEQ(name,"Success"))
761         return(0);
762       break;
763     }
764     case 'T':
765     {
766       if (strEQ(name,"Transparent"))
767         return(TransparentAlpha);
768       if (strEQ(name,"TypeError"))
769         return(TypeError);
770       if (strEQ(name,"TypeWarning"))
771         return(TypeWarning);
772       break;
773     }
774     case 'W':
775     {
776       if (strEQ(name,"WarningException"))
777         return(WarningException);
778       break;
779     }
780     case 'X':
781     {
782       if (strEQ(name,"XServerError"))
783         return(XServerError);
784       if (strEQ(name,"XServerWarning"))
785         return(XServerWarning);
786       break;
787     }
788   }
789   errno=EINVAL;
790   return(0);
791 }
792 \f
793 /*
794 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
795 %                                                                             %
796 %                                                                             %
797 %                                                                             %
798 %   D e s t r o y P a c k a g e I n f o                                       %
799 %                                                                             %
800 %                                                                             %
801 %                                                                             %
802 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
803 %
804 %  Method DestroyPackageInfo frees a previously created info structure.
805 %
806 %  The format of the DestroyPackageInfo routine is:
807 %
808 %      DestroyPackageInfo(struct PackageInfo *info)
809 %
810 %  A description of each parameter follows:
811 %
812 %    o info: a structure of type info.
813 %
814 */
815 static void DestroyPackageInfo(struct PackageInfo *info)
816 {
817   info->image_info=DestroyImageInfo(info->image_info);
818   info=(struct PackageInfo *) RelinquishMagickMemory(info);
819 }
820 \f
821 /*
822 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
823 %                                                                             %
824 %                                                                             %
825 %                                                                             %
826 %   G e t L i s t                                                             %
827 %                                                                             %
828 %                                                                             %
829 %                                                                             %
830 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
831 %
832 %  Method GetList is recursively called by SetupList to traverse the
833 %  Image__Magick reference.  If building an reference_vector (see SetupList),
834 %  *current is the current position in *reference_vector and *last is the final
835 %  entry in *reference_vector.
836 %
837 %  The format of the GetList routine is:
838 %
839 %      GetList(info)
840 %
841 %  A description of each parameter follows:
842 %
843 %    o info: a structure of type info.
844 %
845 */
846 static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
847   ssize_t *current,ssize_t *last,ExceptionInfo *exception)
848 {
849   Image
850     *image;
851
852   if (reference == (SV *) NULL)
853     return(NULL);
854   switch (SvTYPE(reference))
855   {
856     case SVt_PVAV:
857     {
858       AV
859         *av;
860
861       Image
862         *head,
863         *previous;
864
865       register ssize_t
866         i;
867
868       ssize_t
869         n;
870
871       /*
872         Array of images.
873       */
874       previous=(Image *) NULL;
875       head=(Image *) NULL;
876       av=(AV *) reference;
877       n=av_len(av);
878       for (i=0; i <= n; i++)
879       {
880         SV
881           **rv;
882
883         rv=av_fetch(av,i,0);
884         if (rv && *rv && sv_isobject(*rv))
885           {
886             image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
887               exception);
888             if (image == (Image *) NULL)
889               continue;
890             if (image == previous)
891               {
892                 image=CloneImage(image,0,0,MagickTrue,exception);
893                 if (image == (Image *) NULL)
894                   return(NULL);
895               }
896             image->previous=previous;
897             *(previous ? &previous->next : &head)=image;
898             for (previous=image; previous->next; previous=previous->next) ;
899           }
900       }
901       return(head);
902     }
903     case SVt_PVMG:
904     {
905       /*
906         Blessed scalar, one image.
907       */
908       image=INT2PTR(Image *,SvIV(reference));
909       if (image == (Image *) NULL)
910         return(NULL);
911       image->previous=(Image *) NULL;
912       image->next=(Image *) NULL;
913       if (reference_vector)
914         {
915           if (*current == *last)
916             {
917               *last+=256;
918               if (*reference_vector == (SV **) NULL)
919                 *reference_vector=(SV **) AcquireQuantumMemory(*last,
920                   sizeof(*reference_vector));
921               else
922                 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
923                   *last,sizeof(*reference_vector));
924             }
925           if (*reference_vector == (SV **) NULL)
926             {
927               ThrowPerlException(exception,ResourceLimitError,
928                 "MemoryAllocationFailed",PackageName);
929               return((Image *) NULL);
930             }
931           (*reference_vector)[*current]=reference;
932           (*reference_vector)[++(*current)]=NULL;
933         }
934       return(image);
935     }
936     default:
937       break;
938   }
939   (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
940     (double) SvTYPE(reference));
941   return((Image *) NULL);
942 }
943 \f
944 /*
945 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
946 %                                                                             %
947 %                                                                             %
948 %                                                                             %
949 %   G e t P a c k a g e I n f o                                               %
950 %                                                                             %
951 %                                                                             %
952 %                                                                             %
953 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
954 %
955 %  Method GetPackageInfo looks up or creates an info structure for the given
956 %  Image__Magick reference.  If it does create a new one, the information in
957 %  package_info is used to initialize it.
958 %
959 %  The format of the GetPackageInfo routine is:
960 %
961 %      struct PackageInfo *GetPackageInfo(void *reference,
962 %        struct PackageInfo *package_info,ExceptionInfo *exception)
963 %
964 %  A description of each parameter follows:
965 %
966 %    o info: a structure of type info.
967 %
968 %    o exception: Return any errors or warnings in this structure.
969 %
970 */
971 static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
972   struct PackageInfo *package_info,ExceptionInfo *exception)
973 {
974   char
975     message[MaxTextExtent];
976
977   struct PackageInfo
978     *clone_info;
979
980   SV
981     *sv;
982
983   (void) FormatLocaleString(message,MaxTextExtent,"%s::package%s%p",
984     PackageName,XS_VERSION,reference);
985   sv=perl_get_sv(message,(TRUE | 0x02));
986   if (sv == (SV *) NULL)
987     {
988       ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
989         message);
990       return(package_info);
991     }
992   if (SvREFCNT(sv) == 0)
993     (void) SvREFCNT_inc(sv);
994   if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
995     return(clone_info);
996   clone_info=ClonePackageInfo(package_info,exception);
997   sv_setiv(sv,PTR2IV(clone_info));
998   return(clone_info);
999 }
1000 \f
1001 /*
1002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1003 %                                                                             %
1004 %                                                                             %
1005 %                                                                             %
1006 %   S e t A t t r i b u t e                                                   %
1007 %                                                                             %
1008 %                                                                             %
1009 %                                                                             %
1010 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1011 %
1012 %  SetAttribute() sets the attribute to the value in sval.  This can change
1013 %  either or both of image or info.
1014 %
1015 %  The format of the SetAttribute routine is:
1016 %
1017 %      SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1018 %        SV *sval,ExceptionInfo *exception)
1019 %
1020 %  A description of each parameter follows:
1021 %
1022 %    o list: a list of strings.
1023 %
1024 %    o string: a character string.
1025 %
1026 */
1027
1028 static double SiPrefixToDoubleInterval(const char *string,const double interval)
1029 {
1030   char
1031     *q;
1032
1033   double
1034     value;
1035
1036   value=InterpretSiPrefixValue(string,&q);
1037   if (*q == '%')
1038     value*=interval/100.0;
1039   return(value);
1040 }
1041
1042 static inline double StringToDouble(const char *string,char **sentinal)
1043 {
1044   return(InterpretLocaleValue(string,sentinal));
1045 }
1046
1047 static double StringToDoubleInterval(const char *string,const double interval)
1048 {
1049   char
1050     *q;
1051
1052   double
1053     value;
1054
1055   value=InterpretLocaleValue(string,&q);
1056   if (*q == '%')
1057     value*=interval/100.0;
1058   return(value);
1059 }
1060
1061 static inline ssize_t StringToLong(const char *value)
1062 {
1063   return(strtol(value,(char **) NULL,10));
1064 }
1065
1066 static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1067   const char *attribute,SV *sval,ExceptionInfo *exception)
1068 {
1069   GeometryInfo
1070     geometry_info;
1071
1072   long
1073     x,
1074     y;
1075
1076   PixelInfo
1077     pixel;
1078
1079   MagickStatusType
1080     flags;
1081
1082   PixelInfo
1083     *color,
1084     target_color;
1085
1086   ssize_t
1087     sp;
1088
1089   switch (*attribute)
1090   {
1091     case 'A':
1092     case 'a':
1093     {
1094       if (LocaleCompare(attribute,"adjoin") == 0)
1095         {
1096           sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1097             SvPV(sval,na)) : SvIV(sval);
1098           if (sp < 0)
1099             {
1100               ThrowPerlException(exception,OptionError,"UnrecognizedType",
1101                 SvPV(sval,na));
1102               break;
1103             }
1104           if (info)
1105             info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1106           break;
1107         }
1108       if (LocaleCompare(attribute,"alpha") == 0)
1109         {
1110           sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1111             MagickFalse,SvPV(sval,na)) : SvIV(sval);
1112           if (sp < 0)
1113             {
1114               ThrowPerlException(exception,OptionError,"UnrecognizedType",
1115                 SvPV(sval,na));
1116               break;
1117             }
1118           for ( ; image; image=image->next)
1119             (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1120               exception);
1121           break;
1122         }
1123       if (LocaleCompare(attribute,"antialias") == 0)
1124         {
1125           sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1126             SvPV(sval,na)) : SvIV(sval);
1127           if (sp < 0)
1128             {
1129               ThrowPerlException(exception,OptionError,"UnrecognizedType",
1130                 SvPV(sval,na));
1131               break;
1132             }
1133           if (info)
1134             info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1135           break;
1136         }
1137       if (LocaleCompare(attribute,"area-limit") == 0)
1138         {
1139           MagickSizeType
1140             limit;
1141
1142           limit=MagickResourceInfinity;
1143           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1144             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1145               100.0);
1146           (void) SetMagickResourceLimit(AreaResource,limit);
1147           break;
1148         }
1149       if (LocaleCompare(attribute,"attenuate") == 0)
1150         {
1151           if (info)
1152             (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1153           break;
1154         }
1155       if (LocaleCompare(attribute,"authenticate") == 0)
1156         {
1157           if (info)
1158             SetImageOption(info->image_info,attribute,SvPV(sval,na));
1159           break;
1160         }
1161       if (info)
1162         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1163       for ( ; image; image=image->next)
1164         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1165       break;
1166     }
1167     case 'B':
1168     case 'b':
1169     {
1170       if (LocaleCompare(attribute,"background") == 0)
1171         {
1172           (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1173             exception);
1174           if (info)
1175             info->image_info->background_color=target_color;
1176           for ( ; image; image=image->next)
1177             image->background_color=target_color;
1178           break;
1179         }
1180       if (LocaleCompare(attribute,"blue-primary") == 0)
1181         {
1182           for ( ; image; image=image->next)
1183           {
1184             flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1185             image->chromaticity.blue_primary.x=geometry_info.rho;
1186             image->chromaticity.blue_primary.y=geometry_info.sigma;
1187             if ((flags & SigmaValue) == 0)
1188               image->chromaticity.blue_primary.y=
1189                 image->chromaticity.blue_primary.x;
1190           }
1191           break;
1192         }
1193       if (LocaleCompare(attribute,"bordercolor") == 0)
1194         {
1195           (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1196             exception);
1197           if (info)
1198             info->image_info->border_color=target_color;
1199           for ( ; image; image=image->next)
1200             image->border_color=target_color;
1201           break;
1202         }
1203       if (info)
1204         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1205       for ( ; image; image=image->next)
1206         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1207       break;
1208     }
1209     case 'C':
1210     case 'c':
1211     {
1212       if (LocaleCompare(attribute,"cache-threshold") == 0)
1213         {
1214           (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1215             SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1216           (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1217             (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1218           break;
1219         }
1220       if (LocaleCompare(attribute,"clip-mask") == 0)
1221         {
1222           Image
1223             *clip_mask;
1224
1225           clip_mask=(Image *) NULL;
1226           if (SvPOK(sval))
1227             clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1228           for ( ; image; image=image->next)
1229             SetImageMask(image,clip_mask,exception);
1230           break;
1231         }
1232       if (LocaleNCompare(attribute,"colormap",8) == 0)
1233         {
1234           for ( ; image; image=image->next)
1235           {
1236             int
1237               items;
1238
1239             long
1240               i;
1241
1242             if (image->storage_class == DirectClass)
1243               continue;
1244             i=0;
1245             items=sscanf(attribute,"%*[^[][%ld",&i);
1246             (void) items;
1247             if (i > (ssize_t) image->colors)
1248               i%=image->colors;
1249             if ((strchr(SvPV(sval,na),',') == 0) ||
1250                 (strchr(SvPV(sval,na),')') != 0))
1251               QueryColorCompliance(SvPV(sval,na),AllCompliance,
1252                 image->colormap+i,exception);
1253             else
1254               {
1255                 color=image->colormap+i;
1256                 pixel.red=color->red;
1257                 pixel.green=color->green;
1258                 pixel.blue=color->blue;
1259                 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1260                 pixel.red=geometry_info.rho;
1261                 pixel.green=geometry_info.sigma;
1262                 pixel.blue=geometry_info.xi;
1263                 color->red=ClampToQuantum(pixel.red);
1264                 color->green=ClampToQuantum(pixel.green);
1265                 color->blue=ClampToQuantum(pixel.blue);
1266               }
1267           }
1268           break;
1269         }
1270       if (LocaleCompare(attribute,"colorspace") == 0)
1271         {
1272           sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1273             MagickFalse,SvPV(sval,na)) : SvIV(sval);
1274           if (sp < 0)
1275             {
1276               ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1277                 SvPV(sval,na));
1278               break;
1279             }
1280           for ( ; image; image=image->next)
1281             (void) TransformImageColorspace(image,(ColorspaceType) sp,
1282               exception);
1283           break;
1284         }
1285       if (LocaleCompare(attribute,"comment") == 0)
1286         {
1287           for ( ; image; image=image->next)
1288             (void) SetImageProperty(image,"Comment",InterpretImageProperties(
1289               info ? info->image_info : (ImageInfo *) NULL,image,
1290               SvPV(sval,na),exception),exception);
1291           break;
1292         }
1293       if (LocaleCompare(attribute,"compression") == 0)
1294         {
1295           sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1296             MagickFalse,SvPV(sval,na)) : SvIV(sval);
1297           if (sp < 0)
1298             {
1299               ThrowPerlException(exception,OptionError,
1300                 "UnrecognizedImageCompression",SvPV(sval,na));
1301               break;
1302             }
1303           if (info)
1304             info->image_info->compression=(CompressionType) sp;
1305           for ( ; image; image=image->next)
1306             image->compression=(CompressionType) sp;
1307           break;
1308         }
1309       if (info)
1310         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1311       for ( ; image; image=image->next)
1312         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1313       break;
1314     }
1315     case 'D':
1316     case 'd':
1317     {
1318       if (LocaleCompare(attribute,"debug") == 0)
1319         {
1320           SetLogEventMask(SvPV(sval,na));
1321           break;
1322         }
1323       if (LocaleCompare(attribute,"delay") == 0)
1324         {
1325           flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1326           for ( ; image; image=image->next)
1327           {
1328             image->delay=(size_t) floor(geometry_info.rho+0.5);
1329             if ((flags & SigmaValue) != 0)
1330               image->ticks_per_second=(ssize_t)
1331                 floor(geometry_info.sigma+0.5);
1332           }
1333           break;
1334         }
1335       if (LocaleCompare(attribute,"disk-limit") == 0)
1336         {
1337           MagickSizeType
1338             limit;
1339
1340           limit=MagickResourceInfinity;
1341           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1342             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1343               100.0);
1344           (void) SetMagickResourceLimit(DiskResource,limit);
1345           break;
1346         }
1347       if (LocaleCompare(attribute,"density") == 0)
1348         {
1349           if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1350             {
1351               ThrowPerlException(exception,OptionError,"MissingGeometry",
1352                 SvPV(sval,na));
1353               break;
1354             }
1355           if (info)
1356             (void) CloneString(&info->image_info->density,SvPV(sval,na));
1357           for ( ; image; image=image->next)
1358           {
1359             flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1360             image->resolution.x=geometry_info.rho;
1361             image->resolution.y=geometry_info.sigma;
1362             if ((flags & SigmaValue) == 0)
1363               image->resolution.y=image->resolution.x;
1364           }
1365           break;
1366         }
1367       if (LocaleCompare(attribute,"depth") == 0)
1368         {
1369           if (info)
1370             info->image_info->depth=SvIV(sval);
1371           for ( ; image; image=image->next)
1372             (void) SetImageDepth(image,SvIV(sval),exception);
1373           break;
1374         }
1375       if (LocaleCompare(attribute,"dispose") == 0)
1376         {
1377           sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1378             SvPV(sval,na)) : SvIV(sval);
1379           if (sp < 0)
1380             {
1381               ThrowPerlException(exception,OptionError,
1382                 "UnrecognizedDisposeMethod",SvPV(sval,na));
1383               break;
1384             }
1385           for ( ; image; image=image->next)
1386             image->dispose=(DisposeType) sp;
1387           break;
1388         }
1389       if (LocaleCompare(attribute,"dither") == 0)
1390         {
1391           if (info)
1392             {
1393               sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1394                 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1395               if (sp < 0)
1396                 {
1397                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
1398                     SvPV(sval,na));
1399                   break;
1400                 }
1401               info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1402             }
1403           break;
1404         }
1405       if (LocaleCompare(attribute,"display") == 0)
1406         {
1407           display:
1408           if (info)
1409             (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1410           break;
1411         }
1412       if (info)
1413         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1414       for ( ; image; image=image->next)
1415         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1416       break;
1417     }
1418     case 'E':
1419     case 'e':
1420     {
1421       if (LocaleCompare(attribute,"endian") == 0)
1422         {
1423           sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1424             SvPV(sval,na)) : SvIV(sval);
1425           if (sp < 0)
1426             {
1427               ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1428                 SvPV(sval,na));
1429               break;
1430             }
1431           if (info)
1432             info->image_info->endian=(EndianType) sp;
1433           for ( ; image; image=image->next)
1434             image->endian=(EndianType) sp;
1435           break;
1436         }
1437       if (LocaleCompare(attribute,"extract") == 0)
1438         {
1439           /*
1440             Set image extract geometry.
1441           */
1442           (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1443           break;
1444         }
1445       if (info)
1446         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1447       for ( ; image; image=image->next)
1448         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1449       break;
1450     }
1451     case 'F':
1452     case 'f':
1453     {
1454       if (LocaleCompare(attribute,"filename") == 0)
1455         {
1456           if (info)
1457             (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
1458               MaxTextExtent);
1459           for ( ; image; image=image->next)
1460             (void) CopyMagickString(image->filename,SvPV(sval,na),
1461               MaxTextExtent);
1462           break;
1463         }
1464       if (LocaleCompare(attribute,"file") == 0)
1465         {
1466           FILE
1467             *file;
1468
1469           PerlIO
1470             *io_info;
1471
1472           if (info == (struct PackageInfo *) NULL)
1473             break;
1474           io_info=IoIFP(sv_2io(sval));
1475           if (io_info == (PerlIO *) NULL)
1476             {
1477               ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1478                 PackageName);
1479               break;
1480             }
1481           file=PerlIO_findFILE(io_info);
1482           if (file == (FILE *) NULL)
1483             {
1484               ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1485                 PackageName);
1486               break;
1487             }
1488           SetImageInfoFile(info->image_info,file);
1489           break;
1490         }
1491       if (LocaleCompare(attribute,"fill") == 0)
1492         {
1493           if (info)
1494             (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1495           break;
1496         }
1497       if (LocaleCompare(attribute,"font") == 0)
1498         {
1499           if (info)
1500             (void) CloneString(&info->image_info->font,SvPV(sval,na));
1501           break;
1502         }
1503       if (LocaleCompare(attribute,"foreground") == 0)
1504         break;
1505       if (LocaleCompare(attribute,"fuzz") == 0)
1506         {
1507           if (info)
1508             info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1509               QuantumRange+1.0);
1510           for ( ; image; image=image->next)
1511             image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1512               QuantumRange+1.0);
1513           break;
1514         }
1515       if (info)
1516         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1517       for ( ; image; image=image->next)
1518         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1519       break;
1520     }
1521     case 'G':
1522     case 'g':
1523     {
1524       if (LocaleCompare(attribute,"gamma") == 0)
1525         {
1526           for ( ; image; image=image->next)
1527             image->gamma=SvNV(sval);
1528           break;
1529         }
1530       if (LocaleCompare(attribute,"gravity") == 0)
1531         {
1532           sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1533             SvPV(sval,na)) : SvIV(sval);
1534           if (sp < 0)
1535             {
1536               ThrowPerlException(exception,OptionError,
1537                 "UnrecognizedGravityType",SvPV(sval,na));
1538               break;
1539             }
1540           if (info)
1541             SetImageOption(info->image_info,attribute,SvPV(sval,na));
1542           for ( ; image; image=image->next)
1543             image->gravity=(GravityType) sp;
1544           break;
1545         }
1546       if (LocaleCompare(attribute,"green-primary") == 0)
1547         {
1548           for ( ; image; image=image->next)
1549           {
1550             flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1551             image->chromaticity.green_primary.x=geometry_info.rho;
1552             image->chromaticity.green_primary.y=geometry_info.sigma;
1553             if ((flags & SigmaValue) == 0)
1554               image->chromaticity.green_primary.y=
1555                 image->chromaticity.green_primary.x;
1556           }
1557           break;
1558         }
1559       if (info)
1560         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1561       for ( ; image; image=image->next)
1562         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1563       break;
1564     }
1565     case 'I':
1566     case 'i':
1567     {
1568       if (LocaleNCompare(attribute,"index",5) == 0)
1569         {
1570           int
1571             items;
1572
1573           long
1574             index;
1575
1576           register Quantum
1577             *q;
1578
1579           CacheView
1580             *image_view;
1581
1582           for ( ; image; image=image->next)
1583           {
1584             if (image->storage_class != PseudoClass)
1585               continue;
1586             x=0;
1587             y=0;
1588             items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1589             (void) items;
1590             image_view=AcquireAuthenticCacheView(image,exception);
1591             q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1592             if (q != (Quantum *) NULL)
1593               {
1594                 items=sscanf(SvPV(sval,na),"%ld",&index);
1595                 if ((index >= 0) && (index < (ssize_t) image->colors))
1596                   SetPixelIndex(image,index,q);
1597                 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1598               }
1599             image_view=DestroyCacheView(image_view);
1600           }
1601           break;
1602         }
1603       if (LocaleCompare(attribute,"iterations") == 0)
1604         {
1605   iterations:
1606           for ( ; image; image=image->next)
1607             image->iterations=SvIV(sval);
1608           break;
1609         }
1610       if (LocaleCompare(attribute,"interlace") == 0)
1611         {
1612           sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1613             MagickFalse,SvPV(sval,na)) : SvIV(sval);
1614           if (sp < 0)
1615             {
1616               ThrowPerlException(exception,OptionError,
1617                 "UnrecognizedInterlaceType",SvPV(sval,na));
1618               break;
1619             }
1620           if (info)
1621             info->image_info->interlace=(InterlaceType) sp;
1622           for ( ; image; image=image->next)
1623             image->interlace=(InterlaceType) sp;
1624           break;
1625         }
1626       if (info)
1627         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1628       for ( ; image; image=image->next)
1629         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1630       break;
1631     }
1632     case 'L':
1633     case 'l':
1634     {
1635       if (LocaleCompare(attribute,"label") == 0)
1636         {
1637           for ( ; image; image=image->next)
1638             (void) SetImageProperty(image,"label",InterpretImageProperties(
1639               info ? info->image_info : (ImageInfo *) NULL,image,
1640               SvPV(sval,na),exception),exception);
1641           break;
1642         }
1643       if (LocaleCompare(attribute,"loop") == 0)
1644         goto iterations;
1645       if (info)
1646         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1647       for ( ; image; image=image->next)
1648         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1649       break;
1650     }
1651     case 'M':
1652     case 'm':
1653     {
1654       if (LocaleCompare(attribute,"magick") == 0)
1655         {
1656           if (info)
1657             (void) FormatLocaleString(info->image_info->filename,MaxTextExtent,
1658               "%s:",SvPV(sval,na));
1659           for ( ; image; image=image->next)
1660             (void) CopyMagickString(image->magick,SvPV(sval,na),MaxTextExtent);
1661           break;
1662         }
1663       if (LocaleCompare(attribute,"map-limit") == 0)
1664         {
1665           MagickSizeType
1666             limit;
1667
1668           limit=MagickResourceInfinity;
1669           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1670             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1671               100.0);
1672           (void) SetMagickResourceLimit(MapResource,limit);
1673           break;
1674         }
1675       if (LocaleCompare(attribute,"mask") == 0)
1676         {
1677           Image
1678             *mask;
1679
1680           mask=(Image *) NULL;
1681           if (SvPOK(sval))
1682             mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1683           for ( ; image; image=image->next)
1684             SetImageMask(image,mask,exception);
1685           break;
1686         }
1687       if (LocaleCompare(attribute,"mattecolor") == 0)
1688         {
1689           (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1690             exception);
1691           if (info)
1692             info->image_info->matte_color=target_color;
1693           for ( ; image; image=image->next)
1694             image->matte_color=target_color;
1695           break;
1696         }
1697       if (LocaleCompare(attribute,"matte") == 0)
1698         {
1699           sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1700             SvPV(sval,na)) : SvIV(sval);
1701           if (sp < 0)
1702             {
1703               ThrowPerlException(exception,OptionError,"UnrecognizedType",
1704                 SvPV(sval,na));
1705               break;
1706             }
1707           for ( ; image; image=image->next)
1708             image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1709           break;
1710         }
1711       if (LocaleCompare(attribute,"memory-limit") == 0)
1712         {
1713           MagickSizeType
1714             limit;
1715
1716           limit=MagickResourceInfinity;
1717           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1718             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1719               100.0);
1720           (void) SetMagickResourceLimit(MemoryResource,limit);
1721           break;
1722         }
1723       if (LocaleCompare(attribute,"monochrome") == 0)
1724         {
1725           sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1726             SvPV(sval,na)) : SvIV(sval);
1727           if (sp < 0)
1728             {
1729               ThrowPerlException(exception,OptionError,"UnrecognizedType",
1730                 SvPV(sval,na));
1731               break;
1732             }
1733           if (info)
1734             info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1735           for ( ; image; image=image->next)
1736             (void) SetImageType(image,BilevelType,exception);
1737           break;
1738         }
1739       if (info)
1740         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1741       for ( ; image; image=image->next)
1742         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1743       break;
1744     }
1745     case 'O':
1746     case 'o':
1747     {
1748       if (LocaleCompare(attribute,"option") == 0)
1749         {
1750           if (info)
1751             DefineImageOption(info->image_info,SvPV(sval,na));
1752           break;
1753         }
1754       if (LocaleCompare(attribute,"orientation") == 0)
1755         {
1756           sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1757             MagickFalse,SvPV(sval,na)) : SvIV(sval);
1758           if (sp < 0)
1759             {
1760               ThrowPerlException(exception,OptionError,
1761                 "UnrecognizedOrientationType",SvPV(sval,na));
1762               break;
1763             }
1764           if (info)
1765             info->image_info->orientation=(OrientationType) sp;
1766           for ( ; image; image=image->next)
1767             image->orientation=(OrientationType) sp;
1768           break;
1769         }
1770       if (info)
1771         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1772       for ( ; image; image=image->next)
1773         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1774       break;
1775     }
1776     case 'P':
1777     case 'p':
1778     {
1779       if (LocaleCompare(attribute,"page") == 0)
1780         {
1781           char
1782             *geometry;
1783
1784           geometry=GetPageGeometry(SvPV(sval,na));
1785           if (info)
1786             (void) CloneString(&info->image_info->page,geometry);
1787           for ( ; image; image=image->next)
1788             (void) ParsePageGeometry(image,geometry,&image->page,exception);
1789           geometry=(char *) RelinquishMagickMemory(geometry);
1790           break;
1791         }
1792       if (LocaleNCompare(attribute,"pixel",5) == 0)
1793         {
1794           int
1795             items;
1796
1797           PixelInfo
1798             pixel;
1799
1800           register Quantum
1801             *q;
1802
1803           CacheView
1804             *image_view;
1805
1806           for ( ; image; image=image->next)
1807           {
1808             if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1809               break;
1810             x=0;
1811             y=0;
1812             items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1813             (void) items;
1814             image_view=AcquireVirtualCacheView(image,exception);
1815             q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1816             if (q != (Quantum *) NULL)
1817               {
1818                 if ((strchr(SvPV(sval,na),',') == 0) ||
1819                     (strchr(SvPV(sval,na),')') != 0))
1820                   QueryColorCompliance(SvPV(sval,na),AllCompliance,
1821                     &pixel,exception);
1822                 else
1823                   {
1824                     GetPixelInfo(image,&pixel);
1825                     flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1826                     pixel.red=geometry_info.rho;
1827                     if ((flags & SigmaValue) != 0)
1828                       pixel.green=geometry_info.sigma;
1829                     if ((flags & XiValue) != 0)
1830                       pixel.blue=geometry_info.xi;
1831                     if ((flags & PsiValue) != 0)
1832                       pixel.alpha=geometry_info.psi;
1833                     if ((flags & ChiValue) != 0)
1834                       pixel.black=geometry_info.chi;
1835                   }
1836                 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1837                 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1838                 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1839                 if (image->colorspace == CMYKColorspace)
1840                   SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1841                 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1842                 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1843               }
1844             image_view=DestroyCacheView(image_view);
1845           }
1846           break;
1847         }
1848       if (LocaleCompare(attribute,"pointsize") == 0)
1849         {
1850           if (info)
1851             {
1852               (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1853               info->image_info->pointsize=geometry_info.rho;
1854             }
1855           break;
1856         }
1857       if (LocaleCompare(attribute,"preview") == 0)
1858         {
1859           sp=SvPOK(sval) ? ParseCommandOption(MagickPreviewOptions,MagickFalse,
1860             SvPV(sval,na)) : SvIV(sval);
1861           if (sp < 0)
1862             {
1863               ThrowPerlException(exception,OptionError,"UnrecognizedType",
1864                 SvPV(sval,na));
1865               break;
1866             }
1867           if (info)
1868             info->image_info->preview_type=(PreviewType) sp;
1869           break;
1870         }
1871       if (info)
1872         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1873       for ( ; image; image=image->next)
1874         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1875       break;
1876     }
1877     case 'Q':
1878     case 'q':
1879     {
1880       if (LocaleCompare(attribute,"quality") == 0)
1881         {
1882           if (info)
1883             info->image_info->quality=SvIV(sval);
1884           for ( ; image; image=image->next)
1885             image->quality=SvIV(sval);
1886           break;
1887         }
1888       if (info)
1889         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1890       for ( ; image; image=image->next)
1891         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1892       break;
1893     }
1894     case 'R':
1895     case 'r':
1896     {
1897       if (LocaleCompare(attribute,"red-primary") == 0)
1898         {
1899           for ( ; image; image=image->next)
1900           {
1901             flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1902             image->chromaticity.red_primary.x=geometry_info.rho;
1903             image->chromaticity.red_primary.y=geometry_info.sigma;
1904             if ((flags & SigmaValue) == 0)
1905               image->chromaticity.red_primary.y=
1906                 image->chromaticity.red_primary.x;
1907           }
1908           break;
1909         }
1910       if (LocaleCompare(attribute,"render") == 0)
1911         {
1912           sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1913             SvPV(sval,na)) : SvIV(sval);
1914           if (sp < 0)
1915             {
1916               ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1917                 SvPV(sval,na));
1918               break;
1919             }
1920          for ( ; image; image=image->next)
1921            image->rendering_intent=(RenderingIntent) sp;
1922          break;
1923        }
1924       if (LocaleCompare(attribute,"repage") == 0)
1925         {
1926           RectangleInfo
1927             geometry;
1928
1929           for ( ; image; image=image->next)
1930           {
1931             flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
1932             if ((flags & WidthValue) != 0)
1933               {
1934                 if ((flags & HeightValue) == 0)
1935                   geometry.height=geometry.width;
1936                 image->page.width=geometry.width;
1937                 image->page.height=geometry.height;
1938               }
1939             if ((flags & AspectValue) != 0)
1940               {
1941                 if ((flags & XValue) != 0)
1942                   image->page.x+=geometry.x;
1943                 if ((flags & YValue) != 0)
1944                   image->page.y+=geometry.y;
1945               }
1946             else
1947               {
1948                 if ((flags & XValue) != 0)
1949                   {
1950                     image->page.x=geometry.x;
1951                     if (((flags & WidthValue) != 0) && (geometry.x > 0))
1952                       image->page.width=image->columns+geometry.x;
1953                   }
1954                 if ((flags & YValue) != 0)
1955                   {
1956                     image->page.y=geometry.y;
1957                     if (((flags & HeightValue) != 0) && (geometry.y > 0))
1958                       image->page.height=image->rows+geometry.y;
1959                   }
1960               }
1961           }
1962           break;
1963         }
1964       if (info)
1965         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1966       for ( ; image; image=image->next)
1967         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1968       break;
1969     }
1970     case 'S':
1971     case 's':
1972     {
1973       if (LocaleCompare(attribute,"sampling-factor") == 0)
1974         {
1975           if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1976             {
1977               ThrowPerlException(exception,OptionError,"MissingGeometry",
1978                 SvPV(sval,na));
1979               break;
1980             }
1981           if (info)
1982             (void) CloneString(&info->image_info->sampling_factor,
1983               SvPV(sval,na));
1984           break;
1985         }
1986       if (LocaleCompare(attribute,"scene") == 0)
1987         {
1988           for ( ; image; image=image->next)
1989             image->scene=SvIV(sval);
1990           break;
1991         }
1992       if (LocaleCompare(attribute,"server") == 0)
1993         goto display;
1994       if (LocaleCompare(attribute,"size") == 0)
1995         {
1996           if (info)
1997             {
1998               if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1999                 {
2000                   ThrowPerlException(exception,OptionError,"MissingGeometry",
2001                     SvPV(sval,na));
2002                   break;
2003                 }
2004               (void) CloneString(&info->image_info->size,SvPV(sval,na));
2005             }
2006           break;
2007         }
2008       if (LocaleCompare(attribute,"stroke") == 0)
2009         {
2010           if (info)
2011             (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2012           break;
2013         }
2014       if (info)
2015         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2016       for ( ; image; image=image->next)
2017         SetImageProperty(image,attribute,SvPV(sval,na),exception);
2018       break;
2019     }
2020     case 'T':
2021     case 't':
2022     {
2023       if (LocaleCompare(attribute,"texture") == 0)
2024         {
2025           if (info)
2026             (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2027           break;
2028         }
2029       if (LocaleCompare(attribute,"thread-limit") == 0)
2030         {
2031           MagickSizeType
2032             limit;
2033
2034           limit=MagickResourceInfinity;
2035           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2036             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2037               100.0);
2038           (void) SetMagickResourceLimit(ThreadResource,limit);
2039           break;
2040         }
2041       if (LocaleCompare(attribute,"tile-offset") == 0)
2042         {
2043           char
2044             *geometry;
2045
2046           geometry=GetPageGeometry(SvPV(sval,na));
2047           if (info)
2048             (void) CloneString(&info->image_info->page,geometry);
2049           for ( ; image; image=image->next)
2050             (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2051               exception);
2052           geometry=(char *) RelinquishMagickMemory(geometry);
2053           break;
2054         }
2055       if (LocaleCompare(attribute,"time-limit") == 0)
2056         {
2057           MagickSizeType
2058             limit;
2059
2060           limit=MagickResourceInfinity;
2061           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2062             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2063               100.0);
2064           (void) SetMagickResourceLimit(TimeResource,limit);
2065           break;
2066         }
2067       if (LocaleCompare(attribute,"transparent-color") == 0)
2068         {
2069           (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2070             exception);
2071           if (info)
2072             info->image_info->transparent_color=target_color;
2073           for ( ; image; image=image->next)
2074             image->transparent_color=target_color;
2075           break;
2076         }
2077       if (LocaleCompare(attribute,"type") == 0)
2078         {
2079           sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2080             SvPV(sval,na)) : SvIV(sval);
2081           if (sp < 0)
2082             {
2083               ThrowPerlException(exception,OptionError,"UnrecognizedType",
2084                 SvPV(sval,na));
2085               break;
2086             }
2087           if (info)
2088             info->image_info->type=(ImageType) sp;
2089           for ( ; image; image=image->next)
2090             SetImageType(image,(ImageType) sp,exception);
2091           break;
2092         }
2093       if (info)
2094         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2095       for ( ; image; image=image->next)
2096         SetImageProperty(image,attribute,SvPV(sval,na),exception);
2097       break;
2098     }
2099     case 'U':
2100     case 'u':
2101     {
2102       if (LocaleCompare(attribute,"units") == 0)
2103         {
2104           sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2105             MagickFalse,SvPV(sval,na)) : SvIV(sval);
2106           if (sp < 0)
2107             {
2108               ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2109                 SvPV(sval,na));
2110               break;
2111             }
2112           if (info)
2113             info->image_info->units=(ResolutionType) sp;
2114           for ( ; image; image=image->next)
2115           {
2116             ResolutionType
2117               units;
2118
2119             units=(ResolutionType) sp;
2120             if (image->units != units)
2121               switch (image->units)
2122               {
2123                 case UndefinedResolution:
2124                 case PixelsPerInchResolution:
2125                 {
2126                   if (units == PixelsPerCentimeterResolution)
2127                     {
2128                       image->resolution.x*=2.54;
2129                       image->resolution.y*=2.54;
2130                     }
2131                   break;
2132                 }
2133                 case PixelsPerCentimeterResolution:
2134                 {
2135                   if (units == PixelsPerInchResolution)
2136                     {
2137                       image->resolution.x/=2.54;
2138                       image->resolution.y/=2.54;
2139                     }
2140                   break;
2141                 }
2142               }
2143             image->units=units;
2144           }
2145           break;
2146         }
2147       if (info)
2148         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2149       for ( ; image; image=image->next)
2150         SetImageProperty(image,attribute,SvPV(sval,na),exception);
2151       break;
2152     }
2153     case 'V':
2154     case 'v':
2155     {
2156       if (LocaleCompare(attribute,"verbose") == 0)
2157         {
2158           sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2159             SvPV(sval,na)) : SvIV(sval);
2160           if (sp < 0)
2161             {
2162               ThrowPerlException(exception,OptionError,"UnrecognizedType",
2163                 SvPV(sval,na));
2164               break;
2165             }
2166           if (info)
2167             info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2168           break;
2169         }
2170       if (LocaleCompare(attribute,"view") == 0)
2171         {
2172           if (info)
2173             (void) CloneString(&info->image_info->view,SvPV(sval,na));
2174           break;
2175         }
2176       if (LocaleCompare(attribute,"virtual-pixel") == 0)
2177         {
2178           sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2179             MagickFalse,SvPV(sval,na)) : SvIV(sval);
2180           if (sp < 0)
2181             {
2182               ThrowPerlException(exception,OptionError,
2183                 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2184               break;
2185             }
2186           for ( ; image; image=image->next)
2187             SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2188           break;
2189         }
2190       if (info)
2191         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2192       for ( ; image; image=image->next)
2193         SetImageProperty(image,attribute,SvPV(sval,na),exception);
2194       break;
2195     }
2196     case 'W':
2197     case 'w':
2198     {
2199       if (LocaleCompare(attribute,"white-point") == 0)
2200         {
2201           for ( ; image; image=image->next)
2202           {
2203             flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2204             image->chromaticity.white_point.x=geometry_info.rho;
2205             image->chromaticity.white_point.y=geometry_info.sigma;
2206             if ((flags & SigmaValue) == 0)
2207               image->chromaticity.white_point.y=
2208                 image->chromaticity.white_point.x;
2209           }
2210           break;
2211         }
2212       if (info)
2213         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2214       for ( ; image; image=image->next)
2215         SetImageProperty(image,attribute,SvPV(sval,na),exception);
2216       break;
2217     }
2218     default:
2219     {
2220       if (info)
2221         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2222       for ( ; image; image=image->next)
2223         SetImageProperty(image,attribute,SvPV(sval,na),exception);
2224       break;
2225     }
2226   }
2227 }
2228 \f
2229 /*
2230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2231 %                                                                             %
2232 %                                                                             %
2233 %                                                                             %
2234 %   S e t u p L i s t                                                         %
2235 %                                                                             %
2236 %                                                                             %
2237 %                                                                             %
2238 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2239 %
2240 %  Method SetupList returns the list of all the images linked by their
2241 %  image->next and image->previous link lists for use with ImageMagick.  If
2242 %  info is non-NULL, an info structure is returned in *info.  If
2243 %  reference_vector is non-NULL,an array of SV* are returned in
2244 %  *reference_vector.  Reference_vector is used when the images are going to be
2245 %  replaced with new Image*'s.
2246 %
2247 %  The format of the SetupList routine is:
2248 %
2249 %      Image *SetupList(SV *reference,struct PackageInfo **info,
2250 %        SV ***reference_vector,ExceptionInfo *exception)
2251 %
2252 %  A description of each parameter follows:
2253 %
2254 %    o list: a list of strings.
2255 %
2256 %    o string: a character string.
2257 %
2258 %    o exception: Return any errors or warnings in this structure.
2259 %
2260 */
2261 static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2262   SV ***reference_vector,ExceptionInfo *exception)
2263 {
2264   Image
2265     *image;
2266
2267   ssize_t
2268     current,
2269     last;
2270
2271   if (reference_vector)
2272     *reference_vector=NULL;
2273   if (info)
2274     *info=NULL;
2275   current=0;
2276   last=0;
2277   image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2278   if (info && (SvTYPE(reference) == SVt_PVAV))
2279     *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2280       exception);
2281   return(image);
2282 }
2283 \f
2284 /*
2285 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2286 %                                                                             %
2287 %                                                                             %
2288 %                                                                             %
2289 %   s t r E Q c a s e                                                         %
2290 %                                                                             %
2291 %                                                                             %
2292 %                                                                             %
2293 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2294 %
2295 %  strEQcase() compares two strings and returns 0 if they are the
2296 %  same or if the second string runs out first.  The comparison is case
2297 %  insensitive.
2298 %
2299 %  The format of the strEQcase routine is:
2300 %
2301 %      ssize_t strEQcase(const char *p,const char *q)
2302 %
2303 %  A description of each parameter follows:
2304 %
2305 %    o p: a character string.
2306 %
2307 %    o q: a character string.
2308 %
2309 %
2310 */
2311 static ssize_t strEQcase(const char *p,const char *q)
2312 {
2313   char
2314     c;
2315
2316   register ssize_t
2317     i;
2318
2319   for (i=0 ; (c=(*q)) != 0; i++)
2320   {
2321     if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2322         (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2323       return(0);
2324     p++;
2325     q++;
2326   }
2327   return(((*q == 0) && (*p == 0)) ? i : 0);
2328 }
2329 \f
2330 /*
2331 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2332 %                                                                             %
2333 %                                                                             %
2334 %                                                                             %
2335 %   I m a g e : : M a g i c k                                                 %
2336 %                                                                             %
2337 %                                                                             %
2338 %                                                                             %
2339 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2340 %
2341 %
2342 */
2343 MODULE = Image::Magick::@MAGICK_ABI_SUFFIX@ PACKAGE = Image::Magick::@MAGICK_ABI_SUFFIX@
2344
2345 PROTOTYPES: ENABLE
2346
2347 BOOT:
2348   MagickCoreGenesis("PerlMagick",MagickFalse);
2349   SetWarningHandler(NULL);
2350   SetErrorHandler(NULL);
2351   magick_registry=NewSplayTree((int (*)(const void *,const void *))
2352     NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2353
2354 void
2355 UNLOAD()
2356   PPCODE:
2357   {
2358     if (magick_registry != (SplayTreeInfo *) NULL)
2359       magick_registry=DestroySplayTree(magick_registry);
2360     MagickCoreTerminus();
2361   }
2362
2363 double
2364 constant(name,argument)
2365   char *name
2366   ssize_t argument
2367 \f
2368 #
2369 ###############################################################################
2370 #                                                                             #
2371 #                                                                             #
2372 #                                                                             #
2373 #   A n i m a t e                                                             #
2374 #                                                                             #
2375 #                                                                             #
2376 #                                                                             #
2377 ###############################################################################
2378 #
2379 #
2380 void
2381 Animate(ref,...)
2382   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
2383   ALIAS:
2384     AnimateImage  = 1
2385     animate       = 2
2386     animateimage  = 3
2387   PPCODE:
2388   {
2389     ExceptionInfo
2390       *exception;
2391
2392     Image
2393       *image;
2394
2395     register ssize_t
2396       i;
2397
2398     struct PackageInfo
2399       *info,
2400       *package_info;
2401
2402     SV
2403       *perl_exception,
2404       *reference;
2405
2406     PERL_UNUSED_VAR(ref);
2407     PERL_UNUSED_VAR(ix);
2408     exception=AcquireExceptionInfo();
2409     perl_exception=newSVpv("",0);
2410     package_info=(struct PackageInfo *) NULL;
2411     if (sv_isobject(ST(0)) == 0)
2412       {
2413         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2414           PackageName);
2415         goto PerlException;
2416       }
2417     reference=SvRV(ST(0));
2418     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2419     if (image == (Image *) NULL)
2420       {
2421         ThrowPerlException(exception,OptionError,"NoImagesDefined",
2422           PackageName);
2423         goto PerlException;
2424       }
2425     package_info=ClonePackageInfo(info,exception);
2426     if (items == 2)
2427       SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2428     else
2429       if (items > 2)
2430         for (i=2; i < items; i+=2)
2431           SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2432             exception);
2433     (void) AnimateImages(package_info->image_info,image,exception);
2434     (void) CatchImageException(image);
2435
2436   PerlException:
2437     if (package_info != (struct PackageInfo *) NULL)
2438       DestroyPackageInfo(package_info);
2439     InheritPerlException(exception,perl_exception);
2440     exception=DestroyExceptionInfo(exception);
2441     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2442     SvPOK_on(perl_exception);
2443     ST(0)=sv_2mortal(perl_exception);
2444     XSRETURN(1);
2445   }
2446 \f
2447 #
2448 ###############################################################################
2449 #                                                                             #
2450 #                                                                             #
2451 #                                                                             #
2452 #   A p p e n d                                                               #
2453 #                                                                             #
2454 #                                                                             #
2455 #                                                                             #
2456 ###############################################################################
2457 #
2458 #
2459 void
2460 Append(ref,...)
2461   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
2462   ALIAS:
2463     AppendImage  = 1
2464     append       = 2
2465     appendimage  = 3
2466   PPCODE:
2467   {
2468     AV
2469       *av;
2470
2471     char
2472       *attribute;
2473
2474     ExceptionInfo
2475       *exception;
2476
2477     HV
2478       *hv;
2479
2480     Image
2481       *image;
2482
2483     register ssize_t
2484       i;
2485
2486     ssize_t
2487       stack;
2488
2489     struct PackageInfo
2490       *info;
2491
2492     SV
2493       *av_reference,
2494       *perl_exception,
2495       *reference,
2496       *rv,
2497       *sv;
2498
2499     PERL_UNUSED_VAR(ref);
2500     PERL_UNUSED_VAR(ix);
2501     exception=AcquireExceptionInfo();
2502     perl_exception=newSVpv("",0);
2503     sv=NULL;
2504     attribute=NULL;
2505     av=NULL;
2506     if (sv_isobject(ST(0)) == 0)
2507       {
2508         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2509           PackageName);
2510         goto PerlException;
2511       }
2512     reference=SvRV(ST(0));
2513     hv=SvSTASH(reference);
2514     av=newAV();
2515     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2516     SvREFCNT_dec(av);
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     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2525     /*
2526       Get options.
2527     */
2528     stack=MagickTrue;
2529     for (i=2; i < items; i+=2)
2530     {
2531       attribute=(char *) SvPV(ST(i-1),na);
2532       switch (*attribute)
2533       {
2534         case 'S':
2535         case 's':
2536         {
2537           if (LocaleCompare(attribute,"stack") == 0)
2538             {
2539               stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2540                 SvPV(ST(i),na));
2541               if (stack < 0)
2542                 {
2543                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
2544                     SvPV(ST(i),na));
2545                   return;
2546                 }
2547               break;
2548             }
2549           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2550             attribute);
2551           break;
2552         }
2553         default:
2554         {
2555           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2556             attribute);
2557           break;
2558         }
2559       }
2560     }
2561     image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2562     if (image == (Image *) NULL)
2563       goto PerlException;
2564     for ( ; image; image=image->next)
2565     {
2566       AddImageToRegistry(sv,image);
2567       rv=newRV(sv);
2568       av_push(av,sv_bless(rv,hv));
2569       SvREFCNT_dec(sv);
2570     }
2571     exception=DestroyExceptionInfo(exception);
2572     ST(0)=av_reference;
2573     SvREFCNT_dec(perl_exception);
2574     XSRETURN(1);
2575
2576   PerlException:
2577     InheritPerlException(exception,perl_exception);
2578     exception=DestroyExceptionInfo(exception);
2579     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2580     SvPOK_on(perl_exception);
2581     ST(0)=sv_2mortal(perl_exception);
2582     XSRETURN(1);
2583   }
2584 \f
2585 #
2586 ###############################################################################
2587 #                                                                             #
2588 #                                                                             #
2589 #                                                                             #
2590 #   A v e r a g e                                                             #
2591 #                                                                             #
2592 #                                                                             #
2593 #                                                                             #
2594 ###############################################################################
2595 #
2596 #
2597 void
2598 Average(ref)
2599   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
2600   ALIAS:
2601     AverageImage   = 1
2602     average        = 2
2603     averageimage   = 3
2604   PPCODE:
2605   {
2606     AV
2607       *av;
2608
2609     char
2610       *p;
2611
2612     ExceptionInfo
2613       *exception;
2614
2615     HV
2616       *hv;
2617
2618     Image
2619       *image;
2620
2621     struct PackageInfo
2622       *info;
2623
2624     SV
2625       *perl_exception,
2626       *reference,
2627       *rv,
2628       *sv;
2629
2630     PERL_UNUSED_VAR(ref);
2631     PERL_UNUSED_VAR(ix);
2632     exception=AcquireExceptionInfo();
2633     perl_exception=newSVpv("",0);
2634     sv=NULL;
2635     if (sv_isobject(ST(0)) == 0)
2636       {
2637         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2638           PackageName);
2639         goto PerlException;
2640       }
2641     reference=SvRV(ST(0));
2642     hv=SvSTASH(reference);
2643     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2644     if (image == (Image *) NULL)
2645       {
2646         ThrowPerlException(exception,OptionError,"NoImagesDefined",
2647           PackageName);
2648         goto PerlException;
2649       }
2650     image=EvaluateImages(image,MeanEvaluateOperator,exception);
2651     if (image == (Image *) NULL)
2652       goto PerlException;
2653     /*
2654       Create blessed Perl array for the returned image.
2655     */
2656     av=newAV();
2657     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2658     SvREFCNT_dec(av);
2659     AddImageToRegistry(sv,image);
2660     rv=newRV(sv);
2661     av_push(av,sv_bless(rv,hv));
2662     SvREFCNT_dec(sv);
2663     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2664     (void) FormatLocaleString(info->image_info->filename,MaxTextExtent,
2665       "average-%.*s",(int) (MaxTextExtent-9),
2666       ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2667     (void) CopyMagickString(image->filename,info->image_info->filename,
2668       MaxTextExtent);
2669     SetImageInfo(info->image_info,0,exception);
2670     exception=DestroyExceptionInfo(exception);
2671     SvREFCNT_dec(perl_exception);
2672     XSRETURN(1);
2673
2674   PerlException:
2675     InheritPerlException(exception,perl_exception);
2676     exception=DestroyExceptionInfo(exception);
2677     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2678     SvPOK_on(perl_exception);
2679     ST(0)=sv_2mortal(perl_exception);
2680     XSRETURN(1);
2681   }
2682 \f
2683 #
2684 ###############################################################################
2685 #                                                                             #
2686 #                                                                             #
2687 #                                                                             #
2688 #   B l o b T o I m a g e                                                     #
2689 #                                                                             #
2690 #                                                                             #
2691 #                                                                             #
2692 ###############################################################################
2693 #
2694 #
2695 void
2696 BlobToImage(ref,...)
2697   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
2698   ALIAS:
2699     BlobToImage  = 1
2700     blobtoimage  = 2
2701     blobto       = 3
2702   PPCODE:
2703   {
2704     AV
2705       *av;
2706
2707     char
2708       **keep,
2709       **list;
2710
2711     ExceptionInfo
2712       *exception;
2713
2714     HV
2715       *hv;
2716
2717     Image
2718       *image;
2719
2720     register char
2721       **p;
2722
2723     register ssize_t
2724       i;
2725
2726     ssize_t
2727       ac,
2728       n,
2729       number_images;
2730
2731     STRLEN
2732       *length;
2733
2734     struct PackageInfo
2735       *info;
2736
2737     SV
2738       *perl_exception,
2739       *reference,
2740       *rv,
2741       *sv;
2742
2743     PERL_UNUSED_VAR(ref);
2744     PERL_UNUSED_VAR(ix);
2745     exception=AcquireExceptionInfo();
2746     perl_exception=newSVpv("",0);
2747     sv=NULL;
2748     number_images=0;
2749     ac=(items < 2) ? 1 : items-1;
2750     length=(STRLEN *) NULL;
2751     list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2752     if (list == (char **) NULL)
2753       {
2754         ThrowPerlException(exception,ResourceLimitError,
2755           "MemoryAllocationFailed",PackageName);
2756         goto PerlException;
2757       }
2758     length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2759     if (length == (STRLEN *) NULL)
2760       {
2761         ThrowPerlException(exception,ResourceLimitError,
2762           "MemoryAllocationFailed",PackageName);
2763         goto PerlException;
2764       }
2765     if (sv_isobject(ST(0)) == 0)
2766       {
2767         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2768           PackageName);
2769         goto PerlException;
2770       }
2771     reference=SvRV(ST(0));
2772     hv=SvSTASH(reference);
2773     if (SvTYPE(reference) != SVt_PVAV)
2774       {
2775         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2776           PackageName);
2777         goto PerlException;
2778       }
2779     av=(AV *) reference;
2780     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2781       exception);
2782     n=1;
2783     if (items <= 1)
2784       {
2785         ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2786         goto PerlException;
2787       }
2788     for (n=0, i=0; i < ac; i++)
2789     {
2790       list[n]=(char *) (SvPV(ST(i+1),length[n]));
2791       if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2792         {
2793           list[n]=(char *) (SvPV(ST(i+2),length[n]));
2794           continue;
2795         }
2796       n++;
2797     }
2798     list[n]=(char *) NULL;
2799     keep=list;
2800     for (i=number_images=0; i < n; i++)
2801     {
2802       image=BlobToImage(info->image_info,list[i],length[i],exception);
2803       if (image == (Image *) NULL)
2804         break;
2805       for ( ; image; image=image->next)
2806       {
2807         AddImageToRegistry(sv,image);
2808         rv=newRV(sv);
2809         av_push(av,sv_bless(rv,hv));
2810         SvREFCNT_dec(sv);
2811         number_images++;
2812       }
2813     }
2814     /*
2815       Free resources.
2816     */
2817     for (i=0; i < n; i++)
2818       if (list[i] != (char *) NULL)
2819         for (p=keep; list[i] != *p++; )
2820           if (*p == (char *) NULL)
2821             {
2822               list[i]=(char *) RelinquishMagickMemory(list[i]);
2823               break;
2824             }
2825
2826   PerlException:
2827     if (list)
2828       list=(char **) RelinquishMagickMemory(list);
2829     if (length)
2830       length=(STRLEN *) RelinquishMagickMemory(length);
2831     InheritPerlException(exception,perl_exception);
2832     exception=DestroyExceptionInfo(exception);
2833     sv_setiv(perl_exception,(IV) number_images);
2834     SvPOK_on(perl_exception);
2835     ST(0)=sv_2mortal(perl_exception);
2836     XSRETURN(1);
2837   }
2838 \f
2839 #
2840 ###############################################################################
2841 #                                                                             #
2842 #                                                                             #
2843 #                                                                             #
2844 #   C h a n n e l F x                                                         #
2845 #                                                                             #
2846 #                                                                             #
2847 #                                                                             #
2848 ###############################################################################
2849 #
2850 #
2851 void
2852 ChannelFx(ref,...)
2853   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
2854   ALIAS:
2855     ChannelFxImage  = 1
2856     channelfx       = 2
2857     channelfximage  = 3
2858   PPCODE:
2859   {
2860     AV
2861       *av;
2862
2863     char
2864       *attribute,
2865       expression[MaxTextExtent];
2866
2867     ChannelType
2868       channel,
2869       channel_mask;
2870
2871     ExceptionInfo
2872       *exception;
2873
2874     HV
2875       *hv;
2876
2877     Image
2878       *image;
2879
2880     register ssize_t
2881       i;
2882
2883     struct PackageInfo
2884       *info;
2885
2886     SV
2887       *av_reference,
2888       *perl_exception,
2889       *reference,
2890       *rv,
2891       *sv;
2892
2893     PERL_UNUSED_VAR(ref);
2894     PERL_UNUSED_VAR(ix);
2895     exception=AcquireExceptionInfo();
2896     perl_exception=newSVpv("",0);
2897     sv=NULL;
2898     attribute=NULL;
2899     av=NULL;
2900     if (sv_isobject(ST(0)) == 0)
2901       {
2902         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2903           PackageName);
2904         goto PerlException;
2905       }
2906     reference=SvRV(ST(0));
2907     hv=SvSTASH(reference);
2908     av=newAV();
2909     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2910     SvREFCNT_dec(av);
2911     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2912     if (image == (Image *) NULL)
2913       {
2914         ThrowPerlException(exception,OptionError,"NoImagesDefined",
2915           PackageName);
2916         goto PerlException;
2917       }
2918     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2919     /*
2920       Get options.
2921     */
2922     channel=DefaultChannels;
2923     (void) CopyMagickString(expression,"u",MaxTextExtent);
2924     if (items == 2)
2925       (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MaxTextExtent);
2926     else
2927       for (i=2; i < items; i+=2)
2928       {
2929         attribute=(char *) SvPV(ST(i-1),na);
2930         switch (*attribute)
2931         {
2932           case 'C':
2933           case 'c':
2934           {
2935             if (LocaleCompare(attribute,"channel") == 0)
2936               {
2937                 ssize_t
2938                   option;
2939
2940                 option=ParseChannelOption(SvPV(ST(i),na));
2941                 if (option < 0)
2942                   {
2943                     ThrowPerlException(exception,OptionError,
2944                       "UnrecognizedType",SvPV(ST(i),na));
2945                     return;
2946                   }
2947                 channel=(ChannelType) option;
2948                 break;
2949               }
2950             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2951               attribute);
2952             break;
2953           }
2954           case 'E':
2955           case 'e':
2956           {
2957             if (LocaleCompare(attribute,"expression") == 0)
2958               {
2959                 (void) CopyMagickString(expression,SvPV(ST(i),na),
2960                   MaxTextExtent);
2961                 break;
2962               }
2963             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2964               attribute);
2965             break;
2966           }
2967           default:
2968           {
2969             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2970               attribute);
2971             break;
2972           }
2973         }
2974       }
2975     channel_mask=SetImageChannelMask(image,channel);
2976     image=ChannelFxImage(image,expression,exception);
2977     if (image != (Image *) NULL)
2978       (void) SetImageChannelMask(image,channel_mask);
2979     if (image == (Image *) NULL)
2980       goto PerlException;
2981     for ( ; image; image=image->next)
2982     {
2983       AddImageToRegistry(sv,image);
2984       rv=newRV(sv);
2985       av_push(av,sv_bless(rv,hv));
2986       SvREFCNT_dec(sv);
2987     }
2988     exception=DestroyExceptionInfo(exception);
2989     ST(0)=av_reference;
2990     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
2991     XSRETURN(1);
2992
2993   PerlException:
2994     InheritPerlException(exception,perl_exception);
2995     exception=DestroyExceptionInfo(exception);
2996     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2997     SvPOK_on(perl_exception);
2998     ST(0)=sv_2mortal(perl_exception);
2999     XSRETURN(1);
3000   }
3001 \f
3002 #
3003 ###############################################################################
3004 #                                                                             #
3005 #                                                                             #
3006 #                                                                             #
3007 #   C l o n e                                                                 #
3008 #                                                                             #
3009 #                                                                             #
3010 #                                                                             #
3011 ###############################################################################
3012 #
3013 #
3014 void
3015 Clone(ref)
3016   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
3017   ALIAS:
3018     CopyImage   = 1
3019     copy        = 2
3020     copyimage   = 3
3021     CloneImage  = 4
3022     clone       = 5
3023     cloneimage  = 6
3024     Clone       = 7
3025   PPCODE:
3026   {
3027     AV
3028       *av;
3029
3030     ExceptionInfo
3031       *exception;
3032
3033     HV
3034       *hv;
3035
3036     Image
3037       *clone,
3038       *image;
3039
3040     struct PackageInfo
3041       *info;
3042
3043     SV
3044       *perl_exception,
3045       *reference,
3046       *rv,
3047       *sv;
3048
3049     PERL_UNUSED_VAR(ref);
3050     PERL_UNUSED_VAR(ix);
3051     exception=AcquireExceptionInfo();
3052     perl_exception=newSVpv("",0);
3053     sv=NULL;
3054     if (sv_isobject(ST(0)) == 0)
3055       {
3056         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3057           PackageName);
3058         goto PerlException;
3059       }
3060     reference=SvRV(ST(0));
3061     hv=SvSTASH(reference);
3062     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3063     if (image == (Image *) NULL)
3064       {
3065         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3066           PackageName);
3067         goto PerlException;
3068       }
3069     /*
3070       Create blessed Perl array for the returned image.
3071     */
3072     av=newAV();
3073     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3074     SvREFCNT_dec(av);
3075     for ( ; image; image=image->next)
3076     {
3077       clone=CloneImage(image,0,0,MagickTrue,exception);
3078       if (clone == (Image *) NULL)
3079         break;
3080       AddImageToRegistry(sv,clone);
3081       rv=newRV(sv);
3082       av_push(av,sv_bless(rv,hv));
3083       SvREFCNT_dec(sv);
3084     }
3085     exception=DestroyExceptionInfo(exception);
3086     SvREFCNT_dec(perl_exception);
3087     XSRETURN(1);
3088
3089   PerlException:
3090     InheritPerlException(exception,perl_exception);
3091     exception=DestroyExceptionInfo(exception);
3092     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3093     SvPOK_on(perl_exception);
3094     ST(0)=sv_2mortal(perl_exception);
3095     XSRETURN(1);
3096   }
3097 \f
3098 #
3099 ###############################################################################
3100 #                                                                             #
3101 #                                                                             #
3102 #                                                                             #
3103 #   C L O N E                                                                 #
3104 #                                                                             #
3105 #                                                                             #
3106 #                                                                             #
3107 ###############################################################################
3108 #
3109 #
3110 void
3111 CLONE(ref,...)
3112   SV *ref;
3113   CODE:
3114   {
3115     PERL_UNUSED_VAR(ref);
3116     if (magick_registry != (SplayTreeInfo *) NULL)
3117       {
3118         register Image
3119           *p;
3120
3121         ResetSplayTreeIterator(magick_registry);
3122         p=(Image *) GetNextKeyInSplayTree(magick_registry);
3123         while (p != (Image *) NULL)
3124         {
3125           ReferenceImage(p);
3126           p=(Image *) GetNextKeyInSplayTree(magick_registry);
3127         }
3128       }
3129   }
3130 \f
3131 #
3132 ###############################################################################
3133 #                                                                             #
3134 #                                                                             #
3135 #                                                                             #
3136 #   C o a l e s c e                                                           #
3137 #                                                                             #
3138 #                                                                             #
3139 #                                                                             #
3140 ###############################################################################
3141 #
3142 #
3143 void
3144 Coalesce(ref)
3145   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
3146   ALIAS:
3147     CoalesceImage   = 1
3148     coalesce        = 2
3149     coalesceimage   = 3
3150   PPCODE:
3151   {
3152     AV
3153       *av;
3154
3155     ExceptionInfo
3156       *exception;
3157
3158     HV
3159       *hv;
3160
3161     Image
3162       *image;
3163
3164     struct PackageInfo
3165       *info;
3166
3167     SV
3168       *av_reference,
3169       *perl_exception,
3170       *reference,
3171       *rv,
3172       *sv;
3173
3174     PERL_UNUSED_VAR(ref);
3175     PERL_UNUSED_VAR(ix);
3176     exception=AcquireExceptionInfo();
3177     perl_exception=newSVpv("",0);
3178     sv=NULL;
3179     if (sv_isobject(ST(0)) == 0)
3180       {
3181         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3182           PackageName);
3183         goto PerlException;
3184       }
3185     reference=SvRV(ST(0));
3186     hv=SvSTASH(reference);
3187     av=newAV();
3188     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3189     SvREFCNT_dec(av);
3190     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3191     if (image == (Image *) NULL)
3192       {
3193         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3194           PackageName);
3195         goto PerlException;
3196       }
3197     image=CoalesceImages(image,exception);
3198     if (image == (Image *) NULL)
3199       goto PerlException;
3200     for ( ; image; image=image->next)
3201     {
3202       AddImageToRegistry(sv,image);
3203       rv=newRV(sv);
3204       av_push(av,sv_bless(rv,hv));
3205       SvREFCNT_dec(sv);
3206     }
3207     exception=DestroyExceptionInfo(exception);
3208     ST(0)=av_reference;
3209     SvREFCNT_dec(perl_exception);
3210     XSRETURN(1);
3211
3212   PerlException:
3213     InheritPerlException(exception,perl_exception);
3214     exception=DestroyExceptionInfo(exception);
3215     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3216     SvPOK_on(perl_exception);
3217     ST(0)=sv_2mortal(perl_exception);
3218     XSRETURN(1);
3219   }
3220 \f
3221 #
3222 ###############################################################################
3223 #                                                                             #
3224 #                                                                             #
3225 #                                                                             #
3226 #   C o m p a r e                                                             #
3227 #                                                                             #
3228 #                                                                             #
3229 #                                                                             #
3230 ###############################################################################
3231 #
3232 #
3233 void
3234 Compare(ref,...)
3235   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
3236   ALIAS:
3237     CompareImages = 1
3238     compare      = 2
3239     compareimage = 3
3240   PPCODE:
3241   {
3242     AV
3243       *av;
3244
3245     char
3246       *attribute;
3247
3248     double
3249       distortion;
3250
3251     ExceptionInfo
3252       *exception;
3253
3254     HV
3255       *hv;
3256
3257     Image
3258       *difference_image,
3259       *image,
3260       *reconstruct_image;
3261
3262     MetricType
3263       metric;
3264
3265     register ssize_t
3266       i;
3267
3268     ssize_t
3269       option;
3270
3271     struct PackageInfo
3272       *info;
3273
3274     SV
3275       *av_reference,
3276       *perl_exception,
3277       *reference,
3278       *rv,
3279       *sv;
3280
3281     PERL_UNUSED_VAR(ref);
3282     PERL_UNUSED_VAR(ix);
3283     exception=AcquireExceptionInfo();
3284     perl_exception=newSVpv("",0);
3285     sv=NULL;
3286     av=NULL;
3287     attribute=NULL;
3288     if (sv_isobject(ST(0)) == 0)
3289       {
3290         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3291           PackageName);
3292         goto PerlException;
3293       }
3294     reference=SvRV(ST(0));
3295     hv=SvSTASH(reference);
3296     av=newAV();
3297     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3298     SvREFCNT_dec(av);
3299     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3300     if (image == (Image *) NULL)
3301       {
3302         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3303           PackageName);
3304         goto PerlException;
3305       }
3306     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3307     /*
3308       Get attribute.
3309     */
3310     reconstruct_image=image;
3311     metric=RootMeanSquaredErrorMetric;
3312     for (i=2; i < items; i+=2)
3313     {
3314       attribute=(char *) SvPV(ST(i-1),na);
3315       switch (*attribute)
3316       {
3317         case 'C':
3318         case 'c':
3319         {
3320           if (LocaleCompare(attribute,"channel") == 0)
3321             {
3322               ssize_t
3323                 option;
3324
3325               option=ParseChannelOption(SvPV(ST(i),na));
3326               if (option < 0)
3327                 {
3328                   ThrowPerlException(exception,OptionError,
3329                     "UnrecognizedType",SvPV(ST(i),na));
3330                   return;
3331                 }
3332               SetPixelChannelMask(image,(ChannelType) option);
3333               break;
3334             }
3335           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3336             attribute);
3337           break;
3338         }
3339         case 'F':
3340         case 'f':
3341         {
3342           if (LocaleCompare(attribute,"fuzz") == 0)
3343             {
3344               image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3345               break;
3346             }
3347           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3348             attribute);
3349           break;
3350         }
3351         case 'I':
3352         case 'i':
3353         {
3354           if (LocaleCompare(attribute,"image") == 0)
3355             {
3356               reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3357                 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3358               break;
3359             }
3360           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3361             attribute);
3362           break;
3363         }
3364         case 'M':
3365         case 'm':
3366         {
3367           if (LocaleCompare(attribute,"metric") == 0)
3368             {
3369               option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3370                 SvPV(ST(i),na));
3371               if (option < 0)
3372                 {
3373                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
3374                     SvPV(ST(i),na));
3375                   break;
3376                 }
3377               metric=(MetricType) option;
3378               break;
3379             }
3380           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3381             attribute);
3382           break;
3383         }
3384         default:
3385         {
3386           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3387             attribute);
3388           break;
3389         }
3390       }
3391     }
3392     difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3393       exception);
3394     if (difference_image != (Image *) NULL)
3395       {
3396         difference_image->error.mean_error_per_pixel=distortion;
3397         AddImageToRegistry(sv,difference_image);
3398         rv=newRV(sv);
3399         av_push(av,sv_bless(rv,hv));
3400         SvREFCNT_dec(sv);
3401       }
3402     exception=DestroyExceptionInfo(exception);
3403     ST(0)=av_reference;
3404     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
3405     XSRETURN(1);
3406
3407   PerlException:
3408     InheritPerlException(exception,perl_exception);
3409     exception=DestroyExceptionInfo(exception);
3410     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3411     SvPOK_on(perl_exception);
3412     ST(0)=sv_2mortal(perl_exception);
3413     XSRETURN(1);
3414   }
3415 \f
3416 #
3417 ###############################################################################
3418 #                                                                             #
3419 #                                                                             #
3420 #                                                                             #
3421 #   C o m p a r e L a y e r s                                                 #
3422 #                                                                             #
3423 #                                                                             #
3424 #                                                                             #
3425 ###############################################################################
3426 #
3427 #
3428 void
3429 CompareLayers(ref)
3430   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
3431   ALIAS:
3432     CompareImagesLayers   = 1
3433     comparelayers        = 2
3434     compareimagelayers   = 3
3435   PPCODE:
3436   {
3437     AV
3438       *av;
3439
3440     char
3441       *attribute;
3442
3443     ExceptionInfo
3444       *exception;
3445
3446     HV
3447       *hv;
3448
3449     Image
3450       *image;
3451
3452     LayerMethod
3453       method;
3454
3455     register ssize_t
3456       i;
3457
3458     ssize_t
3459       option;
3460
3461     struct PackageInfo
3462       *info;
3463
3464     SV
3465       *av_reference,
3466       *perl_exception,
3467       *reference,
3468       *rv,
3469       *sv;
3470
3471     PERL_UNUSED_VAR(ref);
3472     PERL_UNUSED_VAR(ix);
3473     exception=AcquireExceptionInfo();
3474     perl_exception=newSVpv("",0);
3475     sv=NULL;
3476     if (sv_isobject(ST(0)) == 0)
3477       {
3478         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3479           PackageName);
3480         goto PerlException;
3481       }
3482     reference=SvRV(ST(0));
3483     hv=SvSTASH(reference);
3484     av=newAV();
3485     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3486     SvREFCNT_dec(av);
3487     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3488     if (image == (Image *) NULL)
3489       {
3490         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3491           PackageName);
3492         goto PerlException;
3493       }
3494     method=CompareAnyLayer;
3495     for (i=2; i < items; i+=2)
3496     {
3497       attribute=(char *) SvPV(ST(i-1),na);
3498       switch (*attribute)
3499       {
3500         case 'M':
3501         case 'm':
3502         {
3503           if (LocaleCompare(attribute,"method") == 0)
3504             {
3505               option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3506                 SvPV(ST(i),na));
3507               if (option < 0)
3508                 {
3509                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
3510                     SvPV(ST(i),na));
3511                   break;
3512                 }
3513                method=(LayerMethod) option;
3514               break;
3515             }
3516           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3517             attribute);
3518           break;
3519         }
3520         default:
3521         {
3522           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3523             attribute);
3524           break;
3525         }
3526       }
3527     }
3528     image=CompareImagesLayers(image,method,exception);
3529     if (image == (Image *) NULL)
3530       goto PerlException;
3531     for ( ; image; image=image->next)
3532     {
3533       AddImageToRegistry(sv,image);
3534       rv=newRV(sv);
3535       av_push(av,sv_bless(rv,hv));
3536       SvREFCNT_dec(sv);
3537     }
3538     exception=DestroyExceptionInfo(exception);
3539     ST(0)=av_reference;
3540     SvREFCNT_dec(perl_exception);
3541     XSRETURN(1);
3542
3543   PerlException:
3544     InheritPerlException(exception,perl_exception);
3545     exception=DestroyExceptionInfo(exception);
3546     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3547     SvPOK_on(perl_exception);
3548     ST(0)=sv_2mortal(perl_exception);
3549     XSRETURN(1);
3550   }
3551 \f
3552 #
3553 ###############################################################################
3554 #                                                                             #
3555 #                                                                             #
3556 #                                                                             #
3557 #   D e s t r o y                                                             #
3558 #                                                                             #
3559 #                                                                             #
3560 #                                                                             #
3561 ###############################################################################
3562 #
3563 #
3564 void
3565 DESTROY(ref)
3566   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
3567   PPCODE:
3568   {
3569     SV
3570       *reference;
3571
3572     PERL_UNUSED_VAR(ref);
3573     if (sv_isobject(ST(0)) == 0)
3574       croak("ReferenceIsNotMyType");
3575     reference=SvRV(ST(0));
3576     switch (SvTYPE(reference))
3577     {
3578       case SVt_PVAV:
3579       {
3580         char
3581           message[MaxTextExtent];
3582
3583         const SV
3584           *key;
3585
3586         HV
3587           *hv;
3588
3589         GV
3590           **gvp;
3591
3592         struct PackageInfo
3593           *info;
3594
3595         SV
3596           *sv;
3597
3598         /*
3599           Array (AV *) reference
3600         */
3601         (void) FormatLocaleString(message,MaxTextExtent,"package%s%p",
3602           XS_VERSION,reference);
3603         hv=gv_stashpv(PackageName, FALSE);
3604         if (!hv)
3605           break;
3606         gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3607         if (!gvp)
3608           break;
3609         sv=GvSV(*gvp);
3610         if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3611           {
3612             info=INT2PTR(struct PackageInfo *,SvIV(sv));
3613             DestroyPackageInfo(info);
3614           }
3615         key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3616         (void) key;
3617         break;
3618       }
3619       case SVt_PVMG:
3620       {
3621         Image
3622           *image;
3623
3624         /*
3625           Blessed scalar = (Image *) SvIV(reference)
3626         */
3627         image=INT2PTR(Image *,SvIV(reference));
3628         if (image != (Image *) NULL)
3629           DeleteImageFromRegistry(reference,image);
3630         break;
3631       }
3632       default:
3633         break;
3634     }
3635   }
3636 \f
3637 #
3638 ###############################################################################
3639 #                                                                             #
3640 #                                                                             #
3641 #                                                                             #
3642 #   D i s p l a y                                                             #
3643 #                                                                             #
3644 #                                                                             #
3645 #                                                                             #
3646 ###############################################################################
3647 #
3648 #
3649 void
3650 Display(ref,...)
3651   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
3652   ALIAS:
3653     DisplayImage  = 1
3654     display       = 2
3655     displayimage  = 3
3656   PPCODE:
3657   {
3658     ExceptionInfo
3659       *exception;
3660
3661     Image
3662       *image;
3663
3664     register ssize_t
3665       i;
3666
3667     struct PackageInfo
3668       *info,
3669       *package_info;
3670
3671     SV
3672       *perl_exception,
3673       *reference;
3674
3675     PERL_UNUSED_VAR(ref);
3676     PERL_UNUSED_VAR(ix);
3677     exception=AcquireExceptionInfo();
3678     perl_exception=newSVpv("",0);
3679     package_info=(struct PackageInfo *) NULL;
3680     if (sv_isobject(ST(0)) == 0)
3681       {
3682         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3683           PackageName);
3684         goto PerlException;
3685       }
3686     reference=SvRV(ST(0));
3687     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3688     if (image == (Image *) NULL)
3689       {
3690         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3691           PackageName);
3692         goto PerlException;
3693       }
3694     package_info=ClonePackageInfo(info,exception);
3695     if (items == 2)
3696       SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3697     else
3698       if (items > 2)
3699         for (i=2; i < items; i+=2)
3700           SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3701             exception);
3702     (void) DisplayImages(package_info->image_info,image,exception);
3703     (void) CatchImageException(image);
3704
3705   PerlException:
3706     if (package_info != (struct PackageInfo *) NULL)
3707       DestroyPackageInfo(package_info);
3708     InheritPerlException(exception,perl_exception);
3709     exception=DestroyExceptionInfo(exception);
3710     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3711     SvPOK_on(perl_exception);
3712     ST(0)=sv_2mortal(perl_exception);
3713     XSRETURN(1);
3714   }
3715 \f
3716 #
3717 ###############################################################################
3718 #                                                                             #
3719 #                                                                             #
3720 #                                                                             #
3721 #   E v a l u a t e I m a g e s                                               #
3722 #                                                                             #
3723 #                                                                             #
3724 #                                                                             #
3725 ###############################################################################
3726 #
3727 #
3728 void
3729 EvaluateImages(ref)
3730   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
3731   ALIAS:
3732     EvaluateImages   = 1
3733     evaluateimages   = 2
3734   PPCODE:
3735   {
3736     AV
3737       *av;
3738
3739     char
3740       *attribute,
3741       *p;
3742
3743     ExceptionInfo
3744       *exception;
3745
3746     HV
3747       *hv;
3748
3749     Image
3750       *image;
3751
3752     MagickEvaluateOperator
3753       op;
3754
3755     register ssize_t
3756       i;
3757
3758     struct PackageInfo
3759       *info;
3760
3761     SV
3762       *perl_exception,
3763       *reference,
3764       *rv,
3765       *sv;
3766
3767     PERL_UNUSED_VAR(ref);
3768     PERL_UNUSED_VAR(ix);
3769     exception=AcquireExceptionInfo();
3770     perl_exception=newSVpv("",0);
3771     sv=NULL;
3772     if (sv_isobject(ST(0)) == 0)
3773       {
3774         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3775           PackageName);
3776         goto PerlException;
3777       }
3778     reference=SvRV(ST(0));
3779     hv=SvSTASH(reference);
3780     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3781     if (image == (Image *) NULL)
3782       {
3783         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3784           PackageName);
3785         goto PerlException;
3786       }
3787     op=MeanEvaluateOperator;
3788     if (items == 2)
3789       {
3790         ssize_t
3791           in;
3792
3793         in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
3794           SvPV(ST(1),na));
3795         if (in < 0)
3796           {
3797             ThrowPerlException(exception,OptionError,"UnrecognizedType",
3798               SvPV(ST(1),na));
3799             return;
3800           }
3801         op=(MagickEvaluateOperator) in;
3802       }
3803     else
3804       for (i=2; i < items; i+=2)
3805       {
3806         attribute=(char *) SvPV(ST(i-1),na);
3807         switch (*attribute)
3808         {
3809           case 'O':
3810           case 'o':
3811           {
3812             if (LocaleCompare(attribute,"operator") == 0)
3813               {
3814                 ssize_t
3815                   in;
3816
3817                 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3818                   MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
3819                 if (in < 0)
3820                   {
3821                     ThrowPerlException(exception,OptionError,"UnrecognizedType",
3822                       SvPV(ST(i),na));
3823                     return;
3824                   }
3825                 op=(MagickEvaluateOperator) in;
3826                 break;
3827               }
3828             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3829               attribute);
3830             break;
3831           }
3832           default:
3833           {
3834             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3835               attribute);
3836             break;
3837           }
3838         }
3839       }
3840     image=EvaluateImages(image,op,exception);
3841     if (image == (Image *) NULL)
3842       goto PerlException;
3843     /*
3844       Create blessed Perl array for the returned image.
3845     */
3846     av=newAV();
3847     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3848     SvREFCNT_dec(av);
3849     AddImageToRegistry(sv,image);
3850     rv=newRV(sv);
3851     av_push(av,sv_bless(rv,hv));
3852     SvREFCNT_dec(sv);
3853     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3854     (void) FormatLocaleString(info->image_info->filename,MaxTextExtent,
3855       "evaluate-%.*s",(int) (MaxTextExtent-9),
3856       ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3857     (void) CopyMagickString(image->filename,info->image_info->filename,
3858       MaxTextExtent);
3859     SetImageInfo(info->image_info,0,exception);
3860     exception=DestroyExceptionInfo(exception);
3861     SvREFCNT_dec(perl_exception);
3862     XSRETURN(1);
3863
3864   PerlException:
3865     InheritPerlException(exception,perl_exception);
3866     exception=DestroyExceptionInfo(exception);
3867     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3868     SvPOK_on(perl_exception);
3869     ST(0)=sv_2mortal(perl_exception);
3870     XSRETURN(1);
3871   }
3872 \f
3873 #
3874 ###############################################################################
3875 #                                                                             #
3876 #                                                                             #
3877 #                                                                             #
3878 #   F e a t u r e s                                                           #
3879 #                                                                             #
3880 #                                                                             #
3881 #                                                                             #
3882 ###############################################################################
3883 #
3884 #
3885 void
3886 Features(ref,...)
3887   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
3888   ALIAS:
3889     FeaturesImage = 1
3890     features      = 2
3891     featuresimage = 3
3892   PPCODE:
3893   {
3894 #define ChannelFeatures(channel,direction) \
3895 { \
3896   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3897     channel_features[channel].angular_second_moment[direction]); \
3898   PUSHs(sv_2mortal(newSVpv(message,0))); \
3899   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3900     channel_features[channel].contrast[direction]); \
3901   PUSHs(sv_2mortal(newSVpv(message,0))); \
3902   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3903     channel_features[channel].contrast[direction]); \
3904   PUSHs(sv_2mortal(newSVpv(message,0))); \
3905   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3906     channel_features[channel].variance_sum_of_squares[direction]); \
3907   PUSHs(sv_2mortal(newSVpv(message,0))); \
3908   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3909     channel_features[channel].inverse_difference_moment[direction]); \
3910   PUSHs(sv_2mortal(newSVpv(message,0))); \
3911   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3912     channel_features[channel].sum_average[direction]); \
3913   PUSHs(sv_2mortal(newSVpv(message,0))); \
3914   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3915     channel_features[channel].sum_variance[direction]); \
3916   PUSHs(sv_2mortal(newSVpv(message,0))); \
3917   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3918     channel_features[channel].sum_entropy[direction]); \
3919   PUSHs(sv_2mortal(newSVpv(message,0))); \
3920   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3921     channel_features[channel].entropy[direction]); \
3922   PUSHs(sv_2mortal(newSVpv(message,0))); \
3923   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3924     channel_features[channel].difference_variance[direction]); \
3925   PUSHs(sv_2mortal(newSVpv(message,0))); \
3926   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3927     channel_features[channel].difference_entropy[direction]); \
3928   PUSHs(sv_2mortal(newSVpv(message,0))); \
3929   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3930     channel_features[channel].measure_of_correlation_1[direction]); \
3931   PUSHs(sv_2mortal(newSVpv(message,0))); \
3932   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3933     channel_features[channel].measure_of_correlation_2[direction]); \
3934   PUSHs(sv_2mortal(newSVpv(message,0))); \
3935   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3936     channel_features[channel].maximum_correlation_coefficient[direction]); \
3937   PUSHs(sv_2mortal(newSVpv(message,0))); \
3938 }
3939
3940     AV
3941       *av;
3942
3943     char
3944       *attribute,
3945       message[MaxTextExtent];
3946
3947     ChannelFeatures
3948       *channel_features;
3949
3950     double
3951       distance;
3952
3953     ExceptionInfo
3954       *exception;
3955
3956     Image
3957       *image;
3958
3959     register ssize_t
3960       i;
3961
3962     ssize_t
3963       count;
3964
3965     struct PackageInfo
3966       *info;
3967
3968     SV
3969       *perl_exception,
3970       *reference;
3971
3972     PERL_UNUSED_VAR(ref);
3973     PERL_UNUSED_VAR(ix);
3974     exception=AcquireExceptionInfo();
3975     perl_exception=newSVpv("",0);
3976     av=NULL;
3977     if (sv_isobject(ST(0)) == 0)
3978       {
3979         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3980           PackageName);
3981         goto PerlException;
3982       }
3983     reference=SvRV(ST(0));
3984     av=newAV();
3985     SvREFCNT_dec(av);
3986     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3987     if (image == (Image *) NULL)
3988       {
3989         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3990           PackageName);
3991         goto PerlException;
3992       }
3993     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3994     distance=1;
3995     for (i=2; i < items; i+=2)
3996     {
3997       attribute=(char *) SvPV(ST(i-1),na);
3998       switch (*attribute)
3999       {
4000         case 'D':
4001         case 'd':
4002         {
4003           if (LocaleCompare(attribute,"distance") == 0)
4004             {
4005               distance=StringToLong((char *) SvPV(ST(1),na));
4006               break;
4007             }
4008           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4009             attribute);
4010           break;
4011         }
4012         default:
4013         {
4014           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4015             attribute);
4016           break;
4017         }
4018       }
4019     }
4020     count=0;
4021     for ( ; image; image=image->next)
4022     {
4023       channel_features=GetImageFeatures(image,distance,exception);
4024       if (channel_features == (ChannelFeatures *) NULL)
4025         continue;
4026       count++;
4027       EXTEND(sp,75*count);
4028       for (i=0; i < 4; i++)
4029       {
4030         ChannelFeatures(RedChannel,i);
4031         ChannelFeatures(GreenChannel,i);
4032         ChannelFeatures(BlueChannel,i);
4033         if (image->colorspace == CMYKColorspace)
4034           ChannelFeatures(BlackChannel,i);
4035         if (image->alpha_trait == BlendPixelTrait)
4036           ChannelFeatures(AlphaChannel,i);
4037       }
4038       channel_features=(ChannelFeatures *)
4039         RelinquishMagickMemory(channel_features);
4040     }
4041
4042   PerlException:
4043     InheritPerlException(exception,perl_exception);
4044     exception=DestroyExceptionInfo(exception);
4045     SvREFCNT_dec(perl_exception);
4046   }
4047 \f
4048 #
4049 ###############################################################################
4050 #                                                                             #
4051 #                                                                             #
4052 #                                                                             #
4053 #   F l a t t e n                                                             #
4054 #                                                                             #
4055 #                                                                             #
4056 #                                                                             #
4057 ###############################################################################
4058 #
4059 #
4060 void
4061 Flatten(ref)
4062   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
4063   ALIAS:
4064     FlattenImage   = 1
4065     flatten        = 2
4066     flattenimage   = 3
4067   PPCODE:
4068   {
4069     AV
4070       *av;
4071
4072     char
4073       *attribute,
4074       *p;
4075
4076     ExceptionInfo
4077       *exception;
4078
4079     HV
4080       *hv;
4081
4082     Image
4083       *image;
4084
4085     PixelInfo
4086       background_color;
4087
4088     register ssize_t
4089       i;
4090
4091     struct PackageInfo
4092       *info;
4093
4094     SV
4095       *perl_exception,
4096       *reference,
4097       *rv,
4098       *sv;
4099
4100     PERL_UNUSED_VAR(ref);
4101     PERL_UNUSED_VAR(ix);
4102     exception=AcquireExceptionInfo();
4103     perl_exception=newSVpv("",0);
4104     sv=NULL;
4105     if (sv_isobject(ST(0)) == 0)
4106       {
4107         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4108           PackageName);
4109         goto PerlException;
4110       }
4111     reference=SvRV(ST(0));
4112     hv=SvSTASH(reference);
4113     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4114     if (image == (Image *) NULL)
4115       {
4116         ThrowPerlException(exception,OptionError,"NoImagesDefined",
4117           PackageName);
4118         goto PerlException;
4119       }
4120     background_color=image->background_color;
4121     if (items == 2)
4122       (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4123         &background_color,exception);
4124     else
4125       for (i=2; i < items; i+=2)
4126       {
4127         attribute=(char *) SvPV(ST(i-1),na);
4128         switch (*attribute)
4129         {
4130           case 'B':
4131           case 'b':
4132           {
4133             if (LocaleCompare(attribute,"background") == 0)
4134               {
4135                 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4136                   AllCompliance,&background_color,exception);
4137                 break;
4138               }
4139             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4140               attribute);
4141             break;
4142           }
4143           default:
4144           {
4145             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4146               attribute);
4147             break;
4148           }
4149         }
4150       }
4151     image->background_color=background_color;
4152     image=MergeImageLayers(image,FlattenLayer,exception);
4153     if (image == (Image *) NULL)
4154       goto PerlException;
4155     /*
4156       Create blessed Perl array for the returned image.
4157     */
4158     av=newAV();
4159     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4160     SvREFCNT_dec(av);
4161     AddImageToRegistry(sv,image);
4162     rv=newRV(sv);
4163     av_push(av,sv_bless(rv,hv));
4164     SvREFCNT_dec(sv);
4165     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4166     (void) FormatLocaleString(info->image_info->filename,MaxTextExtent,
4167       "flatten-%.*s",(int) (MaxTextExtent-9),
4168       ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4169     (void) CopyMagickString(image->filename,info->image_info->filename,
4170       MaxTextExtent);
4171     SetImageInfo(info->image_info,0,exception);
4172     exception=DestroyExceptionInfo(exception);
4173     SvREFCNT_dec(perl_exception);
4174     XSRETURN(1);
4175
4176   PerlException:
4177     InheritPerlException(exception,perl_exception);
4178     exception=DestroyExceptionInfo(exception);
4179     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4180     SvPOK_on(perl_exception);  /* return messages in string context */
4181     ST(0)=sv_2mortal(perl_exception);
4182     XSRETURN(1);
4183   }
4184 \f
4185 #
4186 ###############################################################################
4187 #                                                                             #
4188 #                                                                             #
4189 #                                                                             #
4190 #   F x                                                                       #
4191 #                                                                             #
4192 #                                                                             #
4193 #                                                                             #
4194 ###############################################################################
4195 #
4196 #
4197 void
4198 Fx(ref,...)
4199   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
4200   ALIAS:
4201     FxImage  = 1
4202     fx       = 2
4203     fximage  = 3
4204   PPCODE:
4205   {
4206     AV
4207       *av;
4208
4209     char
4210       *attribute,
4211       expression[MaxTextExtent];
4212
4213     ChannelType
4214       channel,
4215       channel_mask;
4216
4217     ExceptionInfo
4218       *exception;
4219
4220     HV
4221       *hv;
4222
4223     Image
4224       *image;
4225
4226     register ssize_t
4227       i;
4228
4229     struct PackageInfo
4230       *info;
4231
4232     SV
4233       *av_reference,
4234       *perl_exception,
4235       *reference,
4236       *rv,
4237       *sv;
4238
4239     PERL_UNUSED_VAR(ref);
4240     PERL_UNUSED_VAR(ix);
4241     exception=AcquireExceptionInfo();
4242     perl_exception=newSVpv("",0);
4243     sv=NULL;
4244     attribute=NULL;
4245     av=NULL;
4246     if (sv_isobject(ST(0)) == 0)
4247       {
4248         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4249           PackageName);
4250         goto PerlException;
4251       }
4252     reference=SvRV(ST(0));
4253     hv=SvSTASH(reference);
4254     av=newAV();
4255     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4256     SvREFCNT_dec(av);
4257     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4258     if (image == (Image *) NULL)
4259       {
4260         ThrowPerlException(exception,OptionError,"NoImagesDefined",
4261           PackageName);
4262         goto PerlException;
4263       }
4264     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4265     /*
4266       Get options.
4267     */
4268     channel=DefaultChannels;
4269     (void) CopyMagickString(expression,"u",MaxTextExtent);
4270     if (items == 2)
4271       (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MaxTextExtent);
4272     else
4273       for (i=2; i < items; i+=2)
4274       {
4275         attribute=(char *) SvPV(ST(i-1),na);
4276         switch (*attribute)
4277         {
4278           case 'C':
4279           case 'c':
4280           {
4281             if (LocaleCompare(attribute,"channel") == 0)
4282               {
4283                 ssize_t
4284                   option;
4285
4286                 option=ParseChannelOption(SvPV(ST(i),na));
4287                 if (option < 0)
4288                   {
4289                     ThrowPerlException(exception,OptionError,
4290                       "UnrecognizedType",SvPV(ST(i),na));
4291                     return;
4292                   }
4293                 channel=(ChannelType) option;
4294                 break;
4295               }
4296             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4297               attribute);
4298             break;
4299           }
4300           case 'E':
4301           case 'e':
4302           {
4303             if (LocaleCompare(attribute,"expression") == 0)
4304               {
4305                 (void) CopyMagickString(expression,SvPV(ST(i),na),
4306                   MaxTextExtent);
4307                 break;
4308               }
4309             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4310               attribute);
4311             break;
4312           }
4313           default:
4314           {
4315             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4316               attribute);
4317             break;
4318           }
4319         }
4320       }
4321     channel_mask=SetImageChannelMask(image,channel);
4322     image=FxImage(image,expression,exception);
4323     if (image != (Image *) NULL)
4324       (void) SetImageChannelMask(image,channel_mask);
4325     if (image == (Image *) NULL)
4326       goto PerlException;
4327     for ( ; image; image=image->next)
4328     {
4329       AddImageToRegistry(sv,image);
4330       rv=newRV(sv);
4331       av_push(av,sv_bless(rv,hv));
4332       SvREFCNT_dec(sv);
4333     }
4334     exception=DestroyExceptionInfo(exception);
4335     ST(0)=av_reference;
4336     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
4337     XSRETURN(1);
4338
4339   PerlException:
4340     InheritPerlException(exception,perl_exception);
4341     exception=DestroyExceptionInfo(exception);
4342     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4343     SvPOK_on(perl_exception);
4344     ST(0)=sv_2mortal(perl_exception);
4345     XSRETURN(1);
4346   }
4347 \f
4348 #
4349 ###############################################################################
4350 #                                                                             #
4351 #                                                                             #
4352 #                                                                             #
4353 #   G e t                                                                     #
4354 #                                                                             #
4355 #                                                                             #
4356 #                                                                             #
4357 ###############################################################################
4358 #
4359 #
4360 void
4361 Get(ref,...)
4362   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
4363   ALIAS:
4364     GetAttributes = 1
4365     GetAttribute  = 2
4366     get           = 3
4367     getattributes = 4
4368     getattribute  = 5
4369   PPCODE:
4370   {
4371     char
4372       *attribute,
4373       color[MaxTextExtent];
4374
4375     const char
4376       *value;
4377
4378     ExceptionInfo
4379       *exception;
4380
4381     Image
4382       *image;
4383
4384     long
4385       j;
4386
4387     register ssize_t
4388       i;
4389
4390     struct PackageInfo
4391       *info;
4392
4393     SV
4394       *perl_exception,
4395       *reference,
4396       *s;
4397
4398     PERL_UNUSED_VAR(ref);
4399     PERL_UNUSED_VAR(ix);
4400     exception=AcquireExceptionInfo();
4401     perl_exception=newSVpv("",0);
4402     if (sv_isobject(ST(0)) == 0)
4403       {
4404         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4405           PackageName);
4406         XSRETURN_EMPTY;
4407       }
4408     reference=SvRV(ST(0));
4409     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4410     if (image == (Image *) NULL && !info)
4411       XSRETURN_EMPTY;
4412     EXTEND(sp,items);
4413     for (i=1; i < items; i++)
4414     {
4415       attribute=(char *) SvPV(ST(i),na);
4416       s=NULL;
4417       switch (*attribute)
4418       {
4419         case 'A':
4420         case 'a':
4421         {
4422           if (LocaleCompare(attribute,"adjoin") == 0)
4423             {
4424               if (info)
4425                 s=newSViv((ssize_t) info->image_info->adjoin);
4426               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4427               continue;
4428             }
4429           if (LocaleCompare(attribute,"antialias") == 0)
4430             {
4431               if (info)
4432                 s=newSViv((ssize_t) info->image_info->antialias);
4433               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4434               continue;
4435             }
4436           if (LocaleCompare(attribute,"area") == 0)
4437             {
4438               s=newSViv(GetMagickResource(AreaResource));
4439               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4440               continue;
4441             }
4442           if (LocaleCompare(attribute,"attenuate") == 0)
4443             {
4444               const char
4445                 *value;
4446
4447               value=GetImageProperty(image,attribute,exception);
4448               if (value != (const char *) NULL)
4449                 s=newSVpv(value,0);
4450               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4451               continue;
4452             }
4453           if (LocaleCompare(attribute,"authenticate") == 0)
4454             {
4455               if (info)
4456                 {
4457                   const char
4458                     *option;
4459
4460                   option=GetImageOption(info->image_info,attribute);
4461                   if (option != (const char *) NULL)
4462                     s=newSVpv(option,0);
4463                 }
4464               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4465               continue;
4466             }
4467           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4468             attribute);
4469           break;
4470         }
4471         case 'B':
4472         case 'b':
4473         {
4474           if (LocaleCompare(attribute,"background") == 0)
4475             {
4476               if (image == (Image *) NULL)
4477                 break;
4478               (void) FormatLocaleString(color,MaxTextExtent,
4479                 "%.20g,%.20g,%.20g,%.20g",image->background_color.red,
4480                 image->background_color.green,image->background_color.blue,
4481                 image->background_color.alpha);
4482               s=newSVpv(color,0);
4483               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4484               continue;
4485             }
4486           if (LocaleCompare(attribute,"base-columns") == 0)
4487             {
4488               if (image != (Image *) NULL)
4489                 s=newSViv((ssize_t) image->magick_columns);
4490               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4491               continue;
4492             }
4493           if (LocaleCompare(attribute,"base-filename") == 0)
4494             {
4495               if (image != (Image *) NULL)
4496                 s=newSVpv(image->magick_filename,0);
4497               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4498               continue;
4499             }
4500           if (LocaleCompare(attribute,"base-height") == 0)
4501             {
4502               if (image != (Image *) NULL)
4503                 s=newSViv((ssize_t) image->magick_rows);
4504               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4505               continue;
4506             }
4507           if (LocaleCompare(attribute,"base-rows") == 0)
4508             {
4509               if (image != (Image *) NULL)
4510                 s=newSViv((ssize_t) image->magick_rows);
4511               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4512               continue;
4513             }
4514           if (LocaleCompare(attribute,"base-width") == 0)
4515             {
4516               if (image != (Image *) NULL)
4517                 s=newSViv((ssize_t) image->magick_columns);
4518               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4519               continue;
4520             }
4521           if (LocaleCompare(attribute,"blue-primary") == 0)
4522             {
4523               if (image == (Image *) NULL)
4524                 break;
4525               (void) FormatLocaleString(color,MaxTextExtent,"%.15g,%.15g",
4526                 image->chromaticity.blue_primary.x,
4527                 image->chromaticity.blue_primary.y);
4528               s=newSVpv(color,0);
4529               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4530               continue;
4531             }
4532           if (LocaleCompare(attribute,"bordercolor") == 0)
4533             {
4534               if (image == (Image *) NULL)
4535                 break;
4536               (void) FormatLocaleString(color,MaxTextExtent,
4537                 "%.20g,%.20g,%.20g,%.20g",image->border_color.red,
4538                 image->border_color.green,image->border_color.blue,
4539                 image->border_color.alpha);
4540               s=newSVpv(color,0);
4541               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4542               continue;
4543             }
4544           if (LocaleCompare(attribute,"bounding-box") == 0)
4545             {
4546               char
4547                 geometry[MaxTextExtent];
4548
4549               RectangleInfo
4550                 page;
4551
4552               if (image == (Image *) NULL)
4553                 break;
4554               page=GetImageBoundingBox(image,exception);
4555               (void) FormatLocaleString(geometry,MaxTextExtent,
4556                 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4557                 page.height,(double) page.x,(double) page.y);
4558               s=newSVpv(geometry,0);
4559               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4560               continue;
4561             }
4562           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4563             attribute);
4564           break;
4565         }
4566         case 'C':
4567         case 'c':
4568         {
4569           if (LocaleCompare(attribute,"class") == 0)
4570             {
4571               if (image == (Image *) NULL)
4572                 break;
4573               s=newSViv(image->storage_class);
4574               (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4575                 image->storage_class));
4576               SvIOK_on(s);
4577               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4578               continue;
4579             }
4580           if (LocaleCompare(attribute,"clip-mask") == 0)
4581             {
4582               if (image != (Image *) NULL)
4583                 {
4584                   Image
4585                     *mask_image;
4586
4587                   SV
4588                     *sv;
4589
4590                   sv=NULL;
4591                   if (image->mask == MagickFalse)
4592                     ClipImage(image,exception);
4593                   mask_image=GetImageMask(image,exception);
4594                   if (mask_image != (Image *) NULL)
4595                     {
4596                       AddImageToRegistry(sv,mask_image);
4597                       s=sv_bless(newRV(sv),SvSTASH(reference));
4598                     }
4599                 }
4600               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4601               continue;
4602             }
4603           if (LocaleCompare(attribute,"clip-path") == 0)
4604             {
4605               if (image != (Image *) NULL)
4606                 {
4607                   Image
4608                     *mask_image;
4609
4610                   SV
4611                     *sv;
4612
4613                   sv=NULL;
4614                   if (image->mask != MagickFalse)
4615                     ClipImage(image,exception);
4616                   mask_image=GetImageMask(image,exception);
4617                   if (mask_image != (Image *) NULL)
4618                     {
4619                       AddImageToRegistry(sv,mask_image);
4620                       s=sv_bless(newRV(sv),SvSTASH(reference));
4621                     }
4622                 }
4623               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4624               continue;
4625             }
4626           if (LocaleCompare(attribute,"compression") == 0)
4627             {
4628               j=info ? info->image_info->compression : image ?
4629                 image->compression : UndefinedCompression;
4630               if (info)
4631                 if (info->image_info->compression == UndefinedCompression)
4632                   j=image->compression;
4633               s=newSViv(j);
4634               (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4635                 j));
4636               SvIOK_on(s);
4637               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4638               continue;
4639             }
4640           if (LocaleCompare(attribute,"colorspace") == 0)
4641             {
4642               j=image ? image->colorspace : RGBColorspace;
4643               s=newSViv(j);
4644               (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4645                 j));
4646               SvIOK_on(s);
4647               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4648               continue;
4649             }
4650           if (LocaleCompare(attribute,"colors") == 0)
4651             {
4652               if (image != (Image *) NULL)
4653                 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4654                   exception));
4655               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4656               continue;
4657             }
4658           if (LocaleNCompare(attribute,"colormap",8) == 0)
4659             {
4660               int
4661                 items;
4662
4663               if (image == (Image *) NULL || !image->colormap)
4664                 break;
4665               j=0;
4666               items=sscanf(attribute,"%*[^[][%ld",&j);
4667               (void) items;
4668               if (j > (ssize_t) image->colors)
4669                 j%=image->colors;
4670               (void) FormatLocaleString(color,MaxTextExtent,
4671                 "%.20g,%.20g,%.20g,%.20g",image->colormap[j].red,
4672                 image->colormap[j].green,image->colormap[j].blue,
4673                 image->colormap[j].alpha);
4674               s=newSVpv(color,0);
4675               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4676               continue;
4677             }
4678           if (LocaleCompare(attribute,"columns") == 0)
4679             {
4680               if (image != (Image *) NULL)
4681                 s=newSViv((ssize_t) image->columns);
4682               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4683               continue;
4684             }
4685           if (LocaleCompare(attribute,"comment") == 0)
4686             {
4687               const char
4688                 *value;
4689
4690               value=GetImageProperty(image,attribute,exception);
4691               if (value != (const char *) NULL)
4692                 s=newSVpv(value,0);
4693               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4694               continue;
4695             }
4696           if (LocaleCompare(attribute,"copyright") == 0)
4697             {
4698               s=newSVpv(GetMagickCopyright(),0);
4699               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4700               continue;
4701             }
4702           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4703             attribute);
4704           break;
4705         }
4706         case 'D':
4707         case 'd':
4708         {
4709           if (LocaleCompare(attribute,"density") == 0)
4710             {
4711               char
4712                 geometry[MaxTextExtent];
4713
4714               if (image == (Image *) NULL)
4715                 break;
4716               (void) FormatLocaleString(geometry,MaxTextExtent,"%.15gx%.15g",
4717                 image->resolution.x,image->resolution.y);
4718               s=newSVpv(geometry,0);
4719               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4720               continue;
4721             }
4722           if (LocaleCompare(attribute,"delay") == 0)
4723             {
4724               if (image != (Image *) NULL)
4725                 s=newSViv((ssize_t) image->delay);
4726               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4727               continue;
4728             }
4729           if (LocaleCompare(attribute,"depth") == 0)
4730             {
4731               s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4732               if (image != (Image *) NULL)
4733                 s=newSViv((ssize_t) GetImageDepth(image,exception));
4734               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4735               continue;
4736             }
4737           if (LocaleCompare(attribute,"directory") == 0)
4738             {
4739               if (image && image->directory)
4740                 s=newSVpv(image->directory,0);
4741               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4742               continue;
4743             }
4744           if (LocaleCompare(attribute,"dispose") == 0)
4745             {
4746               if (image == (Image *) NULL)
4747                 break;
4748
4749               s=newSViv(image->dispose);
4750               (void) sv_setpv(s,
4751                 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
4752               SvIOK_on(s);
4753               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4754               continue;
4755             }
4756           if (LocaleCompare(attribute,"disk") == 0)
4757             {
4758               s=newSViv(GetMagickResource(DiskResource));
4759               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4760               continue;
4761             }
4762           if (LocaleCompare(attribute,"dither") == 0)
4763             {
4764               if (info)
4765                 s=newSViv((ssize_t) info->image_info->dither);
4766               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4767               continue;
4768             }
4769           if (LocaleCompare(attribute,"display") == 0)  /* same as server */
4770             {
4771               if (info && info->image_info->server_name)
4772                 s=newSVpv(info->image_info->server_name,0);
4773               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4774               continue;
4775             }
4776           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4777             attribute);
4778           break;
4779         }
4780         case 'E':
4781         case 'e':
4782         {
4783           if (LocaleCompare(attribute,"elapsed-time") == 0)
4784             {
4785               if (image != (Image *) NULL)
4786                 s=newSVnv(GetElapsedTime(&image->timer));
4787               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4788               continue;
4789             }
4790           if (LocaleCompare(attribute,"endian") == 0)
4791             {
4792               j=info ? info->image_info->endian : image ? image->endian :
4793                 UndefinedEndian;
4794               s=newSViv(j);
4795               (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
4796               SvIOK_on(s);
4797               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4798               continue;
4799             }
4800           if (LocaleCompare(attribute,"error") == 0)
4801             {
4802               if (image != (Image *) NULL)
4803                 s=newSVnv(image->error.mean_error_per_pixel);
4804               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4805               continue;
4806             }
4807           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4808             attribute);
4809           break;
4810         }
4811         case 'F':
4812         case 'f':
4813         {
4814           if (LocaleCompare(attribute,"filesize") == 0)
4815             {
4816               if (image != (Image *) NULL)
4817                 s=newSViv((ssize_t) GetBlobSize(image));
4818               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4819               continue;
4820             }
4821           if (LocaleCompare(attribute,"filename") == 0)
4822             {
4823               if (info && info->image_info->filename &&
4824                   *info->image_info->filename)
4825                 s=newSVpv(info->image_info->filename,0);
4826               if (image != (Image *) NULL)
4827                 s=newSVpv(image->filename,0);
4828               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4829               continue;
4830             }
4831           if (LocaleCompare(attribute,"filter") == 0)
4832             {
4833               s=image ? newSViv(image->filter) : newSViv(0);
4834               (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
4835                 image->filter));
4836               SvIOK_on(s);
4837               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4838               continue;
4839             }
4840           if (LocaleCompare(attribute,"font") == 0)
4841             {
4842               if (info && info->image_info->font)
4843                 s=newSVpv(info->image_info->font,0);
4844               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4845               continue;
4846             }
4847           if (LocaleCompare(attribute,"foreground") == 0)
4848             continue;
4849           if (LocaleCompare(attribute,"format") == 0)
4850             {
4851               const MagickInfo
4852                 *magick_info;
4853
4854               magick_info=(const MagickInfo *) NULL;
4855               if (info && (*info->image_info->magick != '\0'))
4856                 magick_info=GetMagickInfo(info->image_info->magick,exception);
4857               if (image != (Image *) NULL)
4858                 magick_info=GetMagickInfo(image->magick,exception);
4859               if ((magick_info != (const MagickInfo *) NULL) &&
4860                   (*magick_info->description != '\0'))
4861                 s=newSVpv((char *) magick_info->description,0);
4862               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4863               continue;
4864             }
4865           if (LocaleCompare(attribute,"fuzz") == 0)
4866             {
4867               if (info)
4868                 s=newSVnv(info->image_info->fuzz);
4869               if (image != (Image *) NULL)
4870                 s=newSVnv(image->fuzz);
4871               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4872               continue;
4873             }
4874           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4875             attribute);
4876           break;
4877         }
4878         case 'G':
4879         case 'g':
4880         {
4881           if (LocaleCompare(attribute,"gamma") == 0)
4882             {
4883               if (image != (Image *) NULL)
4884                 s=newSVnv(image->gamma);
4885               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4886               continue;
4887             }
4888           if (LocaleCompare(attribute,"geometry") == 0)
4889             {
4890               if (image && image->geometry)
4891                 s=newSVpv(image->geometry,0);
4892               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4893               continue;
4894             }
4895           if (LocaleCompare(attribute,"gravity") == 0)
4896             {
4897               s=image ? newSViv(image->gravity) : newSViv(0);
4898               (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
4899                 image->gravity));
4900               SvIOK_on(s);
4901               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4902               continue;
4903             }
4904           if (LocaleCompare(attribute,"green-primary") == 0)
4905             {
4906               if (image == (Image *) NULL)
4907                 break;
4908               (void) FormatLocaleString(color,MaxTextExtent,"%.15g,%.15g",
4909                 image->chromaticity.green_primary.x,
4910                 image->chromaticity.green_primary.y);
4911               s=newSVpv(color,0);
4912               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4913               continue;
4914             }
4915           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4916             attribute);
4917           break;
4918         }
4919         case 'H':
4920         case 'h':
4921         {
4922           if (LocaleCompare(attribute,"height") == 0)
4923             {
4924               if (image != (Image *) NULL)
4925                 s=newSViv((ssize_t) image->rows);
4926               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4927               continue;
4928             }
4929           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4930             attribute);
4931           break;
4932         }
4933         case 'I':
4934         case 'i':
4935         {
4936           if (LocaleCompare(attribute,"icc") == 0)
4937             {
4938               if (image != (Image *) NULL)
4939                 {
4940                   const StringInfo
4941                     *profile;
4942
4943                   profile=GetImageProfile(image,"icc");
4944                   if (profile != (StringInfo *) NULL)
4945                     s=newSVpv((const char *) GetStringInfoDatum(profile),
4946                       GetStringInfoLength(profile));
4947                 }
4948               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4949               continue;
4950             }
4951           if (LocaleCompare(attribute,"icm") == 0)
4952             {
4953               if (image != (Image *) NULL)
4954                 {
4955                   const StringInfo
4956                     *profile;
4957
4958                   profile=GetImageProfile(image,"icm");
4959                   if (profile != (const StringInfo *) NULL)
4960                     s=newSVpv((const char *) GetStringInfoDatum(profile),
4961                       GetStringInfoLength(profile));
4962                 }
4963               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4964               continue;
4965             }
4966           if (LocaleCompare(attribute,"id") == 0)
4967             {
4968               if (image != (Image *) NULL)
4969                 {
4970                   char
4971                     key[MaxTextExtent];
4972
4973                   MagickBooleanType
4974                     status;
4975
4976                   static ssize_t
4977                     id = 0;
4978
4979                   (void) FormatLocaleString(key,MaxTextExtent,"%.20g\n",(double)
4980                     id);
4981                   status=SetImageRegistry(ImageRegistryType,key,image,
4982                     exception);
4983                   (void) status;
4984                   s=newSViv(id++);
4985                 }
4986               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4987               continue;
4988             }
4989           if (LocaleNCompare(attribute,"index",5) == 0)
4990             {
4991               char
4992                 name[MaxTextExtent];
4993
4994               int
4995                 items;
4996
4997               long
4998                 x,
4999                 y;
5000
5001               register const Quantum
5002                 *p;
5003
5004               CacheView
5005                 *image_view;
5006
5007               if (image == (Image *) NULL)
5008                 break;
5009               if (image->storage_class != PseudoClass)
5010                 break;
5011               x=0;
5012               y=0;
5013               items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5014               (void) items;
5015               image_view=AcquireVirtualCacheView(image,exception);
5016               p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5017               if (p != (const Quantum *) NULL)
5018                 {
5019                   (void) FormatLocaleString(name,MaxTextExtent,QuantumFormat,
5020                     GetPixelIndex(image,p));
5021                   s=newSVpv(name,0);
5022                   PUSHs(s ? sv_2mortal(s) : &sv_undef);
5023                 }
5024               image_view=DestroyCacheView(image_view);
5025               continue;
5026             }
5027           if (LocaleCompare(attribute,"iptc") == 0)
5028             {
5029               if (image != (Image *) NULL)
5030                 {
5031                   const StringInfo
5032                     *profile;
5033
5034                   profile=GetImageProfile(image,"iptc");
5035                   if (profile != (const StringInfo *) NULL)
5036                     s=newSVpv((const char *) GetStringInfoDatum(profile),
5037                       GetStringInfoLength(profile));
5038                 }
5039               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5040               continue;
5041             }
5042           if (LocaleCompare(attribute,"iterations") == 0)  /* same as loop */
5043             {
5044               if (image != (Image *) NULL)
5045                 s=newSViv((ssize_t) image->iterations);
5046               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5047               continue;
5048             }
5049           if (LocaleCompare(attribute,"interlace") == 0)
5050             {
5051               j=info ? info->image_info->interlace : image ? image->interlace :
5052                 UndefinedInterlace;
5053               s=newSViv(j);
5054               (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5055                 j));
5056               SvIOK_on(s);
5057               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5058               continue;
5059             }
5060           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5061             attribute);
5062           break;
5063         }
5064         case 'L':
5065         case 'l':
5066         {
5067           if (LocaleCompare(attribute,"label") == 0)
5068             {
5069               const char
5070                 *value;
5071
5072               if (image == (Image *) NULL)
5073                 break;
5074               value=GetImageProperty(image,"Label",exception);
5075               if (value != (const char *) NULL)
5076                 s=newSVpv(value,0);
5077               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5078               continue;
5079             }
5080           if (LocaleCompare(attribute,"loop") == 0)  /* same as iterations */
5081             {
5082               if (image != (Image *) NULL)
5083                 s=newSViv((ssize_t) image->iterations);
5084               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5085               continue;
5086             }
5087           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5088             attribute);
5089           break;
5090         }
5091         case 'M':
5092         case 'm':
5093         {
5094           if (LocaleCompare(attribute,"magick") == 0)
5095             {
5096               if (info && *info->image_info->magick)
5097                 s=newSVpv(info->image_info->magick,0);
5098               if (image != (Image *) NULL)
5099                 s=newSVpv(image->magick,0);
5100               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5101               continue;
5102             }
5103           if (LocaleCompare(attribute,"map") == 0)
5104             {
5105               s=newSViv(GetMagickResource(MapResource));
5106               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5107               continue;
5108             }
5109           if (LocaleCompare(attribute,"maximum-error") == 0)
5110             {
5111               if (image != (Image *) NULL)
5112                 s=newSVnv(image->error.normalized_maximum_error);
5113               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5114               continue;
5115             }
5116           if (LocaleCompare(attribute,"memory") == 0)
5117             {
5118               s=newSViv(GetMagickResource(MemoryResource));
5119               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5120               continue;
5121             }
5122           if (LocaleCompare(attribute,"mean-error") == 0)
5123             {
5124               if (image != (Image *) NULL)
5125                 s=newSVnv(image->error.normalized_mean_error);
5126               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5127               continue;
5128             }
5129           if (LocaleCompare(attribute,"mime") == 0)
5130             {
5131               if (info && *info->image_info->magick)
5132                 s=newSVpv(MagickToMime(info->image_info->magick),0);
5133               if (image != (Image *) NULL)
5134                 s=newSVpv(MagickToMime(image->magick),0);
5135               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5136               continue;
5137             }
5138           if (LocaleCompare(attribute,"mattecolor") == 0)
5139             {
5140               if (image == (Image *) NULL)
5141                 break;
5142               (void) FormatLocaleString(color,MaxTextExtent,
5143                 "%.20g,%.20g,%.20g,%.20g",image->matte_color.red,
5144                 image->matte_color.green,image->matte_color.blue,
5145                 image->matte_color.alpha);
5146               s=newSVpv(color,0);
5147               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5148               continue;
5149             }
5150           if (LocaleCompare(attribute,"matte") == 0)
5151             {
5152               if (image != (Image *) NULL)
5153                 s=newSViv((ssize_t) image->alpha_trait == BlendPixelTrait ?
5154                   1 : 0);
5155               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5156               continue;
5157             }
5158           if (LocaleCompare(attribute,"mime") == 0)
5159             {
5160               const char
5161                 *magick;
5162
5163               magick=NULL;
5164               if (info && *info->image_info->magick)
5165                 magick=info->image_info->magick;
5166               if (image != (Image *) NULL)
5167                 magick=image->magick;
5168               if (magick)
5169                 {
5170                   char
5171                     *mime;
5172
5173                   mime=MagickToMime(magick);
5174                   s=newSVpv(mime,0);
5175                   mime=(char *) RelinquishMagickMemory(mime);
5176                 }
5177               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5178               continue;
5179             }
5180           if (LocaleCompare(attribute,"monochrome") == 0)
5181             {
5182               if (image == (Image *) NULL)
5183                 continue;
5184               j=info ? info->image_info->monochrome :
5185                 IsImageMonochrome(image,exception);
5186               s=newSViv(j);
5187               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5188               continue;
5189             }
5190           if (LocaleCompare(attribute,"montage") == 0)
5191             {
5192               if (image && image->montage)
5193                 s=newSVpv(image->montage,0);
5194               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5195               continue;
5196             }
5197           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5198             attribute);
5199           break;
5200         }
5201         case 'O':
5202         case 'o':
5203         {
5204           if (LocaleCompare(attribute,"orientation") == 0)
5205             {
5206               j=info ? info->image_info->orientation : image ?
5207                 image->orientation : UndefinedOrientation;
5208               s=newSViv(j);
5209               (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5210                 j));
5211               SvIOK_on(s);
5212               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5213               continue;
5214             }
5215           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5216             attribute);
5217           break;
5218         }
5219         case 'P':
5220         case 'p':
5221         {
5222           if (LocaleCompare(attribute,"page") == 0)
5223             {
5224               if (info && info->image_info->page)
5225                 s=newSVpv(info->image_info->page,0);
5226               if (image != (Image *) NULL)
5227                 {
5228                   char
5229                     geometry[MaxTextExtent];
5230
5231                   (void) FormatLocaleString(geometry,MaxTextExtent,
5232                     "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5233                     (double) image->page.height,(double) image->page.x,(double)
5234                     image->page.y);
5235                   s=newSVpv(geometry,0);
5236                 }
5237               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5238               continue;
5239             }
5240           if (LocaleCompare(attribute,"page.x") == 0)
5241             {
5242               if (image != (Image *) NULL)
5243                 s=newSViv((ssize_t) image->page.x);
5244               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5245               continue;
5246             }
5247           if (LocaleCompare(attribute,"page.y") == 0)
5248             {
5249               if (image != (Image *) NULL)
5250                 s=newSViv((ssize_t) image->page.y);
5251               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5252               continue;
5253             }
5254           if (LocaleNCompare(attribute,"pixel",5) == 0)
5255             {
5256               char
5257                 tuple[MaxTextExtent];
5258
5259               int
5260                 items;
5261
5262               long
5263                 x,
5264                 y;
5265
5266               register const Quantum
5267                 *p;
5268
5269               if (image == (Image *) NULL)
5270                 break;
5271               x=0;
5272               y=0;
5273               items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5274               (void) items;
5275               p=GetVirtualPixels(image,x,y,1,1,exception);
5276               if (image->colorspace != CMYKColorspace)
5277                 (void) FormatLocaleString(tuple,MaxTextExtent,QuantumFormat ","
5278                   QuantumFormat "," QuantumFormat "," QuantumFormat,
5279                   GetPixelRed(image,p),GetPixelGreen(image,p),
5280                   GetPixelBlue(image,p),GetPixelAlpha(image,p));
5281               else
5282                 (void) FormatLocaleString(tuple,MaxTextExtent,QuantumFormat ","
5283                   QuantumFormat "," QuantumFormat "," QuantumFormat ","
5284                   QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5285                   GetPixelBlue(image,p),GetPixelBlack(image,p),
5286                   GetPixelAlpha(image,p));
5287               s=newSVpv(tuple,0);
5288               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5289               continue;
5290             }
5291           if (LocaleCompare(attribute,"pointsize") == 0)
5292             {
5293               if (info)
5294                 s=newSViv((ssize_t) info->image_info->pointsize);
5295               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5296               continue;
5297             }
5298           if (LocaleCompare(attribute,"preview") == 0)
5299             {
5300               s=newSViv(info->image_info->preview_type);
5301               (void) sv_setpv(s,CommandOptionToMnemonic(MagickPreviewOptions,
5302                 info->image_info->preview_type));
5303               SvIOK_on(s);
5304               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5305               continue;
5306             }
5307           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5308             attribute);
5309           break;
5310         }
5311         case 'Q':
5312         case 'q':
5313         {
5314           if (LocaleCompare(attribute,"quality") == 0)
5315             {
5316               if (info)
5317                 s=newSViv((ssize_t) info->image_info->quality);
5318               if (image != (Image *) NULL)
5319                 s=newSViv((ssize_t) image->quality);
5320               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5321               continue;
5322             }
5323           if (LocaleCompare(attribute,"quantum") == 0)
5324             {
5325               if (info)
5326                 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5327               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5328               continue;
5329             }
5330           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5331             attribute);
5332           break;
5333         }
5334         case 'R':
5335         case 'r':
5336         {
5337           if (LocaleCompare(attribute,"rendering-intent") == 0)
5338             {
5339               s=newSViv(image->rendering_intent);
5340               (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5341                 image->rendering_intent));
5342               SvIOK_on(s);
5343               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5344               continue;
5345             }
5346           if (LocaleCompare(attribute,"red-primary") == 0)
5347             {
5348               if (image == (Image *) NULL)
5349                 break;
5350               (void) FormatLocaleString(color,MaxTextExtent,"%.15g,%.15g",
5351                 image->chromaticity.red_primary.x,
5352                 image->chromaticity.red_primary.y);
5353               s=newSVpv(color,0);
5354               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5355               continue;
5356             }
5357           if (LocaleCompare(attribute,"rows") == 0)
5358             {
5359               if (image != (Image *) NULL)
5360                 s=newSViv((ssize_t) image->rows);
5361               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5362               continue;
5363             }
5364           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5365             attribute);
5366           break;
5367         }
5368         case 'S':
5369         case 's':
5370         {
5371           if (LocaleCompare(attribute,"sampling-factor") == 0)
5372             {
5373               if (info && info->image_info->sampling_factor)
5374                 s=newSVpv(info->image_info->sampling_factor,0);
5375               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5376               continue;
5377             }
5378           if (LocaleCompare(attribute,"server") == 0)  /* same as display */
5379             {
5380               if (info && info->image_info->server_name)
5381                 s=newSVpv(info->image_info->server_name,0);
5382               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5383               continue;
5384             }
5385           if (LocaleCompare(attribute,"size") == 0)
5386             {
5387               if (info && info->image_info->size)
5388                 s=newSVpv(info->image_info->size,0);
5389               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5390               continue;
5391             }
5392           if (LocaleCompare(attribute,"scene") == 0)
5393             {
5394               if (image != (Image *) NULL)
5395                 s=newSViv((ssize_t) image->scene);
5396               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5397               continue;
5398             }
5399           if (LocaleCompare(attribute,"scenes") == 0)
5400             {
5401               if (image != (Image *) NULL)
5402                 s=newSViv((ssize_t) info->image_info->number_scenes);
5403               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5404               continue;
5405             }
5406           if (LocaleCompare(attribute,"signature") == 0)
5407             {
5408               const char
5409                 *value;
5410
5411               if (image == (Image *) NULL)
5412                 break;
5413               (void) SignatureImage(image,exception);
5414               value=GetImageProperty(image,"Signature",exception);
5415               if (value != (const char *) NULL)
5416                 s=newSVpv(value,0);
5417               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5418               continue;
5419             }
5420           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5421             attribute);
5422           break;
5423         }
5424         case 'T':
5425         case 't':
5426         {
5427           if (LocaleCompare(attribute,"taint") == 0)
5428             {
5429               if (image != (Image *) NULL)
5430                 s=newSViv((ssize_t) IsTaintImage(image));
5431               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5432               continue;
5433             }
5434           if (LocaleCompare(attribute,"texture") == 0)
5435             {
5436               if (info && info->image_info->texture)
5437                 s=newSVpv(info->image_info->texture,0);
5438               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5439               continue;
5440             }
5441           if (LocaleCompare(attribute,"total-ink-density") == 0)
5442             {
5443               s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5444               if (image != (Image *) NULL)
5445                 s=newSVnv(GetImageTotalInkDensity(image,exception));
5446               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5447               continue;
5448             }
5449           if (LocaleCompare(attribute,"transparent-color") == 0)
5450             {
5451               if (image == (Image *) NULL)
5452                 break;
5453               (void) FormatLocaleString(color,MaxTextExtent,
5454                 "%.20g,%.20g,%.20g,%.20g",image->transparent_color.red,
5455                 image->transparent_color.green,image->transparent_color.blue,
5456                 image->transparent_color.alpha);
5457               s=newSVpv(color,0);
5458               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5459               continue;
5460             }
5461           if (LocaleCompare(attribute,"type") == 0)
5462             {
5463               if (image == (Image *) NULL)
5464                 break;
5465               j=(ssize_t) GetImageType(image,exception);
5466               s=newSViv(j);
5467               (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5468               SvIOK_on(s);
5469               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5470               continue;
5471             }
5472           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5473             attribute);
5474           break;
5475         }
5476         case 'U':
5477         case 'u':
5478         {
5479           if (LocaleCompare(attribute,"units") == 0)
5480             {
5481               j=info ? info->image_info->units : image ? image->units :
5482                 UndefinedResolution;
5483               if (info && (info->image_info->units == UndefinedResolution))
5484                 if (image)
5485                   j=image->units;
5486               if (j == UndefinedResolution)
5487                 s=newSVpv("undefined units",0);
5488               else
5489                 if (j == PixelsPerInchResolution)
5490                   s=newSVpv("pixels / inch",0);
5491                 else
5492                   s=newSVpv("pixels / centimeter",0);
5493               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5494               continue;
5495             }
5496           if (LocaleCompare(attribute,"user-time") == 0)
5497             {
5498               if (image != (Image *) NULL)
5499                 s=newSVnv(GetUserTime(&image->timer));
5500               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5501               continue;
5502             }
5503           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5504             attribute);
5505           break;
5506         }
5507         case 'V':
5508         case 'v':
5509         {
5510           if (LocaleCompare(attribute,"verbose") == 0)
5511             {
5512               if (info)
5513                 s=newSViv((ssize_t) info->image_info->verbose);
5514               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5515               continue;
5516             }
5517           if (LocaleCompare(attribute,"version") == 0)
5518             {
5519               s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5520               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5521               continue;
5522             }
5523           if (LocaleCompare(attribute,"view") == 0)
5524             {
5525               if (info && info->image_info->view)
5526                 s=newSVpv(info->image_info->view,0);
5527               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5528               continue;
5529             }
5530           if (LocaleCompare(attribute,"virtual-pixel") == 0)
5531             {
5532               if (image == (Image *) NULL)
5533                 break;
5534               j=(ssize_t) GetImageVirtualPixelMethod(image);
5535               s=newSViv(j);
5536               (void) sv_setpv(s,CommandOptionToMnemonic(
5537                 MagickVirtualPixelOptions,j));
5538               SvIOK_on(s);
5539               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5540               continue;
5541             }
5542           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5543             attribute);
5544           break;
5545         }
5546         case 'W':
5547         case 'w':
5548         {
5549           if (LocaleCompare(attribute,"white-point") == 0)
5550             {
5551               if (image == (Image *) NULL)
5552                 break;
5553               (void) FormatLocaleString(color,MaxTextExtent,"%.15g,%.15g",
5554                 image->chromaticity.white_point.x,
5555                 image->chromaticity.white_point.y);
5556               s=newSVpv(color,0);
5557               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5558               continue;
5559             }
5560           if (LocaleCompare(attribute,"width") == 0)
5561             {
5562               if (image != (Image *) NULL)
5563                 s=newSViv((ssize_t) image->columns);
5564               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5565               continue;
5566             }
5567           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5568              attribute);
5569           break;
5570         }
5571         case 'X':
5572         case 'x':
5573         {
5574           if (LocaleCompare(attribute,"x-resolution") == 0)
5575             {
5576               if (image != (Image *) NULL)
5577                 s=newSVnv(image->resolution.x);
5578               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5579               continue;
5580             }
5581           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5582             attribute);
5583           break;
5584         }
5585         case 'Y':
5586         case 'y':
5587         {
5588           if (LocaleCompare(attribute,"y-resolution") == 0)
5589             {
5590               if (image != (Image *) NULL)
5591                 s=newSVnv(image->resolution.y);
5592               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5593               continue;
5594             }
5595           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5596             attribute);
5597           break;
5598         }
5599         default:
5600           break;
5601       }
5602       if (image == (Image *) NULL)
5603         ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5604           attribute)
5605       else
5606         {
5607           value=GetImageProperty(image,attribute,exception);
5608           if (value != (const char *) NULL)
5609             {
5610               s=newSVpv(value,0);
5611               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5612             }
5613           else
5614             if (*attribute != '%')
5615               ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5616                 attribute)
5617             else
5618               {
5619                  char
5620                    *meta;
5621
5622                  meta=InterpretImageProperties(info ? info->image_info :
5623                    (ImageInfo *) NULL,image,attribute,exception);
5624                  s=newSVpv(meta,0);
5625                  PUSHs(s ? sv_2mortal(s) : &sv_undef);
5626                  meta=(char *) RelinquishMagickMemory(meta);
5627               }
5628         }
5629     }
5630     exception=DestroyExceptionInfo(exception);
5631     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
5632   }
5633 \f
5634 #
5635 ###############################################################################
5636 #                                                                             #
5637 #                                                                             #
5638 #                                                                             #
5639 #   G e t A u t h e n t i c P i x e l s                                       #
5640 #                                                                             #
5641 #                                                                             #
5642 #                                                                             #
5643 ###############################################################################
5644 #
5645 #
5646 void *
5647 GetAuthenticPixels(ref,...)
5648   Image::Magick::@MAGICK_ABI_SUFFIX@ ref = NO_INIT
5649   ALIAS:
5650     getauthenticpixels = 1
5651     GetImagePixels = 2
5652     getimagepixels = 3
5653   CODE:
5654   {
5655     char
5656       *attribute;
5657
5658     ExceptionInfo
5659       *exception;
5660
5661     Image
5662       *image;
5663
5664     RectangleInfo
5665       region;
5666
5667     ssize_t
5668       i;
5669
5670     struct PackageInfo
5671       *info;
5672
5673     SV
5674       *perl_exception,
5675       *reference;
5676
5677     void
5678       *blob = NULL;
5679
5680     PERL_UNUSED_VAR(ref);
5681     PERL_UNUSED_VAR(ix);
5682     exception=AcquireExceptionInfo();
5683     perl_exception=newSVpv("",0);
5684     if (sv_isobject(ST(0)) == 0)
5685       {
5686         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5687           PackageName);
5688         goto PerlException;
5689       }
5690     reference=SvRV(ST(0));
5691
5692     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5693     if (image == (Image *) NULL)
5694       {
5695         ThrowPerlException(exception,OptionError,"NoImagesDefined",
5696           PackageName);
5697         goto PerlException;
5698       }
5699
5700     region.x=0;
5701     region.y=0;
5702     region.width=image->columns;
5703     region.height=1;
5704     if (items == 1)
5705       (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5706     for (i=2; i < items; i+=2)
5707     {
5708       attribute=(char *) SvPV(ST(i-1),na);
5709       switch (*attribute)
5710       {
5711         case 'g':
5712         case 'G':
5713         {
5714           if (LocaleCompare(attribute,"geometry") == 0)
5715             {
5716               (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5717               break;
5718             }
5719           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5720             attribute);
5721           break;
5722         }
5723         case 'H':
5724         case 'h':
5725         {
5726           if (LocaleCompare(attribute,"height") == 0)
5727             {
5728               region.height=SvIV(ST(i));
5729               continue;
5730             }
5731           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5732             attribute);
5733           break;
5734         }
5735         case 'X':
5736         case 'x':
5737         {
5738           if (LocaleCompare(attribute,"x") == 0)
5739             {
5740               region.x=SvIV(ST(i));
5741               continue;
5742             }
5743           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5744             attribute);
5745           break;
5746         }
5747         case 'Y':
5748         case 'y':
5749         {
5750           if (LocaleCompare(attribute,"y") == 0)
5751             {
5752               region.y=SvIV(ST(i));
5753               continue;
5754             }
5755           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5756             attribute);
5757           break;
5758         }
5759         case 'W':
5760         case 'w':
5761         {
5762           if (LocaleCompare(attribute,"width") == 0)
5763             {
5764               region.width=SvIV(ST(i));
5765               continue;
5766             }
5767           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5768             attribute);
5769           break;
5770         }
5771       }
5772     }
5773     blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
5774       region.height,exception);
5775     if (blob != (void *) NULL)
5776       goto PerlEnd;
5777
5778   PerlException:
5779     InheritPerlException(exception,perl_exception);
5780     exception=DestroyExceptionInfo(exception);
5781     SvREFCNT_dec(perl_exception);  /* throw away all errors */
5782
5783   PerlEnd:
5784     RETVAL = blob;
5785   }
5786   OUTPUT:
5787     RETVAL
5788 \f
5789 #
5790 ###############################################################################
5791 #                                                                             #
5792 #                                                                             #
5793 #                                                                             #
5794 #   G e t V i r t u a l P i x e l s                                           #
5795 #                                                                             #
5796 #                                                                             #
5797 #                                                                             #
5798 ###############################################################################
5799 #
5800 #
5801 void *
5802 GetVirtualPixels(ref,...)
5803   Image::Magick::@MAGICK_ABI_SUFFIX@ ref = NO_INIT
5804   ALIAS:
5805     getvirtualpixels = 1
5806     AcquireImagePixels = 2
5807     acquireimagepixels = 3
5808   CODE:
5809   {
5810     char
5811       *attribute;
5812
5813     const void
5814       *blob = NULL;
5815
5816     ExceptionInfo
5817       *exception;
5818
5819     Image
5820       *image;
5821
5822     RectangleInfo
5823       region;
5824
5825     ssize_t
5826       i;
5827
5828     struct PackageInfo
5829       *info;
5830
5831     SV
5832       *perl_exception,
5833       *reference;
5834
5835     PERL_UNUSED_VAR(ref);
5836     PERL_UNUSED_VAR(ix);
5837     exception=AcquireExceptionInfo();
5838     perl_exception=newSVpv("",0);
5839     if (sv_isobject(ST(0)) == 0)
5840       {
5841         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5842           PackageName);
5843         goto PerlException;
5844       }
5845     reference=SvRV(ST(0));
5846
5847     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5848     if (image == (Image *) NULL)
5849       {
5850         ThrowPerlException(exception,OptionError,"NoImagesDefined",
5851           PackageName);
5852         goto PerlException;
5853       }
5854
5855     region.x=0;
5856     region.y=0;
5857     region.width=image->columns;
5858     region.height=1;
5859     if (items == 1)
5860       (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5861     for (i=2; i < items; i+=2)
5862     {
5863       attribute=(char *) SvPV(ST(i-1),na);
5864       switch (*attribute)
5865       {
5866         case 'g':
5867         case 'G':
5868         {
5869           if (LocaleCompare(attribute,"geometry") == 0)
5870             {
5871               (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5872               break;
5873             }
5874           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5875             attribute);
5876           break;
5877         }
5878         case 'H':
5879         case 'h':
5880         {
5881           if (LocaleCompare(attribute,"height") == 0)
5882             {
5883               region.height=SvIV(ST(i));
5884               continue;
5885             }
5886           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5887             attribute);
5888           break;
5889         }
5890         case 'X':
5891         case 'x':
5892         {
5893           if (LocaleCompare(attribute,"x") == 0)
5894             {
5895               region.x=SvIV(ST(i));
5896               continue;
5897             }
5898           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5899             attribute);
5900           break;
5901         }
5902         case 'Y':
5903         case 'y':
5904         {
5905           if (LocaleCompare(attribute,"y") == 0)
5906             {
5907               region.y=SvIV(ST(i));
5908               continue;
5909             }
5910           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5911             attribute);
5912           break;
5913         }
5914         case 'W':
5915         case 'w':
5916         {
5917           if (LocaleCompare(attribute,"width") == 0)
5918             {
5919               region.width=SvIV(ST(i));
5920               continue;
5921             }
5922           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5923             attribute);
5924           break;
5925         }
5926       }
5927     }
5928     blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
5929       region.height,exception);
5930     if (blob != (void *) NULL)
5931       goto PerlEnd;
5932
5933   PerlException:
5934     InheritPerlException(exception,perl_exception);
5935     exception=DestroyExceptionInfo(exception);
5936     SvREFCNT_dec(perl_exception);  /* throw away all errors */
5937
5938   PerlEnd:
5939     RETVAL = (void *) blob;
5940   }
5941   OUTPUT:
5942     RETVAL
5943 \f
5944 #
5945 ###############################################################################
5946 #                                                                             #
5947 #                                                                             #
5948 #                                                                             #
5949 #   G e t A u t h e n t i c M e t a c o n t e n t                             #
5950 #                                                                             #
5951 #                                                                             #
5952 #                                                                             #
5953 ###############################################################################
5954 #
5955 #
5956 void *
5957 GetAuthenticMetacontent(ref,...)
5958   Image::Magick::@MAGICK_ABI_SUFFIX@ ref = NO_INIT
5959   ALIAS:
5960     getauthenticmetacontent = 1
5961     GetMetacontent = 2
5962     getmetacontent = 3
5963   CODE:
5964   {
5965     ExceptionInfo
5966       *exception;
5967
5968     Image
5969       *image;
5970
5971     struct PackageInfo
5972       *info;
5973
5974     SV
5975       *perl_exception,
5976       *reference;
5977
5978     void
5979       *blob = NULL;
5980
5981     PERL_UNUSED_VAR(ref);
5982     PERL_UNUSED_VAR(ix);
5983     exception=AcquireExceptionInfo();
5984     perl_exception=newSVpv("",0);
5985     if (sv_isobject(ST(0)) == 0)
5986       {
5987         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5988           PackageName);
5989         goto PerlException;
5990       }
5991     reference=SvRV(ST(0));
5992
5993     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5994     if (image == (Image *) NULL)
5995       {
5996         ThrowPerlException(exception,OptionError,"NoImagesDefined",
5997           PackageName);
5998         goto PerlException;
5999       }
6000
6001     blob=(void *) GetAuthenticMetacontent(image);
6002     if (blob != (void *) NULL)
6003       goto PerlEnd;
6004
6005   PerlException:
6006     InheritPerlException(exception,perl_exception);
6007     exception=DestroyExceptionInfo(exception);
6008     SvREFCNT_dec(perl_exception);  /* throw away all errors */
6009
6010   PerlEnd:
6011     RETVAL = blob;
6012   }
6013   OUTPUT:
6014     RETVAL
6015 \f
6016 #
6017 ###############################################################################
6018 #                                                                             #
6019 #                                                                             #
6020 #                                                                             #
6021 #   G e t V i r t u a l M e t a c o n t e n t                                 #
6022 #                                                                             #
6023 #                                                                             #
6024 #                                                                             #
6025 ###############################################################################
6026 #
6027 #
6028 void *
6029 GetVirtualMetacontent(ref,...)
6030   Image::Magick::@MAGICK_ABI_SUFFIX@ ref = NO_INIT
6031   ALIAS:
6032     getvirtualmetacontent = 1
6033   CODE:
6034   {
6035     ExceptionInfo
6036       *exception;
6037
6038     Image
6039       *image;
6040
6041     struct PackageInfo
6042       *info;
6043
6044     SV
6045       *perl_exception,
6046       *reference;
6047
6048     void
6049       *blob = NULL;
6050
6051     PERL_UNUSED_VAR(ref);
6052     PERL_UNUSED_VAR(ix);
6053     exception=AcquireExceptionInfo();
6054     perl_exception=newSVpv("",0);
6055     if (sv_isobject(ST(0)) == 0)
6056       {
6057         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6058           PackageName);
6059         goto PerlException;
6060       }
6061     reference=SvRV(ST(0));
6062
6063     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6064     if (image == (Image *) NULL)
6065       {
6066         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6067           PackageName);
6068         goto PerlException;
6069       }
6070
6071     blob=(void *) GetVirtualMetacontent(image);
6072     if (blob != (void *) NULL)
6073       goto PerlEnd;
6074
6075   PerlException:
6076     InheritPerlException(exception,perl_exception);
6077     exception=DestroyExceptionInfo(exception);
6078     SvREFCNT_dec(perl_exception);  /* throw away all errors */
6079
6080   PerlEnd:
6081     RETVAL = blob;
6082   }
6083   OUTPUT:
6084     RETVAL
6085 \f
6086 #
6087 ###############################################################################
6088 #                                                                             #
6089 #                                                                             #
6090 #                                                                             #
6091 #   H i s t o g r a m                                                         #
6092 #                                                                             #
6093 #                                                                             #
6094 #                                                                             #
6095 ###############################################################################
6096 #
6097 #
6098 void
6099 Histogram(ref,...)
6100   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
6101   ALIAS:
6102     HistogramImage = 1
6103     histogram      = 2
6104     histogramimage = 3
6105   PPCODE:
6106   {
6107     AV
6108       *av;
6109
6110     char
6111       message[MaxTextExtent];
6112
6113     PixelInfo
6114       *histogram;
6115
6116     ExceptionInfo
6117       *exception;
6118
6119     Image
6120       *image;
6121
6122     register ssize_t
6123       i;
6124
6125     ssize_t
6126       count;
6127
6128     struct PackageInfo
6129       *info;
6130
6131     SV
6132       *perl_exception,
6133       *reference;
6134
6135     size_t
6136       number_colors;
6137
6138     PERL_UNUSED_VAR(ref);
6139     PERL_UNUSED_VAR(ix);
6140     exception=AcquireExceptionInfo();
6141     perl_exception=newSVpv("",0);
6142     av=NULL;
6143     if (sv_isobject(ST(0)) == 0)
6144       {
6145         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6146           PackageName);
6147         goto PerlException;
6148       }
6149     reference=SvRV(ST(0));
6150     av=newAV();
6151     SvREFCNT_dec(av);
6152     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6153     if (image == (Image *) NULL)
6154       {
6155         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6156           PackageName);
6157         goto PerlException;
6158       }
6159     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
6160     count=0;
6161     for ( ; image; image=image->next)
6162     {
6163       histogram=GetImageHistogram(image,&number_colors,exception);
6164       if (histogram == (PixelInfo *) NULL)
6165         continue;
6166       count+=(ssize_t) number_colors;
6167       EXTEND(sp,6*count);
6168       for (i=0; i < (ssize_t) number_colors; i++)
6169       {
6170         (void) FormatLocaleString(message,MaxTextExtent,"%.20g",
6171           histogram[i].red);
6172         PUSHs(sv_2mortal(newSVpv(message,0)));
6173         (void) FormatLocaleString(message,MaxTextExtent,"%.20g",
6174           histogram[i].green);
6175         PUSHs(sv_2mortal(newSVpv(message,0)));
6176         (void) FormatLocaleString(message,MaxTextExtent,"%.20g",
6177           histogram[i].blue);
6178         PUSHs(sv_2mortal(newSVpv(message,0)));
6179         if (image->colorspace == CMYKColorspace)
6180           {
6181             (void) FormatLocaleString(message,MaxTextExtent,"%.20g",
6182               histogram[i].black);
6183             PUSHs(sv_2mortal(newSVpv(message,0)));
6184           }
6185         (void) FormatLocaleString(message,MaxTextExtent,"%.20g",
6186           histogram[i].alpha);
6187         PUSHs(sv_2mortal(newSVpv(message,0)));
6188         (void) FormatLocaleString(message,MaxTextExtent,"%.20g",(double)
6189           histogram[i].count);
6190         PUSHs(sv_2mortal(newSVpv(message,0)));
6191       }
6192       histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6193     }
6194
6195   PerlException:
6196     InheritPerlException(exception,perl_exception);
6197     exception=DestroyExceptionInfo(exception);
6198     SvREFCNT_dec(perl_exception);
6199   }
6200 \f
6201 #
6202 ###############################################################################
6203 #                                                                             #
6204 #                                                                             #
6205 #                                                                             #
6206 #   G e t P i x e l                                                           #
6207 #                                                                             #
6208 #                                                                             #
6209 #                                                                             #
6210 ###############################################################################
6211 #
6212 #
6213 void
6214 GetPixel(ref,...)
6215   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
6216   ALIAS:
6217     getpixel = 1
6218     getPixel = 2
6219   PPCODE:
6220   {
6221     AV
6222       *av;
6223
6224     char
6225       *attribute;
6226
6227     ExceptionInfo
6228       *exception;
6229
6230     Image
6231       *image;
6232
6233     MagickBooleanType
6234       normalize;
6235
6236     RectangleInfo
6237       region;
6238
6239     register const Quantum
6240       *p;
6241
6242     register ssize_t
6243       i;
6244
6245     ssize_t
6246       option;
6247
6248     struct PackageInfo
6249       *info;
6250
6251     SV
6252       *perl_exception,
6253       *reference;  /* reference is the SV* of ref=SvIV(reference) */
6254
6255     PERL_UNUSED_VAR(ref);
6256     PERL_UNUSED_VAR(ix);
6257     exception=AcquireExceptionInfo();
6258     perl_exception=newSVpv("",0);
6259     reference=SvRV(ST(0));
6260     av=(AV *) reference;
6261     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6262       exception);
6263     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6264     if (image == (Image *) NULL)
6265       {
6266         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6267           PackageName);
6268         goto PerlException;
6269       }
6270     normalize=MagickTrue;
6271     region.x=0;
6272     region.y=0;
6273     region.width=image->columns;
6274     region.height=1;
6275     if (items == 1)
6276       (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6277     for (i=2; i < items; i+=2)
6278     {
6279       attribute=(char *) SvPV(ST(i-1),na);
6280       switch (*attribute)
6281       {
6282         case 'C':
6283         case 'c':
6284         {
6285           if (LocaleCompare(attribute,"channel") == 0)
6286             {
6287               ssize_t
6288                 option;
6289
6290               option=ParseChannelOption(SvPV(ST(i),na));
6291               if (option < 0)
6292                 {
6293                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
6294                     SvPV(ST(i),na));
6295                   return;
6296                 }
6297               SetPixelChannelMask(image,(ChannelType) option);
6298               break;
6299             }
6300           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6301             attribute);
6302           break;
6303         }
6304         case 'g':
6305         case 'G':
6306         {
6307           if (LocaleCompare(attribute,"geometry") == 0)
6308             {
6309               (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6310               break;
6311             }
6312           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6313             attribute);
6314           break;
6315         }
6316         case 'N':
6317         case 'n':
6318         {
6319           if (LocaleCompare(attribute,"normalize") == 0)
6320             {
6321               option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6322                 SvPV(ST(i),na));
6323               if (option < 0)
6324                 {
6325                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
6326                     SvPV(ST(i),na));
6327                   break;
6328                 }
6329              normalize=option != 0 ? MagickTrue : MagickFalse;
6330              break;
6331             }
6332           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6333             attribute);
6334           break;
6335         }
6336         case 'x':
6337         case 'X':
6338         {
6339           if (LocaleCompare(attribute,"x") == 0)
6340             {
6341               region.x=SvIV(ST(i));
6342               break;
6343             }
6344           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6345             attribute);
6346           break;
6347         }
6348         case 'y':
6349         case 'Y':
6350         {
6351           if (LocaleCompare(attribute,"y") == 0)
6352             {
6353               region.y=SvIV(ST(i));
6354               break;
6355             }
6356           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6357             attribute);
6358           break;
6359         }
6360         default:
6361         {
6362           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6363             attribute);
6364           break;
6365         }
6366       }
6367     }
6368     p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6369     if (p == (const Quantum *) NULL)
6370       PUSHs(&sv_undef);
6371     else
6372       {
6373         double
6374           scale;
6375
6376         scale=1.0;
6377         if (normalize != MagickFalse)
6378           scale=1.0/QuantumRange;
6379         if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6380           PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6381         if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6382           PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6383         if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6384           PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6385         if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6386             (image->colorspace == CMYKColorspace))
6387           PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6388         if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6389           PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6390       }
6391
6392   PerlException:
6393     InheritPerlException(exception,perl_exception);
6394     exception=DestroyExceptionInfo(exception);
6395     SvREFCNT_dec(perl_exception);
6396   }
6397 \f
6398 #
6399 ###############################################################################
6400 #                                                                             #
6401 #                                                                             #
6402 #                                                                             #
6403 #   G e t P i x e l s                                                         #
6404 #                                                                             #
6405 #                                                                             #
6406 #                                                                             #
6407 ###############################################################################
6408 #
6409 #
6410 void
6411 GetPixels(ref,...)
6412   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
6413   ALIAS:
6414     getpixels = 1
6415     getPixels = 2
6416   PPCODE:
6417   {
6418     AV
6419       *av;
6420
6421     char
6422       *attribute;
6423
6424     const char
6425       *map;
6426
6427     ExceptionInfo
6428       *exception;
6429
6430     Image
6431       *image;
6432
6433     MagickBooleanType
6434       normalize,
6435       status;
6436
6437     RectangleInfo
6438       region;
6439
6440     register ssize_t
6441       i;
6442
6443     ssize_t
6444       option;
6445
6446     struct PackageInfo
6447       *info;
6448
6449     SV
6450       *perl_exception,
6451       *reference;  /* reference is the SV* of ref=SvIV(reference) */
6452
6453     PERL_UNUSED_VAR(ref);
6454     PERL_UNUSED_VAR(ix);
6455     exception=AcquireExceptionInfo();
6456     perl_exception=newSVpv("",0);
6457     reference=SvRV(ST(0));
6458     av=(AV *) reference;
6459     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6460       exception);
6461     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6462     if (image == (Image *) NULL)
6463       {
6464         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6465           PackageName);
6466         goto PerlException;
6467       }
6468     map="RGB";
6469     if (image->alpha_trait == BlendPixelTrait)
6470       map="RGBA";
6471     if (image->colorspace == CMYKColorspace)
6472       {
6473         map="CMYK";
6474         if (image->alpha_trait == BlendPixelTrait)
6475           map="CMYKA";
6476       }
6477     normalize=MagickFalse;
6478     region.x=0;
6479     region.y=0;
6480     region.width=image->columns;
6481     region.height=1;
6482     if (items == 1)
6483       (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6484     for (i=2; i < items; i+=2)
6485     {
6486       attribute=(char *) SvPV(ST(i-1),na);
6487       switch (*attribute)
6488       {
6489         case 'g':
6490         case 'G':
6491         {
6492           if (LocaleCompare(attribute,"geometry") == 0)
6493             {
6494               (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6495               break;
6496             }
6497           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6498             attribute);
6499           break;
6500         }
6501         case 'H':
6502         case 'h':
6503         {
6504           if (LocaleCompare(attribute,"height") == 0)
6505             {
6506               region.height=SvIV(ST(i));
6507               break;
6508             }
6509           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6510             attribute);
6511           break;
6512         }
6513         case 'M':
6514         case 'm':
6515         {
6516           if (LocaleCompare(attribute,"map") == 0)
6517             {
6518               map=SvPV(ST(i),na);
6519               break;
6520             }
6521           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6522             attribute);
6523           break;
6524         }
6525         case 'N':
6526         case 'n':
6527         {
6528           if (LocaleCompare(attribute,"normalize") == 0)
6529             {
6530               option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6531                 SvPV(ST(i),na));
6532               if (option < 0)
6533                 {
6534                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
6535                     SvPV(ST(i),na));
6536                   break;
6537                 }
6538              normalize=option != 0 ? MagickTrue : MagickFalse;
6539              break;
6540             }
6541           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6542             attribute);
6543           break;
6544         }
6545         case 'W':
6546         case 'w':
6547         {
6548           if (LocaleCompare(attribute,"width") == 0)
6549             {
6550               region.width=SvIV(ST(i));
6551               break;
6552             }
6553           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6554             attribute);
6555           break;
6556         }
6557         case 'x':
6558         case 'X':
6559         {
6560           if (LocaleCompare(attribute,"x") == 0)
6561             {
6562               region.x=SvIV(ST(i));
6563               break;
6564             }
6565           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6566             attribute);
6567           break;
6568         }
6569         case 'y':
6570         case 'Y':
6571         {
6572           if (LocaleCompare(attribute,"y") == 0)
6573             {
6574               region.y=SvIV(ST(i));
6575               break;
6576             }
6577           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6578             attribute);
6579           break;
6580         }
6581         default:
6582         {
6583           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6584             attribute);
6585           break;
6586         }
6587       }
6588     }
6589     if (normalize != MagickFalse)
6590       {
6591         float
6592           *pixels;
6593
6594         pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6595           region.height*sizeof(*pixels));
6596         if (pixels == (float *) NULL)
6597           {
6598             ThrowPerlException(exception,ResourceLimitError,
6599               "MemoryAllocationFailed",PackageName);
6600             goto PerlException;
6601           }
6602         status=ExportImagePixels(image,region.x,region.y,region.width,
6603           region.height,map,FloatPixel,pixels,exception);
6604         if (status == MagickFalse)
6605           PUSHs(&sv_undef);
6606         else
6607           {
6608             EXTEND(sp,strlen(map)*region.width*region.height);
6609             for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6610               PUSHs(sv_2mortal(newSVnv(pixels[i])));
6611           }
6612         pixels=(float *) RelinquishMagickMemory(pixels);
6613       }
6614     else
6615       {
6616         Quantum
6617           *pixels;
6618
6619         pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6620           region.height*sizeof(*pixels));
6621         if (pixels == (Quantum *) NULL)
6622           {
6623             ThrowPerlException(exception,ResourceLimitError,
6624               "MemoryAllocationFailed",PackageName);
6625             goto PerlException;
6626           }
6627         status=ExportImagePixels(image,region.x,region.y,region.width,
6628           region.height,map,QuantumPixel,pixels,exception);
6629         if (status == MagickFalse)
6630           PUSHs(&sv_undef);
6631         else
6632           {
6633             EXTEND(sp,strlen(map)*region.width*region.height);
6634             for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6635               PUSHs(sv_2mortal(newSViv(pixels[i])));
6636           }
6637         pixels=(Quantum *) RelinquishMagickMemory(pixels);
6638       }
6639
6640   PerlException:
6641     InheritPerlException(exception,perl_exception);
6642     exception=DestroyExceptionInfo(exception);
6643     SvREFCNT_dec(perl_exception);
6644   }
6645 \f
6646 #
6647 ###############################################################################
6648 #                                                                             #
6649 #                                                                             #
6650 #                                                                             #
6651 #   I m a g e T o B l o b                                                     #
6652 #                                                                             #
6653 #                                                                             #
6654 #                                                                             #
6655 ###############################################################################
6656 #
6657 #
6658 void
6659 ImageToBlob(ref,...)
6660   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
6661   ALIAS:
6662     ImageToBlob  = 1
6663     imagetoblob  = 2
6664     toblob       = 3
6665     blob         = 4
6666   PPCODE:
6667   {
6668     char
6669       filename[MaxTextExtent];
6670
6671     ExceptionInfo
6672       *exception;
6673
6674     Image
6675       *image,
6676       *next;
6677
6678     register ssize_t
6679       i;
6680
6681     struct PackageInfo
6682       *info,
6683       *package_info;
6684
6685     size_t
6686       length;
6687
6688     ssize_t
6689       scene;
6690
6691     SV
6692       *perl_exception,
6693       *reference;
6694
6695     void
6696       *blob;
6697
6698     PERL_UNUSED_VAR(ref);
6699     PERL_UNUSED_VAR(ix);
6700     exception=AcquireExceptionInfo();
6701     perl_exception=newSVpv("",0);
6702     package_info=(struct PackageInfo *) NULL;
6703     if (sv_isobject(ST(0)) == 0)
6704       {
6705         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6706           PackageName);
6707         goto PerlException;
6708       }
6709     reference=SvRV(ST(0));
6710     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6711     if (image == (Image *) NULL)
6712       {
6713         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6714           PackageName);
6715         goto PerlException;
6716       }
6717     package_info=ClonePackageInfo(info,exception);
6718     for (i=2; i < items; i+=2)
6719       SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6720     (void) CopyMagickString(filename,package_info->image_info->filename,
6721       MaxTextExtent);
6722     scene=0;
6723     for (next=image; next; next=next->next)
6724     {
6725       (void) CopyMagickString(next->filename,filename,MaxTextExtent);
6726       next->scene=scene++;
6727     }
6728     SetImageInfo(package_info->image_info,(unsigned int)
6729       GetImageListLength(image),exception);
6730     EXTEND(sp,(ssize_t) GetImageListLength(image));
6731     for ( ; image; image=image->next)
6732     {
6733       length=0;
6734       blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6735       if (blob != (char *) NULL)
6736         {
6737           PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6738           blob=(unsigned char *) RelinquishMagickMemory(blob);
6739         }
6740       if (package_info->image_info->adjoin)
6741         break;
6742     }
6743
6744   PerlException:
6745     if (package_info != (struct PackageInfo *) NULL)
6746       DestroyPackageInfo(package_info);
6747     InheritPerlException(exception,perl_exception);
6748     exception=DestroyExceptionInfo(exception);
6749     SvREFCNT_dec(perl_exception);  /* throw away all errors */
6750   }
6751 \f
6752 #
6753 ###############################################################################
6754 #                                                                             #
6755 #                                                                             #
6756 #                                                                             #
6757 #   L a y e r s                                                               #
6758 #                                                                             #
6759 #                                                                             #
6760 #                                                                             #
6761 ###############################################################################
6762 #
6763 #
6764 void
6765 Layers(ref,...)
6766   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
6767   ALIAS:
6768     Layers                = 1
6769     layers           = 2
6770     OptimizeImageLayers   = 3
6771     optimizelayers        = 4
6772     optimizeimagelayers   = 5
6773   PPCODE:
6774   {
6775     AV
6776       *av;
6777
6778     char
6779       *attribute;
6780
6781     CompositeOperator
6782       compose;
6783
6784     ExceptionInfo
6785       *exception;
6786
6787     HV
6788       *hv;
6789
6790     Image
6791       *image,
6792       *layers;
6793
6794     LayerMethod
6795       method;
6796
6797     register ssize_t
6798       i;
6799
6800     ssize_t
6801       option,
6802       sp;
6803
6804     struct PackageInfo
6805       *info;
6806
6807     SV
6808       *av_reference,
6809       *perl_exception,
6810       *reference,
6811       *rv,
6812       *sv;
6813
6814     PERL_UNUSED_VAR(ref);
6815     PERL_UNUSED_VAR(ix);
6816     exception=AcquireExceptionInfo();
6817     perl_exception=newSVpv("",0);
6818     sv=NULL;
6819     if (sv_isobject(ST(0)) == 0)
6820       {
6821         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6822           PackageName);
6823         goto PerlException;
6824       }
6825     reference=SvRV(ST(0));
6826     hv=SvSTASH(reference);
6827     av=newAV();
6828     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
6829     SvREFCNT_dec(av);
6830     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6831     if (image == (Image *) NULL)
6832       {
6833         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6834           PackageName);
6835         goto PerlException;
6836       }
6837     compose=image->compose;
6838     method=OptimizeLayer;
6839     for (i=2; i < items; i+=2)
6840     {
6841       attribute=(char *) SvPV(ST(i-1),na);
6842       switch (*attribute)
6843       {
6844         case 'C':
6845         case 'c':
6846         {
6847           if (LocaleCompare(attribute,"compose") == 0)
6848             {
6849               sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
6850                 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
6851               if (sp < 0)
6852                 {
6853                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
6854                     SvPV(ST(i),na));
6855                   break;
6856                 }
6857               compose=(CompositeOperator) sp;
6858               break;
6859             }
6860           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6861             attribute);
6862           break;
6863         }
6864         case 'M':
6865         case 'm':
6866         {
6867           if (LocaleCompare(attribute,"method") == 0)
6868             {
6869               option=ParseCommandOption(MagickLayerOptions,MagickFalse,
6870                 SvPV(ST(i),na));
6871               if (option < 0)
6872                 {
6873                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
6874                     SvPV(ST(i),na));
6875                   break;
6876                 }
6877               method=(LayerMethod) option;
6878               break;
6879             }
6880           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6881             attribute);
6882           break;
6883         }
6884         default:
6885         {
6886           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6887             attribute);
6888           break;
6889         }
6890       }
6891     }
6892     layers=(Image *) NULL;
6893     switch (method)
6894     {
6895       case CompareAnyLayer:
6896       case CompareClearLayer:
6897       case CompareOverlayLayer:
6898       default:
6899       {
6900         layers=CompareImagesLayers(image,method,exception);
6901         break;
6902       }
6903       case MergeLayer:
6904       case FlattenLayer:
6905       case MosaicLayer:
6906       {
6907         layers=MergeImageLayers(image,method,exception);
6908         break;
6909       }
6910       case DisposeLayer:
6911       {
6912         layers=DisposeImages(image,exception);
6913         break;
6914       }
6915       case OptimizeImageLayer:
6916       {
6917         layers=OptimizeImageLayers(image,exception);
6918         break;
6919       }
6920       case OptimizePlusLayer:
6921       {
6922         layers=OptimizePlusImageLayers(image,exception);
6923         break;
6924       }
6925       case OptimizeTransLayer:
6926       {
6927         OptimizeImageTransparency(image,exception);
6928         break;
6929       }
6930       case RemoveDupsLayer:
6931       {
6932         RemoveDuplicateLayers(&image,exception);
6933         break;
6934       }
6935       case RemoveZeroLayer:
6936       {
6937         RemoveZeroDelayLayers(&image,exception);
6938         break;
6939       }
6940       case OptimizeLayer:
6941       {
6942         QuantizeInfo
6943           *quantize_info;
6944
6945         /*
6946           General Purpose, GIF Animation Optimizer.
6947         */
6948         layers=CoalesceImages(image,exception);
6949         if (layers == (Image *) NULL)
6950           break;
6951         image=layers;
6952         layers=OptimizeImageLayers(image,exception);
6953         if (layers == (Image *) NULL)
6954           break;
6955         image=DestroyImageList(image);
6956         image=layers;
6957         layers=(Image *) NULL;
6958         OptimizeImageTransparency(image,exception);
6959         quantize_info=AcquireQuantizeInfo(info->image_info);
6960         (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
6961         quantize_info=DestroyQuantizeInfo(quantize_info);
6962         break;
6963       }
6964       case CompositeLayer:
6965       {
6966         Image
6967           *source;
6968
6969         RectangleInfo
6970           geometry;
6971
6972         /*
6973           Split image sequence at the first 'NULL:' image.
6974         */
6975         source=image;
6976         while (source != (Image *) NULL)
6977         {
6978           source=GetNextImageInList(source);
6979           if ((source != (Image *) NULL) &&
6980               (LocaleCompare(source->magick,"NULL") == 0))
6981             break;
6982         }
6983         if (source != (Image *) NULL)
6984           {
6985             if ((GetPreviousImageInList(source) == (Image *) NULL) ||
6986                 (GetNextImageInList(source) == (Image *) NULL))
6987               source=(Image *) NULL;
6988             else
6989               {
6990                 /*
6991                   Separate the two lists, junk the null: image.
6992                 */
6993                 source=SplitImageList(source->previous);
6994                 DeleteImageFromList(&source);
6995               }
6996           }
6997         if (source == (Image *) NULL)
6998           {
6999             (void) ThrowMagickException(exception,GetMagickModule(),
7000               OptionError,"MissingNullSeparator","layers Composite");
7001             break;
7002           }
7003         /*
7004           Adjust offset with gravity and virtual canvas.
7005         */
7006         SetGeometry(image,&geometry);
7007         (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7008         geometry.width=source->page.width != 0 ? source->page.width :
7009           source->columns;
7010         geometry.height=source->page.height != 0 ? source->page.height :
7011           source->rows;
7012         GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7013           image->columns,image->page.height != 0 ? image->page.height :
7014           image->rows,image->gravity,&geometry);
7015         CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7016         source=DestroyImageList(source);
7017         break;
7018       }
7019     }
7020     if (layers != (Image *) NULL)
7021       image=layers;
7022     if (image == (Image *) NULL)
7023       goto PerlException;
7024     for ( ; image; image=image->next)
7025     {
7026       AddImageToRegistry(sv,image);
7027       rv=newRV(sv);
7028       av_push(av,sv_bless(rv,hv));
7029       SvREFCNT_dec(sv);
7030     }
7031     exception=DestroyExceptionInfo(exception);
7032     ST(0)=av_reference;
7033     SvREFCNT_dec(perl_exception);
7034     XSRETURN(1);
7035
7036   PerlException:
7037     InheritPerlException(exception,perl_exception);
7038     exception=DestroyExceptionInfo(exception);
7039     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7040     SvPOK_on(perl_exception);
7041     ST(0)=sv_2mortal(perl_exception);
7042     XSRETURN(1);
7043   }
7044 \f
7045 #
7046 ###############################################################################
7047 #                                                                             #
7048 #                                                                             #
7049 #                                                                             #
7050 #   M a g i c k T o M i m e                                                   #
7051 #                                                                             #
7052 #                                                                             #
7053 #                                                                             #
7054 ###############################################################################
7055 #
7056 #
7057 SV *
7058 MagickToMime(ref,name)
7059   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
7060   char *name
7061   ALIAS:
7062     magicktomime = 1
7063   CODE:
7064   {
7065     char
7066       *mime;
7067
7068     PERL_UNUSED_VAR(ref);
7069     PERL_UNUSED_VAR(ix);
7070     mime=MagickToMime(name);
7071     RETVAL=newSVpv(mime,0);
7072     mime=(char *) RelinquishMagickMemory(mime);
7073   }
7074   OUTPUT:
7075     RETVAL
7076 \f
7077 #
7078 ###############################################################################
7079 #                                                                             #
7080 #                                                                             #
7081 #                                                                             #
7082 #   M o g r i f y                                                             #
7083 #                                                                             #
7084 #                                                                             #
7085 #                                                                             #
7086 ###############################################################################
7087 #
7088 #
7089 void
7090 Mogrify(ref,...)
7091   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
7092   ALIAS:
7093     Comment            =   1
7094     CommentImage       =   2
7095     Label              =   3
7096     LabelImage         =   4
7097     AddNoise           =   5
7098     AddNoiseImage      =   6
7099     Colorize           =   7
7100     ColorizeImage      =   8
7101     Border             =   9
7102     BorderImage        =  10
7103     Blur               =  11
7104     BlurImage          =  12
7105     Chop               =  13
7106     ChopImage          =  14
7107     Crop               =  15
7108     CropImage          =  16
7109     Despeckle          =  17
7110     DespeckleImage     =  18
7111     Edge               =  19
7112     EdgeImage          =  20
7113     Emboss             =  21
7114     EmbossImage        =  22
7115     Enhance            =  23
7116     EnhanceImage       =  24
7117     Flip               =  25
7118     FlipImage          =  26
7119     Flop               =  27
7120     FlopImage          =  28
7121     Frame              =  29
7122     FrameImage         =  30
7123     Implode            =  31
7124     ImplodeImage       =  32
7125     Magnify            =  33
7126     MagnifyImage       =  34
7127     MedianFilter       =  35
7128     MedianConvolveImage  =  36
7129     Minify             =  37
7130     MinifyImage        =  38
7131     OilPaint           =  39
7132     OilPaintImage      =  40
7133     ReduceNoise        =  41
7134     ReduceNoiseImage   =  42
7135     Roll               =  43
7136     RollImage          =  44
7137     Rotate             =  45
7138     RotateImage        =  46
7139     Sample             =  47
7140     SampleImage        =  48
7141     Scale              =  49
7142     ScaleImage         =  50
7143     Shade              =  51
7144     ShadeImage         =  52
7145     Sharpen            =  53
7146     SharpenImage       =  54
7147     Shear              =  55
7148     ShearImage         =  56
7149     Spread             =  57
7150     SpreadImage        =  58
7151     Swirl              =  59
7152     SwirlImage         =  60
7153     Resize             =  61
7154     ResizeImage        =  62
7155     Zoom               =  63
7156     ZoomImage          =  64
7157     Annotate           =  65
7158     AnnotateImage      =  66
7159     ColorFloodfill     =  67
7160     ColorFloodfillImage=  68
7161     Composite          =  69
7162     CompositeImage     =  70
7163     Contrast           =  71
7164     ContrastImage      =  72
7165     CycleColormap      =  73
7166     CycleColormapImage =  74
7167     Draw               =  75
7168     DrawImage          =  76
7169     Equalize           =  77
7170     EqualizeImage      =  78
7171     Gamma              =  79
7172     GammaImage         =  80
7173     Map                =  81
7174     MapImage           =  82
7175     MatteFloodfill     =  83
7176     MatteFloodfillImage=  84
7177     Modulate           =  85
7178     ModulateImage      =  86
7179     Negate             =  87
7180     NegateImage        =  88
7181     Normalize          =  89
7182     NormalizeImage     =  90
7183     NumberColors       =  91
7184     NumberColorsImage  =  92
7185     Opaque             =  93
7186     OpaqueImage        =  94
7187     Quantize           =  95
7188     QuantizeImage      =  96
7189     Raise              =  97
7190     RaiseImage         =  98
7191     Segment            =  99
7192     SegmentImage       = 100
7193     Signature          = 101
7194     SignatureImage     = 102
7195     Solarize           = 103
7196     SolarizeImage      = 104
7197     Sync               = 105
7198     SyncImage          = 106
7199     Texture            = 107
7200     TextureImage       = 108
7201     Evaluate           = 109
7202     EvaluateImage      = 110
7203     Transparent        = 111
7204     TransparentImage   = 112
7205     Threshold          = 113
7206     ThresholdImage     = 114
7207     Charcoal           = 115
7208     CharcoalImage      = 116
7209     Trim               = 117
7210     TrimImage          = 118
7211     Wave               = 119
7212     WaveImage          = 120
7213     Separate           = 121
7214     SeparateImage      = 122
7215     Stereo             = 125
7216     StereoImage        = 126
7217     Stegano            = 127
7218     SteganoImage       = 128
7219     Deconstruct        = 129
7220     DeconstructImage   = 130
7221     GaussianBlur       = 131
7222     GaussianBlurImage  = 132
7223     Convolve           = 133
7224     ConvolveImage      = 134
7225     Profile            = 135
7226     ProfileImage       = 136
7227     UnsharpMask        = 137
7228     UnsharpMaskImage   = 138
7229     MotionBlur         = 139
7230     MotionBlurImage    = 140
7231     OrderedDither      = 141
7232     OrderedDitherImage = 142
7233     Shave              = 143
7234     ShaveImage         = 144
7235     Level              = 145
7236     LevelImage         = 146
7237     Clip               = 147
7238     ClipImage          = 148
7239     AffineTransform    = 149
7240     AffineTransformImage = 150
7241     Difference         = 151
7242     DifferenceImage    = 152
7243     AdaptiveThreshold  = 153
7244     AdaptiveThresholdImage = 154
7245     Resample           = 155
7246     ResampleImage      = 156
7247     Describe           = 157
7248     DescribeImage      = 158
7249     BlackThreshold     = 159
7250     BlackThresholdImage= 160
7251     WhiteThreshold     = 161
7252     WhiteThresholdImage= 162
7253     RadialBlur         = 163
7254     RadialBlurImage    = 164
7255     Thumbnail          = 165
7256     ThumbnailImage     = 166
7257     Strip              = 167
7258     StripImage         = 168
7259     Tint               = 169
7260     TintImage          = 170
7261     Channel            = 171
7262     ChannelImage       = 172
7263     Splice             = 173
7264     SpliceImage        = 174
7265     Posterize          = 175
7266     PosterizeImage     = 176
7267     Shadow             = 177
7268     ShadowImage        = 178
7269     Identify           = 179
7270     IdentifyImage      = 180
7271     SepiaTone          = 181
7272     SepiaToneImage     = 182
7273     SigmoidalContrast  = 183
7274     SigmoidalContrastImage = 184
7275     Extent             = 185
7276     ExtentImage        = 186
7277     Vignette           = 187
7278     VignetteImage      = 188
7279     ContrastStretch    = 189
7280     ContrastStretchImage = 190
7281     Sans0              = 191
7282     Sans0Image         = 192
7283     Sans1              = 193
7284     Sans1Image         = 194
7285     AdaptiveSharpen    = 195
7286     AdaptiveSharpenImage = 196
7287     Transpose          = 197
7288     TransposeImage     = 198
7289     Transverse         = 199
7290     TransverseImage    = 200
7291     AutoOrient         = 201
7292     AutoOrientImage    = 202
7293     AdaptiveBlur       = 203
7294     AdaptiveBlurImage  = 204
7295     Sketch             = 205
7296     SketchImage        = 206
7297     UniqueColors       = 207
7298     UniqueColorsImage  = 208
7299     AdaptiveResize     = 209
7300     AdaptiveResizeImage= 210
7301     ClipMask           = 211
7302     ClipMaskImage      = 212
7303     LinearStretch      = 213
7304     LinearStretchImage = 214
7305     ColorMatrix        = 215
7306     ColorMatrixImage   = 216
7307     Mask               = 217
7308     MaskImage          = 218
7309     Polaroid           = 219
7310     PolaroidImage      = 220
7311     FloodfillPaint     = 221
7312     FloodfillPaintImage= 222
7313     Distort            = 223
7314     DistortImage       = 224
7315     Clut               = 225
7316     ClutImage          = 226
7317     LiquidRescale      = 227
7318     LiquidRescaleImage = 228
7319     Encipher           = 229
7320     EncipherImage      = 230
7321     Decipher           = 231
7322     DecipherImage      = 232
7323     Deskew             = 233
7324     DeskewImage        = 234
7325     Remap              = 235
7326     RemapImage         = 236
7327     SparseColor        = 237
7328     SparseColorImage   = 238
7329     Function           = 239
7330     FunctionImage      = 240
7331     SelectiveBlur      = 241
7332     SelectiveBlurImage = 242
7333     HaldClut           = 243
7334     HaldClutImage      = 244
7335     BlueShift          = 245
7336     BlueShiftImage     = 246
7337     ForwardFourierTransform  = 247
7338     ForwardFourierTransformImage = 248
7339     InverseFourierTransform = 249
7340     InverseFourierTransformImage = 250
7341     ColorDecisionList  = 251
7342     ColorDecisionListImage = 252
7343     AutoGamma          = 253
7344     AutoGammaImage     = 254
7345     AutoLevel          = 255
7346     AutoLevelImage     = 256
7347     LevelColors        = 257
7348     LevelImageColors   = 258
7349     Clamp              = 259
7350     ClampImage         = 260
7351     BrightnessContrast = 261
7352     BrightnessContrastImage = 262
7353     Morphology         = 263
7354     MorphologyImage    = 264
7355     Color              = 265
7356     ColorImage         = 266
7357     Mode               = 267
7358     ModeImage          = 268
7359     Statistic          = 269
7360     StatisticImage     = 270
7361     Perceptible        = 271
7362     PerceptibleImage   = 272
7363     Poly               = 273
7364     PolyImage          = 274
7365     MogrifyRegion      = 666
7366   PPCODE:
7367   {
7368     AffineMatrix
7369       affine,
7370       current;
7371
7372     char
7373       attribute_flag[MaxArguments],
7374       message[MaxTextExtent];
7375
7376     ChannelType
7377       channel,
7378       channel_mask;
7379
7380     CompositeOperator
7381       compose;
7382
7383     const char
7384       *attribute,
7385       *value;
7386
7387     double
7388       angle;
7389
7390     ExceptionInfo
7391       *exception;
7392
7393     GeometryInfo
7394       geometry_info;
7395
7396     Image
7397       *image,
7398       *next,
7399       *region_image;
7400
7401     MagickBooleanType
7402       status;
7403
7404     MagickStatusType
7405       flags;
7406
7407     PixelInfo
7408       fill_color;
7409
7410     RectangleInfo
7411       geometry,
7412       region_info;
7413
7414     register ssize_t
7415       i;
7416
7417     ssize_t
7418       base,
7419       j,
7420       number_images;
7421
7422     struct Methods
7423       *rp;
7424
7425     struct PackageInfo
7426       *info;
7427
7428     SV
7429       *perl_exception,
7430       **pv,
7431       *reference,
7432       **reference_vector;
7433
7434     struct ArgumentList
7435       argument_list[MaxArguments];
7436
7437     PERL_UNUSED_VAR(ref);
7438     PERL_UNUSED_VAR(ix);
7439     exception=AcquireExceptionInfo();
7440     perl_exception=newSVpv("",0);
7441     reference_vector=NULL;
7442     region_image=NULL;
7443     number_images=0;
7444     base=2;
7445     if (sv_isobject(ST(0)) == 0)
7446       {
7447         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7448           PackageName);
7449         goto PerlException;
7450       }
7451     reference=SvRV(ST(0));
7452     region_info.width=0;
7453     region_info.height=0;
7454     region_info.x=0;
7455     region_info.y=0;
7456     region_image=(Image *) NULL;
7457     image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7458     if (ix && (ix != 666))
7459       {
7460         /*
7461           Called as Method(...)
7462         */
7463         ix=(ix+1)/2;
7464         rp=(&Methods[ix-1]);
7465         attribute=rp->name;
7466       }
7467     else
7468       {
7469         /*
7470           Called as Mogrify("Method",...)
7471         */
7472         attribute=(char *) SvPV(ST(1),na);
7473         if (ix)
7474           {
7475             flags=ParseGravityGeometry(image,attribute,&region_info,exception);
7476             attribute=(char *) SvPV(ST(2),na);
7477             base++;
7478           }
7479         for (rp=Methods; ; rp++)
7480         {
7481           if (rp >= EndOf(Methods))
7482             {
7483               ThrowPerlException(exception,OptionError,
7484                 "UnrecognizedPerlMagickMethod",attribute);
7485               goto PerlException;
7486             }
7487           if (strEQcase(attribute,rp->name))
7488             break;
7489         }
7490         ix=rp-Methods+1;
7491         base++;
7492       }
7493     if (image == (Image *) NULL)
7494       {
7495         ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7496         goto PerlException;
7497       }
7498     Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7499     Zero(&attribute_flag,NumberOf(attribute_flag),char);
7500     for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7501     {
7502       Arguments
7503         *pp,
7504         *qq;
7505
7506       ssize_t
7507         ssize_test;
7508
7509       struct ArgumentList
7510         *al;
7511
7512       SV
7513         *sv;
7514
7515       sv=NULL;
7516       ssize_test=0;
7517       pp=(Arguments *) NULL;
7518       qq=rp->arguments;
7519       if (i == items)
7520         {
7521           pp=rp->arguments,
7522           sv=ST(i-1);
7523         }
7524       else
7525         for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7526         {
7527           if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7528             break;
7529           if (strEQcase(attribute,qq->method) > ssize_test)
7530             {
7531               pp=qq;
7532               ssize_test=strEQcase(attribute,qq->method);
7533             }
7534         }
7535       if (pp == (Arguments *) NULL)
7536         {
7537           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7538             attribute);
7539           goto continue_outer_loop;
7540         }
7541       al=(&argument_list[pp-rp->arguments]);
7542       switch (pp->type)
7543       {
7544         case ArrayReference:
7545         {
7546           if (SvTYPE(sv) != SVt_RV)
7547             {
7548               (void) FormatLocaleString(message,MaxTextExtent,
7549                 "invalid %.60s value",pp->method);
7550               ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7551               goto continue_outer_loop;
7552             }
7553           al->array_reference=SvRV(sv);
7554           break;
7555         }
7556         case RealReference:
7557         {
7558           al->real_reference=SvNV(sv);
7559           break;
7560         }
7561         case FileReference:
7562         {
7563           al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7564           break;
7565         }
7566         case ImageReference:
7567         {
7568           if (!sv_isobject(sv) ||
7569               !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7570                 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7571             {
7572               ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7573                 PackageName);
7574               goto PerlException;
7575             }
7576           break;
7577         }
7578         case IntegerReference:
7579         {
7580           al->integer_reference=SvIV(sv);
7581           break;
7582         }
7583         case StringReference:
7584         {
7585           al->string_reference=(char *) SvPV(sv,al->length);
7586           if (sv_isobject(sv))
7587             al->image_reference=SetupList(aTHX_ SvRV(sv),
7588               (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7589           break;
7590         }
7591         default:
7592         {
7593           /*
7594             Is a string; look up name.
7595           */
7596           if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7597             {
7598               al->string_reference=(char *) SvPV(sv,al->length);
7599               al->integer_reference=(-1);
7600               break;
7601             }
7602           al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7603             MagickFalse,SvPV(sv,na));
7604           if (pp->type == MagickChannelOptions)
7605             al->integer_reference=ParseChannelOption(SvPV(sv,na));
7606           if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7607             {
7608               (void) FormatLocaleString(message,MaxTextExtent,
7609                 "invalid %.60s value",pp->method);
7610               ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7611               goto continue_outer_loop;
7612             }
7613           break;
7614         }
7615       }
7616       attribute_flag[pp-rp->arguments]++;
7617       continue_outer_loop: ;
7618     }
7619     (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7620     pv=reference_vector;
7621     SetGeometryInfo(&geometry_info);
7622     channel=DefaultChannels;
7623     for (next=image; next; next=next->next)
7624     {
7625       image=next;
7626       SetGeometry(image,&geometry);
7627       if ((region_info.width*region_info.height) != 0)
7628         {
7629           region_image=image;
7630           image=CropImage(image,&region_info,exception);
7631         }
7632       switch (ix)
7633       {
7634         default:
7635         {
7636           (void) FormatLocaleString(message,MaxTextExtent,"%.20g",(double) ix);
7637           ThrowPerlException(exception,OptionError,
7638             "UnrecognizedPerlMagickMethod",message);
7639           goto PerlException;
7640         }
7641         case 1:  /* Comment */
7642         {
7643           if (attribute_flag[0] == 0)
7644             argument_list[0].string_reference=(char *) NULL;
7645           (void) SetImageProperty(image,"comment",InterpretImageProperties(
7646             info ? info->image_info : (ImageInfo *) NULL,image,
7647             argument_list[0].string_reference,exception),exception);
7648           break;
7649         }
7650         case 2:  /* Label */
7651         {
7652           if (attribute_flag[0] == 0)
7653             argument_list[0].string_reference=(char *) NULL;
7654           (void) SetImageProperty(image,"label",InterpretImageProperties(
7655             info ? info->image_info : (ImageInfo *) NULL,image,
7656             argument_list[0].string_reference,exception),exception);
7657           break;
7658         }
7659         case 3:  /* AddNoise */
7660         {
7661           double
7662             attenuate;
7663
7664           if (attribute_flag[0] == 0)
7665             argument_list[0].integer_reference=UniformNoise;
7666           attenuate=1.0;
7667           if (attribute_flag[1] != 0)
7668             attenuate=argument_list[1].real_reference;
7669           if (attribute_flag[2] != 0)
7670             channel=(ChannelType) argument_list[2].integer_reference;
7671           channel_mask=SetImageChannelMask(image,channel);
7672           image=AddNoiseImage(image,(NoiseType)
7673             argument_list[0].integer_reference,attenuate,exception);
7674           if (image != (Image *) NULL)
7675             (void) SetImageChannelMask(image,channel_mask);
7676           break;
7677         }
7678         case 4:  /* Colorize */
7679         {
7680           PixelInfo
7681             target;
7682
7683           (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7684             0,0,&target,exception);
7685           if (attribute_flag[0] != 0)
7686             (void) QueryColorCompliance(argument_list[0].string_reference,
7687               AllCompliance,&target,exception);
7688           if (attribute_flag[1] == 0)
7689             argument_list[1].string_reference="100%";
7690           image=ColorizeImage(image,argument_list[1].string_reference,&target,
7691             exception);
7692           break;
7693         }
7694         case 5:  /* Border */
7695         {
7696           CompositeOperator
7697             compose;
7698
7699           geometry.width=0;
7700           geometry.height=0;
7701           if (attribute_flag[0] != 0)
7702             flags=ParsePageGeometry(image,argument_list[0].string_reference,
7703               &geometry,exception);
7704           if (attribute_flag[1] != 0)
7705             geometry.width=argument_list[1].integer_reference;
7706           if (attribute_flag[2] != 0)
7707             geometry.height=argument_list[2].integer_reference;
7708           if (attribute_flag[3] != 0)
7709             QueryColorCompliance(argument_list[3].string_reference,
7710               AllCompliance,&image->border_color,exception);
7711           if (attribute_flag[4] != 0)
7712             QueryColorCompliance(argument_list[4].string_reference,
7713               AllCompliance,&image->border_color,exception);
7714           if (attribute_flag[5] != 0)
7715             QueryColorCompliance(argument_list[5].string_reference,
7716               AllCompliance,&image->border_color,exception);
7717           compose=image->compose;
7718           if (attribute_flag[6] != 0)
7719             compose=(CompositeOperator) argument_list[6].integer_reference;
7720           image=BorderImage(image,&geometry,compose,exception);
7721           break;
7722         }
7723         case 6:  /* Blur */
7724         {
7725           if (attribute_flag[0] != 0)
7726             {
7727               flags=ParseGeometry(argument_list[0].string_reference,
7728                 &geometry_info);
7729               if ((flags & SigmaValue) == 0)
7730                 geometry_info.sigma=1.0;
7731             }
7732           if (attribute_flag[1] != 0)
7733             geometry_info.rho=argument_list[1].real_reference;
7734           if (attribute_flag[2] != 0)
7735             geometry_info.sigma=argument_list[2].real_reference;
7736           if (attribute_flag[3] != 0)
7737             channel=(ChannelType) argument_list[3].integer_reference;
7738           channel_mask=SetImageChannelMask(image,channel);
7739           image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
7740             exception);
7741           if (image != (Image *) NULL)
7742             (void) SetImageChannelMask(image,channel_mask);
7743           break;
7744         }
7745         case 7:  /* Chop */
7746         {
7747           if (attribute_flag[0] != 0)
7748             flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7749               &geometry,exception);
7750           if (attribute_flag[1] != 0)
7751             geometry.width=argument_list[1].integer_reference;
7752           if (attribute_flag[2] != 0)
7753             geometry.height=argument_list[2].integer_reference;
7754           if (attribute_flag[3] != 0)
7755             geometry.x=argument_list[3].integer_reference;
7756           if (attribute_flag[4] != 0)
7757             geometry.y=argument_list[4].integer_reference;
7758           image=ChopImage(image,&geometry,exception);
7759           break;
7760         }
7761         case 8:  /* Crop */
7762         {
7763           if (attribute_flag[6] != 0)
7764             image->gravity=(GravityType) argument_list[6].integer_reference;
7765           if (attribute_flag[0] != 0)
7766             flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7767               &geometry,exception);
7768           if (attribute_flag[1] != 0)
7769             geometry.width=argument_list[1].integer_reference;
7770           if (attribute_flag[2] != 0)
7771             geometry.height=argument_list[2].integer_reference;
7772           if (attribute_flag[3] != 0)
7773             geometry.x=argument_list[3].integer_reference;
7774           if (attribute_flag[4] != 0)
7775             geometry.y=argument_list[4].integer_reference;
7776           if (attribute_flag[5] != 0)
7777             image->fuzz=StringToDoubleInterval(
7778               argument_list[5].string_reference,(double) QuantumRange+1.0);
7779           image=CropImage(image,&geometry,exception);
7780           break;
7781         }
7782         case 9:  /* Despeckle */
7783         {
7784           image=DespeckleImage(image,exception);
7785           break;
7786         }
7787         case 10:  /* Edge */
7788         {
7789           if (attribute_flag[0] != 0)
7790             geometry_info.rho=argument_list[0].real_reference;
7791           image=EdgeImage(image,geometry_info.rho,exception);
7792           break;
7793         }
7794         case 11:  /* Emboss */
7795         {
7796           if (attribute_flag[0] != 0)
7797             {
7798               flags=ParseGeometry(argument_list[0].string_reference,
7799                 &geometry_info);
7800               if ((flags & SigmaValue) == 0)
7801                 geometry_info.sigma=1.0;
7802             }
7803           if (attribute_flag[1] != 0)
7804             geometry_info.rho=argument_list[1].real_reference;
7805           if (attribute_flag[2] != 0)
7806             geometry_info.sigma=argument_list[2].real_reference;
7807           image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
7808             exception);
7809           break;
7810         }
7811         case 12:  /* Enhance */
7812         {
7813           image=EnhanceImage(image,exception);
7814           break;
7815         }
7816         case 13:  /* Flip */
7817         {
7818           image=FlipImage(image,exception);
7819           break;
7820         }
7821         case 14:  /* Flop */
7822         {
7823           image=FlopImage(image,exception);
7824           break;
7825         }
7826         case 15:  /* Frame */
7827         {
7828           CompositeOperator
7829             compose;
7830
7831           FrameInfo
7832             frame_info;
7833
7834           if (attribute_flag[0] != 0)
7835             {
7836               flags=ParsePageGeometry(image,argument_list[0].string_reference,
7837                 &geometry,exception);
7838               frame_info.width=geometry.width;
7839               frame_info.height=geometry.height;
7840               frame_info.outer_bevel=geometry.x;
7841               frame_info.inner_bevel=geometry.y;
7842             }
7843           if (attribute_flag[1] != 0)
7844             frame_info.width=argument_list[1].integer_reference;
7845           if (attribute_flag[2] != 0)
7846             frame_info.height=argument_list[2].integer_reference;
7847           if (attribute_flag[3] != 0)
7848             frame_info.inner_bevel=argument_list[3].integer_reference;
7849           if (attribute_flag[4] != 0)
7850             frame_info.outer_bevel=argument_list[4].integer_reference;
7851           if (attribute_flag[5] != 0)
7852             QueryColorCompliance(argument_list[5].string_reference,
7853               AllCompliance,&fill_color,exception);
7854           if (attribute_flag[6] != 0)
7855             QueryColorCompliance(argument_list[6].string_reference,
7856               AllCompliance,&fill_color,exception);
7857           frame_info.x=(ssize_t) frame_info.width;
7858           frame_info.y=(ssize_t) frame_info.height;
7859           frame_info.width=image->columns+2*frame_info.x;
7860           frame_info.height=image->rows+2*frame_info.y;
7861           if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
7862             image->matte_color=fill_color;
7863           compose=image->compose;
7864           if (attribute_flag[7] != 0)
7865             compose=(CompositeOperator) argument_list[7].integer_reference;
7866           image=FrameImage(image,&frame_info,compose,exception);
7867           break;
7868         }
7869         case 16:  /* Implode */
7870         {
7871           PixelInterpolateMethod
7872             method;
7873
7874           if (attribute_flag[0] == 0)
7875             argument_list[0].real_reference=0.5;
7876           method=UndefinedInterpolatePixel;
7877           if (attribute_flag[1] != 0)
7878             method=(PixelInterpolateMethod) argument_list[1].integer_reference;
7879           image=ImplodeImage(image,argument_list[0].real_reference,
7880             method,exception);
7881           break;
7882         }
7883         case 17:  /* Magnify */
7884         {
7885           image=MagnifyImage(image,exception);
7886           break;
7887         }
7888         case 18:  /* MedianFilter */
7889         {
7890           if (attribute_flag[0] != 0)
7891             {
7892               flags=ParseGeometry(argument_list[0].string_reference,
7893                 &geometry_info);
7894               if ((flags & SigmaValue) == 0)
7895                 geometry_info.sigma=geometry_info.rho;
7896             }
7897           if (attribute_flag[1] != 0)
7898             geometry_info.rho=argument_list[1].real_reference;
7899           if (attribute_flag[2] != 0)
7900             geometry_info.sigma=argument_list[2].real_reference;
7901           if (attribute_flag[3] != 0)
7902             channel=(ChannelType) argument_list[3].integer_reference;
7903           channel_mask=SetImageChannelMask(image,channel);
7904           image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
7905             (size_t) geometry_info.sigma,exception);
7906           if (image != (Image *) NULL)
7907             (void) SetImageChannelMask(image,channel_mask);
7908           break;
7909         }
7910         case 19:  /* Minify */
7911         {
7912           image=MinifyImage(image,exception);
7913           break;
7914         }
7915         case 20:  /* OilPaint */
7916         {
7917           if (attribute_flag[0] == 0)
7918             argument_list[0].real_reference=0.0;
7919           if (attribute_flag[1] == 0)
7920             argument_list[1].real_reference=1.0;
7921           image=OilPaintImage(image,argument_list[0].real_reference,
7922             argument_list[1].real_reference,exception);
7923           break;
7924         }
7925         case 21:  /* ReduceNoise */
7926         {
7927           if (attribute_flag[0] != 0)
7928             {
7929               flags=ParseGeometry(argument_list[0].string_reference,
7930                 &geometry_info);
7931               if ((flags & SigmaValue) == 0)
7932                 geometry_info.sigma=1.0;
7933             }
7934           if (attribute_flag[1] != 0)
7935             geometry_info.rho=argument_list[1].real_reference;
7936           if (attribute_flag[2] != 0)
7937             geometry_info.sigma=argument_list[2].real_reference;
7938           if (attribute_flag[3] != 0)
7939             channel=(ChannelType) argument_list[3].integer_reference;
7940           channel_mask=SetImageChannelMask(image,channel);
7941           image=StatisticImage(image,NonpeakStatistic,(size_t)
7942             geometry_info.rho,(size_t) geometry_info.sigma,exception);
7943           if (image != (Image *) NULL)
7944             (void) SetImageChannelMask(image,channel_mask);
7945           break;
7946         }
7947         case 22:  /* Roll */
7948         {
7949           if (attribute_flag[0] != 0)
7950             flags=ParsePageGeometry(image,argument_list[0].string_reference,
7951               &geometry,exception);
7952           if (attribute_flag[1] != 0)
7953             geometry.x=argument_list[1].integer_reference;
7954           if (attribute_flag[2] != 0)
7955             geometry.y=argument_list[2].integer_reference;
7956           image=RollImage(image,geometry.x,geometry.y,exception);
7957           break;
7958         }
7959         case 23:  /* Rotate */
7960         {
7961           if (attribute_flag[0] == 0)
7962             argument_list[0].real_reference=90.0;
7963           if (attribute_flag[1] != 0)
7964             {
7965               QueryColorCompliance(argument_list[1].string_reference,
7966                 AllCompliance,&image->background_color,exception);
7967               if ((image->background_color.alpha_trait == BlendPixelTrait) &&
7968                   (image->alpha_trait != BlendPixelTrait))
7969                 (void) SetImageAlpha(image,OpaqueAlpha,exception);
7970             }
7971           image=RotateImage(image,argument_list[0].real_reference,exception);
7972           break;
7973         }
7974         case 24:  /* Sample */
7975         {
7976           if (attribute_flag[0] != 0)
7977             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
7978               &geometry,exception);
7979           if (attribute_flag[1] != 0)
7980             geometry.width=argument_list[1].integer_reference;
7981           if (attribute_flag[2] != 0)
7982             geometry.height=argument_list[2].integer_reference;
7983           image=SampleImage(image,geometry.width,geometry.height,exception);
7984           break;
7985         }
7986         case 25:  /* Scale */
7987         {
7988           if (attribute_flag[0] != 0)
7989             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
7990               &geometry,exception);
7991           if (attribute_flag[1] != 0)
7992             geometry.width=argument_list[1].integer_reference;
7993           if (attribute_flag[2] != 0)
7994             geometry.height=argument_list[2].integer_reference;
7995           image=ScaleImage(image,geometry.width,geometry.height,exception);
7996           break;
7997         }
7998         case 26:  /* Shade */
7999         {
8000           if (attribute_flag[0] != 0)
8001             {
8002               flags=ParseGeometry(argument_list[0].string_reference,
8003                 &geometry_info);
8004               if ((flags & SigmaValue) == 0)
8005                 geometry_info.sigma=0.0;
8006             }
8007           if (attribute_flag[1] != 0)
8008             geometry_info.rho=argument_list[1].real_reference;
8009           if (attribute_flag[2] != 0)
8010             geometry_info.sigma=argument_list[2].real_reference;
8011           image=ShadeImage(image,
8012             argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8013             geometry_info.rho,geometry_info.sigma,exception);
8014           break;
8015         }
8016         case 27:  /* Sharpen */
8017         {
8018           if (attribute_flag[0] != 0)
8019             {
8020               flags=ParseGeometry(argument_list[0].string_reference,
8021                 &geometry_info);
8022               if ((flags & SigmaValue) == 0)
8023                 geometry_info.sigma=1.0;
8024             }
8025           if (attribute_flag[1] != 0)
8026             geometry_info.rho=argument_list[1].real_reference;
8027           if (attribute_flag[2] != 0)
8028             geometry_info.sigma=argument_list[2].real_reference;
8029           if (attribute_flag[3] != 0)
8030             channel=(ChannelType) argument_list[3].integer_reference;
8031           channel_mask=SetImageChannelMask(image,channel);
8032           image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8033             exception);
8034           if (image != (Image *) NULL)
8035             (void) SetImageChannelMask(image,channel_mask);
8036           break;
8037         }
8038         case 28:  /* Shear */
8039         {
8040           if (attribute_flag[0] != 0)
8041             {
8042               flags=ParseGeometry(argument_list[0].string_reference,
8043                 &geometry_info);
8044               if ((flags & SigmaValue) == 0)
8045                 geometry_info.sigma=geometry_info.rho;
8046             }
8047           if (attribute_flag[1] != 0)
8048             geometry_info.rho=argument_list[1].real_reference;
8049           if (attribute_flag[2] != 0)
8050             geometry_info.sigma=argument_list[2].real_reference;
8051           if (attribute_flag[3] != 0)
8052             QueryColorCompliance(argument_list[3].string_reference,
8053               AllCompliance,&image->background_color,exception);
8054           if (attribute_flag[4] != 0)
8055             QueryColorCompliance(argument_list[4].string_reference,
8056               AllCompliance,&image->background_color,exception);
8057           image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8058             exception);
8059           break;
8060         }
8061         case 29:  /* Spread */
8062         {
8063           PixelInterpolateMethod
8064             method;
8065
8066           if (attribute_flag[0] == 0)
8067             argument_list[0].real_reference=1.0;
8068           method=UndefinedInterpolatePixel;
8069           if (attribute_flag[1] != 0)
8070             method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8071           image=SpreadImage(image,argument_list[0].real_reference,method,
8072             exception);
8073           break;
8074         }
8075         case 30:  /* Swirl */
8076         {
8077           PixelInterpolateMethod
8078             method;
8079
8080           if (attribute_flag[0] == 0)
8081             argument_list[0].real_reference=50.0;
8082           method=UndefinedInterpolatePixel;
8083           if (attribute_flag[1] != 0)
8084             method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8085           image=SwirlImage(image,argument_list[0].real_reference,
8086             method,exception);
8087           break;
8088         }
8089         case 31:  /* Resize */
8090         case 32:  /* Zoom */
8091         {
8092           if (attribute_flag[0] != 0)
8093             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8094               &geometry,exception);
8095           if (attribute_flag[1] != 0)
8096             geometry.width=argument_list[1].integer_reference;
8097           if (attribute_flag[2] != 0)
8098             geometry.height=argument_list[2].integer_reference;
8099           if (attribute_flag[3] == 0)
8100             argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8101           if (attribute_flag[4] != 0)
8102             SetImageArtifact(image,"filter:support",
8103               argument_list[4].string_reference);
8104           image=ResizeImage(image,geometry.width,geometry.height,
8105             (FilterTypes) argument_list[3].integer_reference,
8106             exception);
8107           break;
8108         }
8109         case 33:  /* Annotate */
8110         {
8111           DrawInfo
8112             *draw_info;
8113
8114           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8115             (DrawInfo *) NULL);
8116           if (attribute_flag[0] != 0)
8117             {
8118               char
8119                 *text;
8120
8121               text=InterpretImageProperties(info ? info->image_info :
8122                 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8123                 exception);
8124               (void) CloneString(&draw_info->text,text);
8125               text=DestroyString(text);
8126             }
8127           if (attribute_flag[1] != 0)
8128             (void) CloneString(&draw_info->font,
8129               argument_list[1].string_reference);
8130           if (attribute_flag[2] != 0)
8131             draw_info->pointsize=argument_list[2].real_reference;
8132           if (attribute_flag[3] != 0)
8133             (void) CloneString(&draw_info->density,
8134               argument_list[3].string_reference);
8135           if (attribute_flag[4] != 0)
8136             (void) QueryColorCompliance(argument_list[4].string_reference,
8137               AllCompliance,&draw_info->undercolor,exception);
8138           if (attribute_flag[5] != 0)
8139             {
8140               (void) QueryColorCompliance(argument_list[5].string_reference,
8141                 AllCompliance,&draw_info->stroke,exception);
8142               if (argument_list[5].image_reference != (Image *) NULL)
8143                 draw_info->stroke_pattern=CloneImage(
8144                   argument_list[5].image_reference,0,0,MagickTrue,exception);
8145             }
8146           if (attribute_flag[6] != 0)
8147             {
8148               (void) QueryColorCompliance(argument_list[6].string_reference,
8149                 AllCompliance,&draw_info->fill,exception);
8150               if (argument_list[6].image_reference != (Image *) NULL)
8151                 draw_info->fill_pattern=CloneImage(
8152                   argument_list[6].image_reference,0,0,MagickTrue,exception);
8153             }
8154           if (attribute_flag[7] != 0)
8155             {
8156               (void) CloneString(&draw_info->geometry,
8157                 argument_list[7].string_reference);
8158               flags=ParsePageGeometry(image,argument_list[7].string_reference,
8159                 &geometry,exception);
8160               if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8161                 geometry_info.sigma=geometry_info.xi;
8162             }
8163           if (attribute_flag[8] != 0)
8164             (void) QueryColorCompliance(argument_list[8].string_reference,
8165               AllCompliance,&draw_info->fill,exception);
8166           if (attribute_flag[11] != 0)
8167             draw_info->gravity=(GravityType)
8168               argument_list[11].integer_reference;
8169           if (attribute_flag[25] != 0)
8170             {
8171               AV
8172                 *av;
8173
8174               av=(AV *) argument_list[25].array_reference;
8175               if ((av_len(av) != 3) && (av_len(av) != 5))
8176                 {
8177                   ThrowPerlException(exception,OptionError,
8178                     "affine matrix must have 4 or 6 elements",PackageName);
8179                   goto PerlException;
8180                 }
8181               draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8182               draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8183               draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8184               draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8185               if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8186                   draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8187                 {
8188                   ThrowPerlException(exception,OptionError,
8189                     "affine matrix is singular",PackageName);
8190                    goto PerlException;
8191                 }
8192               if (av_len(av) == 5)
8193                 {
8194                   draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8195                   draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8196                 }
8197             }
8198           for (j=12; j < 17; j++)
8199           {
8200             if (attribute_flag[j] == 0)
8201               continue;
8202             value=argument_list[j].string_reference;
8203             angle=argument_list[j].real_reference;
8204             current=draw_info->affine;
8205             GetAffineMatrix(&affine);
8206             switch (j)
8207             {
8208               case 12:
8209               {
8210                 /*
8211                   Translate.
8212                 */
8213                 flags=ParseGeometry(value,&geometry_info);
8214                 affine.tx=geometry_info.xi;
8215                 affine.ty=geometry_info.psi;
8216                 if ((flags & PsiValue) == 0)
8217                   affine.ty=affine.tx;
8218                 break;
8219               }
8220               case 13:
8221               {
8222                 /*
8223                   Scale.
8224                 */
8225                 flags=ParseGeometry(value,&geometry_info);
8226                 affine.sx=geometry_info.rho;
8227                 affine.sy=geometry_info.sigma;
8228                 if ((flags & SigmaValue) == 0)
8229                   affine.sy=affine.sx;
8230                 break;
8231               }
8232               case 14:
8233               {
8234                 /*
8235                   Rotate.
8236                 */
8237                 if (angle == 0.0)
8238                   break;
8239                 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8240                 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8241                 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8242                 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8243                 break;
8244               }
8245               case 15:
8246               {
8247                 /*
8248                   SkewX.
8249                 */
8250                 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8251                 break;
8252               }
8253               case 16:
8254               {
8255                 /*
8256                   SkewY.
8257                 */
8258                 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8259                 break;
8260               }
8261             }
8262             draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8263             draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8264             draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8265             draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8266             draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8267               current.tx;
8268             draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8269               current.ty;
8270           }
8271           if (attribute_flag[9] == 0)
8272             argument_list[9].real_reference=0.0;
8273           if (attribute_flag[10] == 0)
8274             argument_list[10].real_reference=0.0;
8275           if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8276             {
8277               char
8278                 geometry[MaxTextExtent];
8279
8280               (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
8281                 (double) argument_list[9].real_reference+draw_info->affine.tx,
8282                 (double) argument_list[10].real_reference+draw_info->affine.ty);
8283               (void) CloneString(&draw_info->geometry,geometry);
8284             }
8285           if (attribute_flag[17] != 0)
8286             draw_info->stroke_width=argument_list[17].real_reference;
8287           if (attribute_flag[18] != 0)
8288             {
8289               draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8290                 MagickTrue : MagickFalse;
8291               draw_info->stroke_antialias=draw_info->text_antialias;
8292             }
8293           if (attribute_flag[19] != 0)
8294             (void) CloneString(&draw_info->family,
8295               argument_list[19].string_reference);
8296           if (attribute_flag[20] != 0)
8297             draw_info->style=(StyleType) argument_list[20].integer_reference;
8298           if (attribute_flag[21] != 0)
8299             draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8300           if (attribute_flag[22] != 0)
8301             draw_info->weight=argument_list[22].integer_reference;
8302           if (attribute_flag[23] != 0)
8303             draw_info->align=(AlignType) argument_list[23].integer_reference;
8304           if (attribute_flag[24] != 0)
8305             (void) CloneString(&draw_info->encoding,
8306               argument_list[24].string_reference);
8307           if (attribute_flag[25] != 0)
8308             draw_info->fill_pattern=CloneImage(
8309               argument_list[25].image_reference,0,0,MagickTrue,exception);
8310           if (attribute_flag[26] != 0)
8311             draw_info->fill_pattern=CloneImage(
8312               argument_list[26].image_reference,0,0,MagickTrue,exception);
8313           if (attribute_flag[27] != 0)
8314             draw_info->stroke_pattern=CloneImage(
8315               argument_list[27].image_reference,0,0,MagickTrue,exception);
8316           if (attribute_flag[29] != 0)
8317             draw_info->kerning=argument_list[29].real_reference;
8318           if (attribute_flag[30] != 0)
8319             draw_info->interline_spacing=argument_list[30].real_reference;
8320           if (attribute_flag[31] != 0)
8321             draw_info->interword_spacing=argument_list[31].real_reference;
8322           if (attribute_flag[32] != 0)
8323             draw_info->direction=(DirectionType)
8324               argument_list[32].integer_reference;
8325           (void) AnnotateImage(image,draw_info,exception);
8326           draw_info=DestroyDrawInfo(draw_info);
8327           break;
8328         }
8329         case 34:  /* ColorFloodfill */
8330         {
8331           DrawInfo
8332             *draw_info;
8333
8334           MagickBooleanType
8335             invert;
8336
8337           PixelInfo
8338             target;
8339
8340           draw_info=CloneDrawInfo(info ? info->image_info :
8341             (ImageInfo *) NULL,(DrawInfo *) NULL);
8342           if (attribute_flag[0] != 0)
8343             flags=ParsePageGeometry(image,argument_list[0].string_reference,
8344               &geometry,exception);
8345           if (attribute_flag[1] != 0)
8346             geometry.x=argument_list[1].integer_reference;
8347           if (attribute_flag[2] != 0)
8348             geometry.y=argument_list[2].integer_reference;
8349           if (attribute_flag[3] != 0)
8350             (void) QueryColorCompliance(argument_list[3].string_reference,
8351               AllCompliance,&draw_info->fill,exception);
8352           (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8353             geometry.x,geometry.y,&target,exception);
8354           invert=MagickFalse;
8355           if (attribute_flag[4] != 0)
8356             {
8357               QueryColorCompliance(argument_list[4].string_reference,
8358                 AllCompliance,&target,exception);
8359               invert=MagickTrue;
8360             }
8361           if (attribute_flag[5] != 0)
8362             image->fuzz=StringToDoubleInterval(
8363               argument_list[5].string_reference,(double) QuantumRange+1.0);
8364           if (attribute_flag[6] != 0)
8365             invert=(MagickBooleanType) argument_list[6].integer_reference;
8366           (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8367             geometry.y,invert,exception);
8368           draw_info=DestroyDrawInfo(draw_info);
8369           break;
8370         }
8371         case 35:  /* Composite */
8372         {
8373           char
8374             composite_geometry[MaxTextExtent];
8375
8376           Image
8377             *composite_image,
8378             *rotate_image;
8379
8380           MagickBooleanType
8381             clip_to_self;
8382
8383           compose=OverCompositeOp;
8384           if (attribute_flag[0] != 0)
8385             composite_image=argument_list[0].image_reference;
8386           else
8387             {
8388               ThrowPerlException(exception,OptionError,
8389                 "CompositeImageRequired",PackageName);
8390               goto PerlException;
8391             }
8392           /*
8393             Parameter Handling used for BOTH normal and tiled composition.
8394           */
8395           if (attribute_flag[1] != 0) /* compose */
8396             compose=(CompositeOperator) argument_list[1].integer_reference;
8397           if (attribute_flag[6] != 0) /* opacity  */
8398             {
8399               if (compose != DissolveCompositeOp)
8400                 (void) SetImageAlpha(composite_image,(Quantum)
8401                   StringToDoubleInterval(argument_list[6].string_reference,
8402                   (double) QuantumRange+1.0),exception);
8403               else
8404                 {
8405                   CacheView
8406                     *composite_view;
8407
8408                   double
8409                     opacity;
8410
8411                   MagickBooleanType
8412                     sync;
8413
8414                   register ssize_t
8415                     x;
8416
8417                   register Quantum
8418                     *q;
8419
8420                   ssize_t
8421                     y;
8422
8423                   /*
8424                     Handle dissolve composite operator (patch by
8425                     Kevin A. McGrail).
8426                   */
8427                   (void) CloneString(&image->geometry,
8428                     argument_list[6].string_reference);
8429                   opacity=(Quantum) StringToDoubleInterval(
8430                     argument_list[6].string_reference,(double) QuantumRange+
8431                     1.0);
8432                   if (composite_image->alpha_trait == BlendPixelTrait)
8433                     (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8434                   composite_view=AcquireAuthenticCacheView(composite_image,exception);
8435                   for (y=0; y < (ssize_t) composite_image->rows ; y++)
8436                   {
8437                     q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8438                       composite_image->columns,1,exception);
8439                     for (x=0; x < (ssize_t) composite_image->columns; x++)
8440                     {
8441                       if (GetPixelAlpha(image,q) == OpaqueAlpha)
8442                         SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8443                           q);
8444                       q+=GetPixelChannels(composite_image);
8445                     }
8446                     sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8447                     if (sync == MagickFalse)
8448                       break;
8449                   }
8450                   composite_view=DestroyCacheView(composite_view);
8451                 }
8452             }
8453           if (attribute_flag[9] != 0)    /* "color=>" */
8454             QueryColorCompliance(argument_list[9].string_reference,
8455               AllCompliance,&composite_image->background_color,exception);
8456           if (attribute_flag[12] != 0) /* "interpolate=>" */
8457             image->interpolate=(PixelInterpolateMethod)
8458               argument_list[12].integer_reference;
8459           if (attribute_flag[13] != 0)   /* "args=>" */
8460             (void) SetImageArtifact(composite_image,"compose:args",
8461               argument_list[13].string_reference);
8462           if (attribute_flag[14] != 0)   /* "blend=>"  depreciated */
8463             (void) SetImageArtifact(composite_image,"compose:args",
8464               argument_list[14].string_reference);
8465           clip_to_self=MagickTrue;
8466           if (attribute_flag[15] != 0)
8467             clip_to_self=(MagickBooleanType)
8468               argument_list[15].integer_reference;
8469           /*
8470             Tiling Composition (with orthogonal rotate).
8471           */
8472           rotate_image=(Image *) NULL;
8473           if (attribute_flag[8] != 0)   /* "rotate=>" */
8474             {
8475                /*
8476                  Rotate image.
8477                */
8478                rotate_image=RotateImage(composite_image,
8479                  argument_list[8].real_reference,exception);
8480                if (rotate_image == (Image *) NULL)
8481                  break;
8482             }
8483           if ((attribute_flag[7] != 0) &&
8484               (argument_list[7].integer_reference != 0)) /* tile */
8485             {
8486               ssize_t
8487                 x,
8488                 y;
8489
8490               /*
8491                 Tile the composite image.
8492               */
8493              if (attribute_flag[8] != 0)   /* "tile=>" */
8494                (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
8495                  "false");
8496              else
8497                (void) SetImageArtifact(composite_image,
8498                  "compose:outside-overlay","false");
8499              for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8500                 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8501                 {
8502                   if (attribute_flag[8] != 0) /* rotate */
8503                     (void) CompositeImage(image,rotate_image,compose,
8504                       MagickTrue,x,y,exception);
8505                   else
8506                     (void) CompositeImage(image,composite_image,compose,
8507                       MagickTrue,x,y,exception);
8508                 }
8509               if (attribute_flag[8] != 0) /* rotate */
8510                 rotate_image=DestroyImage(rotate_image);
8511               break;
8512             }
8513           /*
8514             Parameter Handling used used ONLY for normal composition.
8515           */
8516           if (attribute_flag[5] != 0) /* gravity */
8517             image->gravity=(GravityType) argument_list[5].integer_reference;
8518           if (attribute_flag[2] != 0) /* geometry offset */
8519             {
8520               SetGeometry(image,&geometry);
8521               (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8522                 &geometry);
8523               GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8524                 &geometry);
8525             }
8526           if (attribute_flag[3] != 0) /* x offset */
8527             geometry.x=argument_list[3].integer_reference;
8528           if (attribute_flag[4] != 0) /* y offset */
8529             geometry.y=argument_list[4].integer_reference;
8530           if (attribute_flag[10] != 0) /* mask */
8531             {
8532               if ((image->compose == DisplaceCompositeOp) ||
8533                   (image->compose == DistortCompositeOp))
8534                 {
8535                   /*
8536                     Merge Y displacement into X displacement image.
8537                   */
8538                   composite_image=CloneImage(composite_image,0,0,MagickTrue,
8539                     exception);
8540                   (void) CompositeImage(composite_image,
8541                     argument_list[10].image_reference,CopyGreenCompositeOp,
8542                     MagickTrue,0,0,exception);
8543                 }
8544               else
8545                 {
8546                   Image
8547                     *mask_image;
8548
8549                   /*
8550                     Set a blending mask for the composition.
8551                   */
8552                   mask_image=CloneImage(argument_list[10].image_reference,0,0,
8553                     MagickTrue,exception);
8554                   (void) NegateImage(mask_image,MagickFalse,exception);
8555                   (void) SetImageMask(composite_image,mask_image,exception);
8556                   mask_image=DestroyImage(mask_image);
8557                 }
8558             }
8559           if (attribute_flag[11] != 0) /* channel */
8560             channel=(ChannelType) argument_list[11].integer_reference;
8561           /*
8562             Composite two images (normal composition).
8563           */
8564           (void) FormatLocaleString(composite_geometry,MaxTextExtent,
8565             "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8566             (double) composite_image->rows,(double) geometry.x,(double)
8567             geometry.y);
8568           flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8569             exception);
8570           channel_mask=SetImageChannelMask(image,channel);
8571           if (attribute_flag[8] == 0) /* no rotate */
8572             CompositeImage(image,composite_image,compose,clip_to_self,
8573               geometry.x,geometry.y,exception);
8574           else
8575             {
8576               /*
8577                 Position adjust rotated image then composite.
8578               */
8579               geometry.x-=(ssize_t) (rotate_image->columns-
8580                 composite_image->columns)/2;
8581               geometry.y-=(ssize_t) (rotate_image->rows-
8582                 composite_image->rows)/2;
8583               CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8584                 geometry.y,exception);
8585               rotate_image=DestroyImage(rotate_image);
8586             }
8587           if (attribute_flag[10] != 0) /* mask */
8588             {
8589               if ((image->compose == DisplaceCompositeOp) ||
8590                   (image->compose == DistortCompositeOp))
8591                 composite_image=DestroyImage(composite_image);
8592               else
8593                 (void) SetImageMask(image,(Image *) NULL,exception);
8594             }
8595           (void) SetImageChannelMask(image,channel_mask);
8596           break;
8597         }
8598         case 36:  /* Contrast */
8599         {
8600           if (attribute_flag[0] == 0)
8601             argument_list[0].integer_reference=0;
8602           (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8603             MagickTrue : MagickFalse,exception);
8604           break;
8605         }
8606         case 37:  /* CycleColormap */
8607         {
8608           if (attribute_flag[0] == 0)
8609             argument_list[0].integer_reference=6;
8610           (void) CycleColormapImage(image,argument_list[0].integer_reference,
8611             exception);
8612           break;
8613         }
8614         case 38:  /* Draw */
8615         {
8616           DrawInfo
8617             *draw_info;
8618
8619           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8620             (DrawInfo *) NULL);
8621           (void) CloneString(&draw_info->primitive,"point");
8622           if (attribute_flag[0] != 0)
8623             {
8624               if (argument_list[0].integer_reference < 0)
8625                 (void) CloneString(&draw_info->primitive,
8626                   argument_list[0].string_reference);
8627               else
8628                 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8629                   MagickPrimitiveOptions,argument_list[0].integer_reference));
8630             }
8631           if (attribute_flag[1] != 0)
8632             {
8633               if (LocaleCompare(draw_info->primitive,"path") == 0)
8634                 {
8635                   (void) ConcatenateString(&draw_info->primitive," '");
8636                   ConcatenateString(&draw_info->primitive,
8637                     argument_list[1].string_reference);
8638                   (void) ConcatenateString(&draw_info->primitive,"'");
8639                 }
8640               else
8641                 {
8642                   (void) ConcatenateString(&draw_info->primitive," ");
8643                   ConcatenateString(&draw_info->primitive,
8644                     argument_list[1].string_reference);
8645                 }
8646             }
8647           if (attribute_flag[2] != 0)
8648             {
8649               (void) ConcatenateString(&draw_info->primitive," ");
8650               (void) ConcatenateString(&draw_info->primitive,
8651                 CommandOptionToMnemonic(MagickMethodOptions,
8652                 argument_list[2].integer_reference));
8653             }
8654           if (attribute_flag[3] != 0)
8655             {
8656               (void) QueryColorCompliance(argument_list[3].string_reference,
8657                 AllCompliance,&draw_info->stroke,exception);
8658               if (argument_list[3].image_reference != (Image *) NULL)
8659                 draw_info->stroke_pattern=CloneImage(
8660                   argument_list[3].image_reference,0,0,MagickTrue,exception);
8661             }
8662           if (attribute_flag[4] != 0)
8663             {
8664               (void) QueryColorCompliance(argument_list[4].string_reference,
8665                 AllCompliance,&draw_info->fill,exception);
8666               if (argument_list[4].image_reference != (Image *) NULL)
8667                 draw_info->fill_pattern=CloneImage(
8668                   argument_list[4].image_reference,0,0,MagickTrue,exception);
8669             }
8670           if (attribute_flag[5] != 0)
8671             draw_info->stroke_width=argument_list[5].real_reference;
8672           if (attribute_flag[6] != 0)
8673             (void) CloneString(&draw_info->font,
8674               argument_list[6].string_reference);
8675           if (attribute_flag[7] != 0)
8676             (void) QueryColorCompliance(argument_list[7].string_reference,
8677               AllCompliance,&draw_info->border_color,exception);
8678           if (attribute_flag[8] != 0)
8679             draw_info->affine.tx=argument_list[8].real_reference;
8680           if (attribute_flag[9] != 0)
8681             draw_info->affine.ty=argument_list[9].real_reference;
8682           if (attribute_flag[20] != 0)
8683             {
8684               AV
8685                 *av;
8686
8687               av=(AV *) argument_list[20].array_reference;
8688               if ((av_len(av) != 3) && (av_len(av) != 5))
8689                 {
8690                   ThrowPerlException(exception,OptionError,
8691                     "affine matrix must have 4 or 6 elements",PackageName);
8692                   goto PerlException;
8693                 }
8694               draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8695               draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8696               draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8697               draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8698               if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8699                   draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8700                 {
8701                   ThrowPerlException(exception,OptionError,
8702                     "affine matrix is singular",PackageName);
8703                    goto PerlException;
8704                 }
8705               if (av_len(av) == 5)
8706                 {
8707                   draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8708                   draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8709                 }
8710             }
8711           for (j=10; j < 15; j++)
8712           {
8713             if (attribute_flag[j] == 0)
8714               continue;
8715             value=argument_list[j].string_reference;
8716             angle=argument_list[j].real_reference;
8717             current=draw_info->affine;
8718             GetAffineMatrix(&affine);
8719             switch (j)
8720             {
8721               case 10:
8722               {
8723                 /*
8724                   Translate.
8725                 */
8726                 flags=ParseGeometry(value,&geometry_info);
8727                 affine.tx=geometry_info.xi;
8728                 affine.ty=geometry_info.psi;
8729                 if ((flags & PsiValue) == 0)
8730                   affine.ty=affine.tx;
8731                 break;
8732               }
8733               case 11:
8734               {
8735                 /*
8736                   Scale.
8737                 */
8738                 flags=ParseGeometry(value,&geometry_info);
8739                 affine.sx=geometry_info.rho;
8740                 affine.sy=geometry_info.sigma;
8741                 if ((flags & SigmaValue) == 0)
8742                   affine.sy=affine.sx;
8743                 break;
8744               }
8745               case 12:
8746               {
8747                 /*
8748                   Rotate.
8749                 */
8750                 if (angle == 0.0)
8751                   break;
8752                 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8753                 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8754                 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8755                 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8756                 break;
8757               }
8758               case 13:
8759               {
8760                 /*
8761                   SkewX.
8762                 */
8763                 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8764                 break;
8765               }
8766               case 14:
8767               {
8768                 /*
8769                   SkewY.
8770                 */
8771                 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8772                 break;
8773               }
8774             }
8775             draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8776             draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8777             draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8778             draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8779             draw_info->affine.tx=
8780               current.sx*affine.tx+current.ry*affine.ty+current.tx;
8781             draw_info->affine.ty=
8782               current.rx*affine.tx+current.sy*affine.ty+current.ty;
8783           }
8784           if (attribute_flag[15] != 0)
8785             draw_info->fill_pattern=CloneImage(
8786               argument_list[15].image_reference,0,0,MagickTrue,exception);
8787           if (attribute_flag[16] != 0)
8788             draw_info->pointsize=argument_list[16].real_reference;
8789           if (attribute_flag[17] != 0)
8790             {
8791               draw_info->stroke_antialias=argument_list[17].integer_reference != 0
8792                 ? MagickTrue : MagickFalse;
8793               draw_info->text_antialias=draw_info->stroke_antialias;
8794             }
8795           if (attribute_flag[18] != 0)
8796             (void) CloneString(&draw_info->density,
8797               argument_list[18].string_reference);
8798           if (attribute_flag[19] != 0)
8799             draw_info->stroke_width=argument_list[19].real_reference;
8800           if (attribute_flag[21] != 0)
8801             draw_info->dash_offset=argument_list[21].real_reference;
8802           if (attribute_flag[22] != 0)
8803             {
8804               AV
8805                 *av;
8806
8807               av=(AV *) argument_list[22].array_reference;
8808               draw_info->dash_pattern=(double *) AcquireQuantumMemory(
8809                 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
8810               if (draw_info->dash_pattern != (double *) NULL)
8811                 {
8812                   for (i=0; i <= av_len(av); i++)
8813                     draw_info->dash_pattern[i]=(double)
8814                       SvNV(*(av_fetch(av,i,0)));
8815                   draw_info->dash_pattern[i]=0.0;
8816                 }
8817             }
8818           if (attribute_flag[23] != 0)
8819             image->interpolate=(PixelInterpolateMethod)
8820               argument_list[23].integer_reference;
8821           if ((attribute_flag[24] != 0) &&
8822               (draw_info->fill_pattern != (Image *) NULL))
8823             flags=ParsePageGeometry(draw_info->fill_pattern,
8824               argument_list[24].string_reference,
8825               &draw_info->fill_pattern->tile_offset,exception);
8826           if (attribute_flag[25] != 0)
8827             {
8828               (void) ConcatenateString(&draw_info->primitive," '");
8829               (void) ConcatenateString(&draw_info->primitive,
8830                 argument_list[25].string_reference);
8831               (void) ConcatenateString(&draw_info->primitive,"'");
8832             }
8833           if (attribute_flag[26] != 0)
8834             draw_info->fill_pattern=CloneImage(
8835               argument_list[26].image_reference,0,0,MagickTrue,exception);
8836           if (attribute_flag[27] != 0)
8837             draw_info->stroke_pattern=CloneImage(
8838               argument_list[27].image_reference,0,0,MagickTrue,exception);
8839           if (attribute_flag[28] != 0)
8840             (void) CloneString(&draw_info->primitive,
8841               argument_list[28].string_reference);
8842           if (attribute_flag[29] != 0)
8843             draw_info->kerning=argument_list[29].real_reference;
8844           if (attribute_flag[30] != 0)
8845             draw_info->interline_spacing=argument_list[30].real_reference;
8846           if (attribute_flag[31] != 0)
8847             draw_info->interword_spacing=argument_list[31].real_reference;
8848           if (attribute_flag[32] != 0)
8849             draw_info->direction=(DirectionType)
8850               argument_list[32].integer_reference;
8851           DrawImage(image,draw_info,exception);
8852           draw_info=DestroyDrawInfo(draw_info);
8853           break;
8854         }
8855         case 39:  /* Equalize */
8856         {
8857           if (attribute_flag[0] != 0)
8858             channel=(ChannelType) argument_list[0].integer_reference;
8859           channel_mask=SetImageChannelMask(image,channel);
8860           EqualizeImage(image,exception);
8861           (void) SetImageChannelMask(image,channel_mask);
8862           break;
8863         }
8864         case 40:  /* Gamma */
8865         {
8866           if (attribute_flag[1] != 0)
8867             channel=(ChannelType) argument_list[1].integer_reference;
8868           if (attribute_flag[2] == 0)
8869             argument_list[2].real_reference=1.0;
8870           if (attribute_flag[3] == 0)
8871             argument_list[3].real_reference=1.0;
8872           if (attribute_flag[4] == 0)
8873             argument_list[4].real_reference=1.0;
8874           if (attribute_flag[0] == 0)
8875             {
8876               (void) FormatLocaleString(message,MaxTextExtent,
8877                 "%.15g,%.15g,%.15g",(double) argument_list[2].real_reference,
8878                 (double) argument_list[3].real_reference,
8879                 (double) argument_list[4].real_reference);
8880               argument_list[0].string_reference=message;
8881             }
8882           (void) GammaImage(image,StringToDouble(
8883             argument_list[0].string_reference,(char **) NULL),exception);
8884           break;
8885         }
8886         case 41:  /* Map */
8887         {
8888           QuantizeInfo
8889             *quantize_info;
8890
8891           if (attribute_flag[0] == 0)
8892             {
8893               ThrowPerlException(exception,OptionError,"MapImageRequired",
8894                 PackageName);
8895               goto PerlException;
8896             }
8897           quantize_info=AcquireQuantizeInfo(info->image_info);
8898           if (attribute_flag[1] != 0)
8899             quantize_info->dither_method=(DitherMethod)
8900               argument_list[1].integer_reference;
8901           (void) RemapImages(quantize_info,image,
8902             argument_list[0].image_reference,exception);
8903           quantize_info=DestroyQuantizeInfo(quantize_info);
8904           break;
8905         }
8906         case 42:  /* MatteFloodfill */
8907         {
8908           DrawInfo
8909             *draw_info;
8910
8911           MagickBooleanType
8912             invert;
8913
8914           PixelInfo
8915             target;
8916
8917           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8918             (DrawInfo *) NULL);
8919           if (attribute_flag[0] != 0)
8920             flags=ParsePageGeometry(image,argument_list[0].string_reference,
8921               &geometry,exception);
8922           if (attribute_flag[1] != 0)
8923             geometry.x=argument_list[1].integer_reference;
8924           if (attribute_flag[2] != 0)
8925             geometry.y=argument_list[2].integer_reference;
8926           if (image->alpha_trait != BlendPixelTrait)
8927             (void) SetImageAlpha(image,OpaqueAlpha,exception);
8928           (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8929             geometry.x,geometry.y,&target,exception);
8930           if (attribute_flag[4] != 0)
8931             QueryColorCompliance(argument_list[4].string_reference,
8932               AllCompliance,&target,exception);
8933           if (attribute_flag[3] != 0)
8934             target.alpha=StringToDoubleInterval(
8935               argument_list[3].string_reference,(double) (double) QuantumRange+
8936               1.0);
8937           if (attribute_flag[5] != 0)
8938             image->fuzz=StringToDoubleInterval(
8939               argument_list[5].string_reference,(double) QuantumRange+1.0);
8940           invert=MagickFalse;
8941           if (attribute_flag[6] != 0)
8942             invert=(MagickBooleanType) argument_list[6].integer_reference;
8943           channel_mask=SetImageChannelMask(image,AlphaChannel);
8944           (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8945             geometry.y,invert,exception);
8946           (void) SetImageChannelMask(image,channel_mask);
8947           draw_info=DestroyDrawInfo(draw_info);
8948           break;
8949         }
8950         case 43:  /* Modulate */
8951         {
8952           char
8953             modulate[MaxTextExtent];
8954
8955           geometry_info.rho=100.0;
8956           geometry_info.sigma=100.0;
8957           geometry_info.xi=100.0;
8958           if (attribute_flag[0] != 0)
8959             (void)ParseGeometry(argument_list[0].string_reference,
8960               &geometry_info);
8961           if (attribute_flag[1] != 0)
8962             geometry_info.xi=argument_list[1].real_reference;
8963           if (attribute_flag[2] != 0)
8964             geometry_info.sigma=argument_list[2].real_reference;
8965           if (attribute_flag[3] != 0)
8966             {
8967               geometry_info.sigma=argument_list[3].real_reference;
8968               SetImageArtifact(image,"modulate:colorspace","HWB");
8969             }
8970           if (attribute_flag[4] != 0)
8971             {
8972               geometry_info.rho=argument_list[4].real_reference;
8973               SetImageArtifact(image,"modulate:colorspace","HSB");
8974             }
8975           if (attribute_flag[5] != 0)
8976             {
8977               geometry_info.sigma=argument_list[5].real_reference;
8978               SetImageArtifact(image,"modulate:colorspace","HSL");
8979             }
8980           if (attribute_flag[6] != 0)
8981             {
8982               geometry_info.rho=argument_list[6].real_reference;
8983               SetImageArtifact(image,"modulate:colorspace","HWB");
8984             }
8985           (void) FormatLocaleString(modulate,MaxTextExtent,"%.15g,%.15g,%.15g",
8986             geometry_info.rho,geometry_info.sigma,geometry_info.xi);
8987           (void) ModulateImage(image,modulate,exception);
8988           break;
8989         }
8990         case 44:  /* Negate */
8991         {
8992           if (attribute_flag[0] == 0)
8993             argument_list[0].integer_reference=0;
8994           if (attribute_flag[1] != 0)
8995             channel=(ChannelType) argument_list[1].integer_reference;
8996           channel_mask=SetImageChannelMask(image,channel);
8997           (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
8998             MagickTrue : MagickFalse,exception);
8999           (void) SetImageChannelMask(image,channel_mask);
9000           break;
9001         }
9002         case 45:  /* Normalize */
9003         {
9004           if (attribute_flag[0] != 0)
9005             channel=(ChannelType) argument_list[0].integer_reference;
9006           channel_mask=SetImageChannelMask(image,channel);
9007           NormalizeImage(image,exception);
9008           (void) SetImageChannelMask(image,channel_mask);
9009           break;
9010         }
9011         case 46:  /* NumberColors */
9012           break;
9013         case 47:  /* Opaque */
9014         {
9015           MagickBooleanType
9016             invert;
9017
9018           PixelInfo
9019             fill_color,
9020             target;
9021
9022           (void) QueryColorCompliance("none",AllCompliance,&target,
9023              exception);
9024           (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9025             exception);
9026           if (attribute_flag[0] != 0)
9027             (void) QueryColorCompliance(argument_list[0].string_reference,
9028               AllCompliance,&target,exception);
9029           if (attribute_flag[1] != 0)
9030             (void) QueryColorCompliance(argument_list[1].string_reference,
9031               AllCompliance,&fill_color,exception);
9032           if (attribute_flag[2] != 0)
9033             image->fuzz=StringToDoubleInterval(
9034               argument_list[2].string_reference,(double) QuantumRange+1.0);
9035           if (attribute_flag[3] != 0)
9036             channel=(ChannelType) argument_list[3].integer_reference;
9037           invert=MagickFalse;
9038           if (attribute_flag[4] != 0)
9039             invert=(MagickBooleanType) argument_list[4].integer_reference;
9040           channel_mask=SetImageChannelMask(image,channel);
9041           (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9042           (void) SetImageChannelMask(image,channel_mask);
9043           break;
9044         }
9045         case 48:  /* Quantize */
9046         {
9047           QuantizeInfo
9048             *quantize_info;
9049
9050           quantize_info=AcquireQuantizeInfo(info->image_info);
9051           if (attribute_flag[0] != 0)
9052             quantize_info->number_colors=(size_t)
9053               argument_list[0].integer_reference;
9054           if (attribute_flag[1] != 0)
9055             quantize_info->tree_depth=(size_t)
9056               argument_list[1].integer_reference;
9057           if (attribute_flag[2] != 0)
9058             quantize_info->colorspace=(ColorspaceType)
9059               argument_list[2].integer_reference;
9060           if (attribute_flag[3] != 0)
9061             quantize_info->dither_method=(DitherMethod)
9062               argument_list[3].integer_reference;
9063           if (attribute_flag[4] != 0)
9064             quantize_info->measure_error=argument_list[4].integer_reference !=
9065               0 ? MagickTrue : MagickFalse;
9066           if (attribute_flag[5] != 0)
9067             (void) QueryColorCompliance(argument_list[5].string_reference,
9068               AllCompliance,&image->transparent_color,exception);
9069           if (attribute_flag[5] && argument_list[5].integer_reference)
9070             {
9071               (void) QuantizeImages(quantize_info,image,exception);
9072               goto PerlException;
9073             }
9074           if (attribute_flag[6] != 0)
9075             quantize_info->dither_method=(DitherMethod)
9076               argument_list[6].integer_reference;
9077           if ((image->storage_class == DirectClass) ||
9078               (image->colors > quantize_info->number_colors) ||
9079               (quantize_info->colorspace == GRAYColorspace))
9080             (void) QuantizeImage(quantize_info,image,exception);
9081           else
9082             CompressImageColormap(image,exception);
9083           quantize_info=DestroyQuantizeInfo(quantize_info);
9084           break;
9085         }
9086         case 49:  /* Raise */
9087         {
9088           if (attribute_flag[0] != 0)
9089             flags=ParsePageGeometry(image,argument_list[0].string_reference,
9090               &geometry,exception);
9091           if (attribute_flag[1] != 0)
9092             geometry.width=argument_list[1].integer_reference;
9093           if (attribute_flag[2] != 0)
9094             geometry.height=argument_list[2].integer_reference;
9095           if (attribute_flag[3] == 0)
9096             argument_list[3].integer_reference=1;
9097           (void) RaiseImage(image,&geometry,
9098             argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9099             exception);
9100           break;
9101         }
9102         case 50:  /* Segment */
9103         {
9104           ColorspaceType
9105             colorspace;
9106
9107           double
9108             cluster_threshold,
9109             smoothing_threshold;
9110
9111           MagickBooleanType
9112             verbose;
9113
9114           cluster_threshold=1.0;
9115           smoothing_threshold=1.5;
9116           colorspace=sRGBColorspace;
9117           verbose=MagickFalse;
9118           if (attribute_flag[0] != 0)
9119             {
9120               flags=ParseGeometry(argument_list[0].string_reference,
9121                 &geometry_info);
9122               cluster_threshold=geometry_info.rho;
9123               if (flags & SigmaValue)
9124                 smoothing_threshold=geometry_info.sigma;
9125             }
9126           if (attribute_flag[1] != 0)
9127             cluster_threshold=argument_list[1].real_reference;
9128           if (attribute_flag[2] != 0)
9129             smoothing_threshold=argument_list[2].real_reference;
9130           if (attribute_flag[3] != 0)
9131             colorspace=(ColorspaceType) argument_list[3].integer_reference;
9132           if (attribute_flag[4] != 0)
9133             verbose=argument_list[4].integer_reference != 0 ?
9134               MagickTrue : MagickFalse;
9135           (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9136             smoothing_threshold,exception);
9137           break;
9138         }
9139         case 51:  /* Signature */
9140         {
9141           (void) SignatureImage(image,exception);
9142           break;
9143         }
9144         case 52:  /* Solarize */
9145         {
9146           geometry_info.rho=QuantumRange/2.0;
9147           if (attribute_flag[0] != 0)
9148             flags=ParseGeometry(argument_list[0].string_reference,
9149               &geometry_info);
9150           if (attribute_flag[1] != 0)
9151             geometry_info.rho=StringToDoubleInterval(
9152               argument_list[1].string_reference,(double) QuantumRange+1.0);
9153           (void) SolarizeImage(image,geometry_info.rho,exception);
9154           break;
9155         }
9156         case 53:  /* Sync */
9157         {
9158           (void) SyncImage(image,exception);
9159           break;
9160         }
9161         case 54:  /* Texture */
9162         {
9163           if (attribute_flag[0] == 0)
9164             break;
9165           TextureImage(image,argument_list[0].image_reference,exception);
9166           break;
9167         }
9168         case 55:  /* Evalute */
9169         {
9170           MagickEvaluateOperator
9171             op;
9172
9173           op=SetEvaluateOperator;
9174           if (attribute_flag[0] == MagickFalse)
9175             argument_list[0].real_reference=0.0;
9176           if (attribute_flag[1] != MagickFalse)
9177             op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9178           if (attribute_flag[2] != MagickFalse)
9179             channel=(ChannelType) argument_list[2].integer_reference;
9180           channel_mask=SetImageChannelMask(image,channel);
9181           (void) EvaluateImage(image,op,argument_list[0].real_reference,
9182             exception);
9183           (void) SetImageChannelMask(image,channel_mask);
9184           break;
9185         }
9186         case 56:  /* Transparent */
9187         {
9188           double
9189             opacity;
9190
9191           MagickBooleanType
9192             invert;
9193
9194           PixelInfo
9195             target;
9196
9197           (void) QueryColorCompliance("none",AllCompliance,&target,
9198             exception);
9199           if (attribute_flag[0] != 0)
9200             (void) QueryColorCompliance(argument_list[0].string_reference,
9201               AllCompliance,&target,exception);
9202           opacity=TransparentAlpha;
9203           if (attribute_flag[1] != 0)
9204             opacity=StringToDoubleInterval(argument_list[1].string_reference,
9205               (double) QuantumRange+1.0);
9206           if (attribute_flag[2] != 0)
9207             image->fuzz=StringToDoubleInterval(
9208               argument_list[2].string_reference,(double) QuantumRange+1.0);
9209           if (attribute_flag[3] == 0)
9210             argument_list[3].integer_reference=0;
9211           invert=MagickFalse;
9212           if (attribute_flag[3] != 0)
9213             invert=(MagickBooleanType) argument_list[3].integer_reference;
9214           (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9215             invert,exception);
9216           break;
9217         }
9218         case 57:  /* Threshold */
9219         {
9220           double
9221             threshold;
9222
9223           if (attribute_flag[0] == 0)
9224             argument_list[0].string_reference="50%";
9225           if (attribute_flag[1] != 0)
9226             channel=(ChannelType) argument_list[1].integer_reference;
9227           threshold=StringToDoubleInterval(argument_list[0].string_reference,
9228             (double) QuantumRange+1.0);
9229           channel_mask=SetImageChannelMask(image,channel);
9230           (void) BilevelImage(image,threshold,exception);
9231           (void) SetImageChannelMask(image,channel_mask);
9232           break;
9233         }
9234         case 58:  /* Charcoal */
9235         {
9236           if (attribute_flag[0] != 0)
9237             {
9238               flags=ParseGeometry(argument_list[0].string_reference,
9239                 &geometry_info);
9240               if ((flags & SigmaValue) == 0)
9241                 geometry_info.sigma=1.0;
9242             }
9243           if (attribute_flag[1] != 0)
9244             geometry_info.rho=argument_list[1].real_reference;
9245           if (attribute_flag[2] != 0)
9246             geometry_info.sigma=argument_list[2].real_reference;
9247           image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9248             exception);
9249           break;
9250         }
9251         case 59:  /* Trim */
9252         {
9253           if (attribute_flag[0] != 0)
9254             image->fuzz=StringToDoubleInterval(
9255               argument_list[0].string_reference,(double) QuantumRange+1.0);
9256           image=TrimImage(image,exception);
9257           break;
9258         }
9259         case 60:  /* Wave */
9260         {
9261           PixelInterpolateMethod
9262             method;
9263
9264           if (attribute_flag[0] != 0)
9265             {
9266               flags=ParseGeometry(argument_list[0].string_reference,
9267                 &geometry_info);
9268               if ((flags & SigmaValue) == 0)
9269                 geometry_info.sigma=1.0;
9270             }
9271           if (attribute_flag[1] != 0)
9272             geometry_info.rho=argument_list[1].real_reference;
9273           if (attribute_flag[2] != 0)
9274             geometry_info.sigma=argument_list[2].real_reference;
9275           method=UndefinedInterpolatePixel;
9276           if (attribute_flag[3] != 0)
9277             method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9278           image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9279             method,exception);
9280           break;
9281         }
9282         case 61:  /* Separate */
9283         {
9284           if (attribute_flag[0] != 0)
9285             channel=(ChannelType) argument_list[0].integer_reference;
9286           image=SeparateImage(image,channel,exception);
9287           break;
9288         }
9289         case 63:  /* Stereo */
9290         {
9291           if (attribute_flag[0] == 0)
9292             {
9293               ThrowPerlException(exception,OptionError,"StereoImageRequired",
9294                 PackageName);
9295               goto PerlException;
9296             }
9297           if (attribute_flag[1] != 0)
9298             geometry.x=argument_list[1].integer_reference;
9299           if (attribute_flag[2] != 0)
9300             geometry.y=argument_list[2].integer_reference;
9301           image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9302             geometry.x,geometry.y,exception);
9303           break;
9304         }
9305         case 64:  /* Stegano */
9306         {
9307           if (attribute_flag[0] == 0)
9308             {
9309               ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9310                 PackageName);
9311               goto PerlException;
9312             }
9313           if (attribute_flag[1] == 0)
9314             argument_list[1].integer_reference=0;
9315           image->offset=argument_list[1].integer_reference;
9316           image=SteganoImage(image,argument_list[0].image_reference,exception);
9317           break;
9318         }
9319         case 65:  /* Deconstruct */
9320         {
9321           image=CompareImagesLayers(image,CompareAnyLayer,exception);
9322           break;
9323         }
9324         case 66:  /* GaussianBlur */
9325         {
9326           if (attribute_flag[0] != 0)
9327             {
9328               flags=ParseGeometry(argument_list[0].string_reference,
9329                 &geometry_info);
9330               if ((flags & SigmaValue) == 0)
9331                 geometry_info.sigma=1.0;
9332             }
9333           if (attribute_flag[1] != 0)
9334             geometry_info.rho=argument_list[1].real_reference;
9335           if (attribute_flag[2] != 0)
9336             geometry_info.sigma=argument_list[2].real_reference;
9337           if (attribute_flag[3] != 0)
9338             channel=(ChannelType) argument_list[3].integer_reference;
9339           channel_mask=SetImageChannelMask(image,channel);
9340           image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9341             exception);
9342           if (image != (Image *) NULL)
9343             (void) SetImageChannelMask(image,channel_mask);
9344           break;
9345         }
9346         case 67:  /* Convolve */
9347         {
9348           KernelInfo
9349             *kernel;
9350
9351           kernel=(KernelInfo *) NULL;
9352           if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9353             break;
9354           if (attribute_flag[0] != 0)
9355             {
9356               AV
9357                 *av;
9358
9359               size_t
9360                 order;
9361
9362               kernel=AcquireKernelInfo((const char *) NULL);
9363               if (kernel == (KernelInfo *) NULL)
9364                 break;
9365               av=(AV *) argument_list[0].array_reference;
9366               order=(size_t) sqrt(av_len(av)+1);
9367               kernel->width=order;
9368               kernel->height=order;
9369               kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9370                 order*sizeof(*kernel->values));
9371               if (kernel->values == (MagickRealType *) NULL)
9372                 {
9373                   kernel=DestroyKernelInfo(kernel);
9374                   ThrowPerlException(exception,ResourceLimitFatalError,
9375                     "MemoryAllocationFailed",PackageName);
9376                   goto PerlException;
9377                 }
9378               for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9379                 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9380               for ( ; j < (ssize_t) (order*order); j++)
9381                 kernel->values[j]=0.0;
9382             }
9383           if (attribute_flag[1] != 0)
9384             channel=(ChannelType) argument_list[1].integer_reference;
9385           if (attribute_flag[2] != 0)
9386             SetImageArtifact(image,"filter:blur",
9387               argument_list[2].string_reference);
9388           if (attribute_flag[3] != 0)
9389             {
9390               kernel=AcquireKernelInfo(argument_list[3].string_reference);
9391               if (kernel == (KernelInfo *) NULL)
9392                 break;
9393             }
9394           channel_mask=SetImageChannelMask(image,channel);
9395           image=ConvolveImage(image,kernel,exception);
9396           if (image != (Image *) NULL)
9397             (void) SetImageChannelMask(image,channel_mask);
9398           kernel=DestroyKernelInfo(kernel);
9399           break;
9400         }
9401         case 68:  /* Profile */
9402         {
9403           const char
9404             *name;
9405
9406           Image
9407             *profile_image;
9408
9409           ImageInfo
9410             *profile_info;
9411
9412           StringInfo
9413             *profile;
9414
9415           name="*";
9416           if (attribute_flag[0] != 0)
9417             name=argument_list[0].string_reference;
9418           if (attribute_flag[2] != 0)
9419             image->rendering_intent=(RenderingIntent)
9420               argument_list[2].integer_reference;
9421           if (attribute_flag[3] != 0)
9422             image->black_point_compensation=
9423               argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9424           if (attribute_flag[1] != 0)
9425             {
9426               if (argument_list[1].length == 0)
9427                 {
9428                   /*
9429                     Remove a profile from the image.
9430                   */
9431                   (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9432                     exception);
9433                   break;
9434                 }
9435               /*
9436                 Associate user supplied profile with the image.
9437               */
9438               profile=AcquireStringInfo(argument_list[1].length);
9439               SetStringInfoDatum(profile,(const unsigned char *)
9440                 argument_list[1].string_reference);
9441               (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9442                 (size_t) GetStringInfoLength(profile),exception);
9443               profile=DestroyStringInfo(profile);
9444               break;
9445             }
9446           /*
9447             Associate a profile with the image.
9448           */
9449           profile_info=CloneImageInfo(info ? info->image_info :
9450             (ImageInfo *) NULL);
9451           profile_image=ReadImages(profile_info,name,exception);
9452           if (profile_image == (Image *) NULL)
9453             break;
9454           ResetImageProfileIterator(profile_image);
9455           name=GetNextImageProfile(profile_image);
9456           while (name != (const char *) NULL)
9457           {
9458             const StringInfo
9459               *profile;
9460
9461             profile=GetImageProfile(profile_image,name);
9462             if (profile != (const StringInfo *) NULL)
9463               (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9464                 (size_t) GetStringInfoLength(profile),exception);
9465             name=GetNextImageProfile(profile_image);
9466           }
9467           profile_image=DestroyImage(profile_image);
9468           profile_info=DestroyImageInfo(profile_info);
9469           break;
9470         }
9471         case 69:  /* UnsharpMask */
9472         {
9473           if (attribute_flag[0] != 0)
9474             {
9475               flags=ParseGeometry(argument_list[0].string_reference,
9476                 &geometry_info);
9477               if ((flags & SigmaValue) == 0)
9478                 geometry_info.sigma=1.0;
9479               if ((flags & XiValue) == 0)
9480                 geometry_info.xi=1.0;
9481               if ((flags & PsiValue) == 0)
9482                 geometry_info.psi=0.5;
9483             }
9484           if (attribute_flag[1] != 0)
9485             geometry_info.rho=argument_list[1].real_reference;
9486           if (attribute_flag[2] != 0)
9487             geometry_info.sigma=argument_list[2].real_reference;
9488           if (attribute_flag[3] != 0)
9489             geometry_info.xi=argument_list[3].real_reference;
9490           if (attribute_flag[4] != 0)
9491             geometry_info.psi=argument_list[4].real_reference;
9492           if (attribute_flag[5] != 0)
9493             channel=(ChannelType) argument_list[5].integer_reference;
9494           channel_mask=SetImageChannelMask(image,channel);
9495           image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9496             geometry_info.xi,geometry_info.psi,exception);
9497           if (image != (Image *) NULL)
9498             (void) SetImageChannelMask(image,channel_mask);
9499           break;
9500         }
9501         case 70:  /* MotionBlur */
9502         {
9503           if (attribute_flag[0] != 0)
9504             {
9505               flags=ParseGeometry(argument_list[0].string_reference,
9506                 &geometry_info);
9507               if ((flags & SigmaValue) == 0)
9508                 geometry_info.sigma=1.0;
9509               if ((flags & XiValue) == 0)
9510                 geometry_info.xi=1.0;
9511             }
9512           if (attribute_flag[1] != 0)
9513             geometry_info.rho=argument_list[1].real_reference;
9514           if (attribute_flag[2] != 0)
9515             geometry_info.sigma=argument_list[2].real_reference;
9516           if (attribute_flag[3] != 0)
9517             geometry_info.xi=argument_list[3].real_reference;
9518           if (attribute_flag[4] != 0)
9519             channel=(ChannelType) argument_list[4].integer_reference;
9520           channel_mask=SetImageChannelMask(image,channel);
9521           image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9522             geometry_info.xi,exception);
9523           if (image != (Image *) NULL)
9524             (void) SetImageChannelMask(image,channel_mask);
9525           break;
9526         }
9527         case 71:  /* OrderedDither */
9528         {
9529           if (attribute_flag[0] == 0)
9530             argument_list[0].string_reference="o8x8";
9531           if (attribute_flag[1] != 0)
9532             channel=(ChannelType) argument_list[1].integer_reference;
9533           channel_mask=SetImageChannelMask(image,channel);
9534           (void) OrderedPosterizeImage(image,argument_list[0].string_reference,
9535             exception);
9536           (void) SetImageChannelMask(image,channel_mask);
9537           break;
9538         }
9539         case 72:  /* Shave */
9540         {
9541           if (attribute_flag[0] != 0)
9542             flags=ParsePageGeometry(image,argument_list[0].string_reference,
9543               &geometry,exception);
9544           if (attribute_flag[1] != 0)
9545             geometry.width=argument_list[1].integer_reference;
9546           if (attribute_flag[2] != 0)
9547             geometry.height=argument_list[2].integer_reference;
9548           image=ShaveImage(image,&geometry,exception);
9549           break;
9550         }
9551         case 73:  /* Level */
9552         {
9553           double
9554             black_point,
9555             gamma,
9556             white_point;
9557
9558           black_point=0.0;
9559           white_point=(double) image->columns*image->rows;
9560           gamma=1.0;
9561           if (attribute_flag[0] != 0)
9562             {
9563               flags=ParseGeometry(argument_list[0].string_reference,
9564                 &geometry_info);
9565               black_point=geometry_info.rho;
9566               if ((flags & SigmaValue) != 0)
9567                 white_point=geometry_info.sigma;
9568               if ((flags & XiValue) != 0)
9569                 gamma=geometry_info.xi;
9570               if ((flags & PercentValue) != 0)
9571                 {
9572                   black_point*=(double) (QuantumRange/100.0);
9573                   white_point*=(double) (QuantumRange/100.0);
9574                 }
9575               if ((flags & SigmaValue) == 0)
9576                 white_point=(double) QuantumRange-black_point;
9577             }
9578           if (attribute_flag[1] != 0)
9579             black_point=argument_list[1].real_reference;
9580           if (attribute_flag[2] != 0)
9581             white_point=argument_list[2].real_reference;
9582           if (attribute_flag[3] != 0)
9583             gamma=argument_list[3].real_reference;
9584           if (attribute_flag[4] != 0)
9585             channel=(ChannelType) argument_list[4].integer_reference;
9586           if (attribute_flag[5] != 0)
9587             {
9588               argument_list[0].real_reference=argument_list[5].real_reference;
9589               attribute_flag[0]=attribute_flag[5];
9590             }
9591           channel_mask=SetImageChannelMask(image,channel);
9592           (void) LevelImage(image,black_point,white_point,gamma,exception);
9593           (void) SetImageChannelMask(image,channel_mask);
9594           break;
9595         }
9596         case 74:  /* Clip */
9597         {
9598           if (attribute_flag[0] == 0)
9599             argument_list[0].string_reference="#1";
9600           if (attribute_flag[1] == 0)
9601             argument_list[1].integer_reference=MagickTrue;
9602           (void) ClipImagePath(image,argument_list[0].string_reference,
9603             argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9604             exception);
9605           break;
9606         }
9607         case 75:  /* AffineTransform */
9608         {
9609           DrawInfo
9610             *draw_info;
9611
9612           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9613             (DrawInfo *) NULL);
9614           if (attribute_flag[0] != 0)
9615             {
9616               AV
9617                 *av;
9618
9619               av=(AV *) argument_list[0].array_reference;
9620               if ((av_len(av) != 3) && (av_len(av) != 5))
9621                 {
9622                   ThrowPerlException(exception,OptionError,
9623                     "affine matrix must have 4 or 6 elements",PackageName);
9624                   goto PerlException;
9625                 }
9626               draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9627               draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9628               draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9629               draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9630               if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9631                   draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9632                 {
9633                   ThrowPerlException(exception,OptionError,
9634                     "affine matrix is singular",PackageName);
9635                    goto PerlException;
9636                 }
9637               if (av_len(av) == 5)
9638                 {
9639                   draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9640                   draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9641                 }
9642             }
9643           for (j=1; j < 6; j++)
9644           {
9645             if (attribute_flag[j] == 0)
9646               continue;
9647             value=argument_list[j].string_reference;
9648             angle=argument_list[j].real_reference;
9649             current=draw_info->affine;
9650             GetAffineMatrix(&affine);
9651             switch (j)
9652             {
9653               case 1:
9654               {
9655                 /*
9656                   Translate.
9657                 */
9658                 flags=ParseGeometry(value,&geometry_info);
9659                 affine.tx=geometry_info.xi;
9660                 affine.ty=geometry_info.psi;
9661                 if ((flags & PsiValue) == 0)
9662                   affine.ty=affine.tx;
9663                 break;
9664               }
9665               case 2:
9666               {
9667                 /*
9668                   Scale.
9669                 */
9670                 flags=ParseGeometry(value,&geometry_info);
9671                 affine.sx=geometry_info.rho;
9672                 affine.sy=geometry_info.sigma;
9673                 if ((flags & SigmaValue) == 0)
9674                   affine.sy=affine.sx;
9675                 break;
9676               }
9677               case 3:
9678               {
9679                 /*
9680                   Rotate.
9681                 */
9682                 if (angle == 0.0)
9683                   break;
9684                 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9685                 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9686                 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9687                 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9688                 break;
9689               }
9690               case 4:
9691               {
9692                 /*
9693                   SkewX.
9694                 */
9695                 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9696                 break;
9697               }
9698               case 5:
9699               {
9700                 /*
9701                   SkewY.
9702                 */
9703                 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9704                 break;
9705               }
9706             }
9707             draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9708             draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9709             draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9710             draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9711             draw_info->affine.tx=
9712               current.sx*affine.tx+current.ry*affine.ty+current.tx;
9713             draw_info->affine.ty=
9714               current.rx*affine.tx+current.sy*affine.ty+current.ty;
9715           }
9716           if (attribute_flag[6] != 0)
9717             image->interpolate=(PixelInterpolateMethod)
9718               argument_list[6].integer_reference;
9719           if (attribute_flag[7] != 0)
9720             QueryColorCompliance(argument_list[7].string_reference,
9721               AllCompliance,&image->background_color,exception);
9722           image=AffineTransformImage(image,&draw_info->affine,exception);
9723           draw_info=DestroyDrawInfo(draw_info);
9724           break;
9725         }
9726         case 76:  /* Difference */
9727         {
9728           if (attribute_flag[0] == 0)
9729             {
9730               ThrowPerlException(exception,OptionError,
9731                 "ReferenceImageRequired",PackageName);
9732               goto PerlException;
9733             }
9734           if (attribute_flag[1] != 0)
9735             image->fuzz=StringToDoubleInterval(
9736               argument_list[1].string_reference,(double) QuantumRange+1.0);
9737           (void) IsImagesEqual(image,argument_list[0].image_reference,
9738             exception);
9739           break;
9740         }
9741         case 77:  /* AdaptiveThreshold */
9742         {
9743           if (attribute_flag[0] != 0)
9744             {
9745               flags=ParseGeometry(argument_list[0].string_reference,
9746                 &geometry_info);
9747               if ((flags & PercentValue) != 0)
9748                 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9749             }
9750           if (attribute_flag[1] != 0)
9751             geometry_info.rho=argument_list[1].integer_reference;
9752           if (attribute_flag[2] != 0)
9753             geometry_info.sigma=argument_list[2].integer_reference;
9754           if (attribute_flag[3] != 0)
9755             geometry_info.xi=argument_list[3].integer_reference;;
9756           image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
9757             (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
9758           break;
9759         }
9760         case 78:  /* Resample */
9761         {
9762           size_t
9763             height,
9764             width;
9765
9766           if (attribute_flag[0] != 0)
9767             {
9768               flags=ParseGeometry(argument_list[0].string_reference,
9769                 &geometry_info);
9770               if ((flags & SigmaValue) == 0)
9771                 geometry_info.sigma=geometry_info.rho;
9772             }
9773           if (attribute_flag[1] != 0)
9774             geometry_info.rho=argument_list[1].real_reference;
9775           if (attribute_flag[2] != 0)
9776             geometry_info.sigma=argument_list[2].real_reference;
9777           if (attribute_flag[3] == 0)
9778             argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
9779           if (attribute_flag[4] == 0)
9780             SetImageArtifact(image,"filter:support",
9781               argument_list[4].string_reference);
9782           width=(size_t) (geometry_info.rho*image->columns/
9783             (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
9784           height=(size_t) (geometry_info.sigma*image->rows/
9785             (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
9786           image=ResizeImage(image,width,height,(FilterTypes)
9787             argument_list[3].integer_reference,exception);
9788           if (image != (Image *) NULL)
9789             {
9790               image->resolution.x=geometry_info.rho;
9791               image->resolution.y=geometry_info.sigma;
9792             }
9793           break;
9794         }
9795         case 79:  /* Describe */
9796         {
9797           if (attribute_flag[0] == 0)
9798             argument_list[0].file_reference=(FILE *) NULL;
9799           if (attribute_flag[1] != 0)
9800             (void) SetImageArtifact(image,"identify:features",
9801               argument_list[1].string_reference);
9802           (void) IdentifyImage(image,argument_list[0].file_reference,
9803             MagickTrue,exception);
9804           break;
9805         }
9806         case 80:  /* BlackThreshold */
9807         {
9808           if (attribute_flag[0] == 0)
9809             argument_list[0].string_reference="50%";
9810           if (attribute_flag[2] != 0)
9811             channel=(ChannelType) argument_list[2].integer_reference;
9812           channel_mask=SetImageChannelMask(image,channel);
9813           BlackThresholdImage(image,argument_list[0].string_reference,
9814             exception);
9815           (void) SetImageChannelMask(image,channel_mask);
9816           break;
9817         }
9818         case 81:  /* WhiteThreshold */
9819         {
9820           if (attribute_flag[0] == 0)
9821             argument_list[0].string_reference="50%";
9822           if (attribute_flag[2] != 0)
9823             channel=(ChannelType) argument_list[2].integer_reference;
9824           channel_mask=SetImageChannelMask(image,channel);
9825           WhiteThresholdImage(image,argument_list[0].string_reference,
9826             exception);
9827           (void) SetImageChannelMask(image,channel_mask);
9828           break;
9829         }
9830         case 82:  /* RadialBlur */
9831         {
9832           if (attribute_flag[0] != 0)
9833             {
9834               flags=ParseGeometry(argument_list[0].string_reference,
9835                 &geometry_info);
9836             }
9837           if (attribute_flag[1] != 0)
9838             geometry_info.rho=argument_list[1].real_reference;
9839           if (attribute_flag[2] != 0)
9840             channel=(ChannelType) argument_list[2].integer_reference;
9841           channel_mask=SetImageChannelMask(image,channel);
9842           image=RadialBlurImage(image,geometry_info.rho,exception);
9843           if (image != (Image *) NULL)
9844             (void) SetImageChannelMask(image,channel_mask);
9845           break;
9846         }
9847         case 83:  /* Thumbnail */
9848         {
9849           if (attribute_flag[0] != 0)
9850             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
9851               &geometry,exception);
9852           if (attribute_flag[1] != 0)
9853             geometry.width=argument_list[1].integer_reference;
9854           if (attribute_flag[2] != 0)
9855             geometry.height=argument_list[2].integer_reference;
9856           image=ThumbnailImage(image,geometry.width,geometry.height,exception);
9857           break;
9858         }
9859         case 84:  /* Strip */
9860         {
9861           (void) StripImage(image,exception);
9862           break;
9863         }
9864         case 85:  /* Tint */
9865         {
9866           PixelInfo
9867             tint;
9868
9869           GetPixelInfo(image,&tint);
9870           if (attribute_flag[0] != 0)
9871             (void) QueryColorCompliance(argument_list[0].string_reference,
9872               AllCompliance,&tint,exception);
9873           if (attribute_flag[1] == 0)
9874             argument_list[1].string_reference="100";
9875           image=TintImage(image,argument_list[1].string_reference,&tint,
9876             exception);
9877           break;
9878         }
9879         case 86:  /* Channel */
9880         {
9881           if (attribute_flag[0] != 0)
9882             channel=(ChannelType) argument_list[0].integer_reference;
9883           image=SeparateImage(image,channel,exception);
9884           break;
9885         }
9886         case 87:  /* Splice */
9887         {
9888           if (attribute_flag[0] != 0)
9889             flags=ParseGravityGeometry(image,argument_list[0].string_reference,
9890               &geometry,exception);
9891           if (attribute_flag[1] != 0)
9892             geometry.width=argument_list[1].integer_reference;
9893           if (attribute_flag[2] != 0)
9894             geometry.height=argument_list[2].integer_reference;
9895           if (attribute_flag[3] != 0)
9896             geometry.x=argument_list[3].integer_reference;
9897           if (attribute_flag[4] != 0)
9898             geometry.y=argument_list[4].integer_reference;
9899           if (attribute_flag[5] != 0)
9900             image->fuzz=StringToDoubleInterval(
9901               argument_list[5].string_reference,(double) QuantumRange+1.0);
9902           if (attribute_flag[6] != 0)
9903             (void) QueryColorCompliance(argument_list[6].string_reference,
9904               AllCompliance,&image->background_color,exception);
9905           if (attribute_flag[7] != 0)
9906             image->gravity=(GravityType) argument_list[7].integer_reference;
9907           image=SpliceImage(image,&geometry,exception);
9908           break;
9909         }
9910         case 88:  /* Posterize */
9911         {
9912           if (attribute_flag[0] == 0)
9913             argument_list[0].integer_reference=3;
9914           if (attribute_flag[1] == 0)
9915             argument_list[1].integer_reference=0;
9916           (void) PosterizeImage(image,argument_list[0].integer_reference,
9917             argument_list[1].integer_reference ? RiemersmaDitherMethod :
9918             NoDitherMethod,exception);
9919           break;
9920         }
9921         case 89:  /* Shadow */
9922         {
9923           if (attribute_flag[0] != 0)
9924             {
9925               flags=ParseGeometry(argument_list[0].string_reference,
9926                 &geometry_info);
9927               if ((flags & SigmaValue) == 0)
9928                 geometry_info.sigma=1.0;
9929               if ((flags & XiValue) == 0)
9930                 geometry_info.xi=4.0;
9931               if ((flags & PsiValue) == 0)
9932                 geometry_info.psi=4.0;
9933             }
9934           if (attribute_flag[1] != 0)
9935             geometry_info.rho=argument_list[1].real_reference;
9936           if (attribute_flag[2] != 0)
9937             geometry_info.sigma=argument_list[2].real_reference;
9938           if (attribute_flag[3] != 0)
9939             geometry_info.xi=argument_list[3].integer_reference;
9940           if (attribute_flag[4] != 0)
9941             geometry_info.psi=argument_list[4].integer_reference;
9942           image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
9943             (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
9944             ceil(geometry_info.psi-0.5),exception);
9945           break;
9946         }
9947         case 90:  /* Identify */
9948         {
9949           if (attribute_flag[0] == 0)
9950             argument_list[0].file_reference=(FILE *) NULL;
9951           if (attribute_flag[1] != 0)
9952             (void) SetImageArtifact(image,"identify:features",
9953               argument_list[1].string_reference);
9954           if ((attribute_flag[2] != 0) &&
9955               (argument_list[2].integer_reference != 0))
9956             (void) SetImageArtifact(image,"identify:unique","true");
9957           (void) IdentifyImage(image,argument_list[0].file_reference,
9958             MagickTrue,exception);
9959           break;
9960         }
9961         case 91:  /* SepiaTone */
9962         {
9963           if (attribute_flag[0] == 0)
9964             argument_list[0].real_reference=80.0*QuantumRange/100.0;
9965           image=SepiaToneImage(image,argument_list[0].real_reference,
9966             exception);
9967           break;
9968         }
9969         case 92:  /* SigmoidalContrast */
9970         {
9971           MagickBooleanType
9972             sharpen;
9973
9974           if (attribute_flag[0] != 0)
9975             {
9976               flags=ParseGeometry(argument_list[0].string_reference,
9977                 &geometry_info);
9978               if ((flags & SigmaValue) == 0)
9979                 geometry_info.sigma=QuantumRange/2.0;
9980               if ((flags & PercentValue) != 0)
9981                 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
9982             }
9983           if (attribute_flag[1] != 0)
9984             geometry_info.rho=argument_list[1].real_reference;
9985           if (attribute_flag[2] != 0)
9986             geometry_info.sigma=argument_list[2].real_reference;
9987           if (attribute_flag[3] != 0)
9988             channel=(ChannelType) argument_list[3].integer_reference;
9989           sharpen=MagickTrue;
9990           if (attribute_flag[4] != 0)
9991             sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
9992               MagickFalse;
9993           channel_mask=SetImageChannelMask(image,channel);
9994           (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
9995             geometry_info.sigma,exception);
9996           (void) SetImageChannelMask(image,channel_mask);
9997           break;
9998         }
9999         case 93:  /* Extent */
10000         {
10001           if (attribute_flag[7] != 0)
10002             image->gravity=(GravityType) argument_list[7].integer_reference;
10003           if (attribute_flag[0] != 0)
10004             {
10005               int
10006                 flags;
10007
10008               flags=ParseGravityGeometry(image,
10009                 argument_list[0].string_reference,&geometry,exception);
10010               (void) flags;
10011               if (geometry.width == 0)
10012                 geometry.width=image->columns;
10013               if (geometry.height == 0)
10014                 geometry.height=image->rows;
10015             }
10016           if (attribute_flag[1] != 0)
10017             geometry.width=argument_list[1].integer_reference;
10018           if (attribute_flag[2] != 0)
10019             geometry.height=argument_list[2].integer_reference;
10020           if (attribute_flag[3] != 0)
10021             geometry.x=argument_list[3].integer_reference;
10022           if (attribute_flag[4] != 0)
10023             geometry.y=argument_list[4].integer_reference;
10024           if (attribute_flag[5] != 0)
10025             image->fuzz=StringToDoubleInterval(
10026               argument_list[5].string_reference,(double) QuantumRange+1.0);
10027           if (attribute_flag[6] != 0)
10028             (void) QueryColorCompliance(argument_list[6].string_reference,
10029               AllCompliance,&image->background_color,exception);
10030           image=ExtentImage(image,&geometry,exception);
10031           break;
10032         }
10033         case 94:  /* Vignette */
10034         {
10035           if (attribute_flag[0] != 0)
10036             {
10037               flags=ParseGeometry(argument_list[0].string_reference,
10038                 &geometry_info);
10039               if ((flags & SigmaValue) == 0)
10040                 geometry_info.sigma=1.0;
10041               if ((flags & XiValue) == 0)
10042                 geometry_info.xi=0.1*image->columns;
10043               if ((flags & PsiValue) == 0)
10044                 geometry_info.psi=0.1*image->rows;
10045             }
10046           if (attribute_flag[1] != 0)
10047             geometry_info.rho=argument_list[1].real_reference;
10048           if (attribute_flag[2] != 0)
10049             geometry_info.sigma=argument_list[2].real_reference;
10050           if (attribute_flag[3] != 0)
10051             geometry_info.xi=argument_list[3].integer_reference;
10052           if (attribute_flag[4] != 0)
10053             geometry_info.psi=argument_list[4].integer_reference;
10054           if (attribute_flag[5] != 0)
10055             (void) QueryColorCompliance(argument_list[5].string_reference,
10056               AllCompliance,&image->background_color,exception);
10057           image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10058             (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10059             ceil(geometry_info.psi-0.5),exception);
10060           break;
10061         }
10062         case 95:  /* ContrastStretch */
10063         {
10064           double
10065             black_point,
10066             white_point;
10067
10068           black_point=0.0;
10069           white_point=(double) image->columns*image->rows;
10070           if (attribute_flag[0] != 0)
10071             {
10072               flags=ParseGeometry(argument_list[0].string_reference,
10073                 &geometry_info);
10074               black_point=geometry_info.rho;
10075               white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10076                 black_point;
10077               if ((flags & PercentValue) != 0)
10078                 {
10079                   black_point*=(double) image->columns*image->rows/100.0;
10080                   white_point*=(double) image->columns*image->rows/100.0;
10081                 }
10082               white_point=(double) image->columns*image->rows-
10083                 white_point;
10084             }
10085           if (attribute_flag[1] != 0)
10086             black_point=argument_list[1].real_reference;
10087           if (attribute_flag[2] != 0)
10088             white_point=argument_list[2].real_reference;
10089           if (attribute_flag[4] != 0)
10090             channel=(ChannelType) argument_list[4].integer_reference;
10091           channel_mask=SetImageChannelMask(image,channel);
10092           (void) ContrastStretchImage(image,black_point,white_point,exception);
10093           (void) SetImageChannelMask(image,channel_mask);
10094           break;
10095         }
10096         case 96:  /* Sans0 */
10097         {
10098           break;
10099         }
10100         case 97:  /* Sans1 */
10101         {
10102           break;
10103         }
10104         case 98:  /* AdaptiveSharpen */
10105         {
10106           if (attribute_flag[0] != 0)
10107             {
10108               flags=ParseGeometry(argument_list[0].string_reference,
10109                 &geometry_info);
10110               if ((flags & SigmaValue) == 0)
10111                 geometry_info.sigma=1.0;
10112               if ((flags & XiValue) == 0)
10113                 geometry_info.xi=0.0;
10114             }
10115           if (attribute_flag[1] != 0)
10116             geometry_info.rho=argument_list[1].real_reference;
10117           if (attribute_flag[2] != 0)
10118             geometry_info.sigma=argument_list[2].real_reference;
10119           if (attribute_flag[3] != 0)
10120             geometry_info.xi=argument_list[3].real_reference;
10121           if (attribute_flag[4] != 0)
10122             channel=(ChannelType) argument_list[4].integer_reference;
10123           channel_mask=SetImageChannelMask(image,channel);
10124           image=AdaptiveSharpenImage(image,geometry_info.rho,
10125             geometry_info.sigma,exception);
10126           if (image != (Image *) NULL)
10127             (void) SetImageChannelMask(image,channel_mask);
10128           break;
10129         }
10130         case 99:  /* Transpose */
10131         {
10132           image=TransposeImage(image,exception);
10133           break;
10134         }
10135         case 100:  /* Tranverse */
10136         {
10137           image=TransverseImage(image,exception);
10138           break;
10139         }
10140         case 101:  /* AutoOrient */
10141         {
10142           image=AutoOrientImage(image,image->orientation,exception);
10143           break;
10144         }
10145         case 102:  /* AdaptiveBlur */
10146         {
10147           if (attribute_flag[0] != 0)
10148             {
10149               flags=ParseGeometry(argument_list[0].string_reference,
10150                 &geometry_info);
10151               if ((flags & SigmaValue) == 0)
10152                 geometry_info.sigma=1.0;
10153               if ((flags & XiValue) == 0)
10154                 geometry_info.xi=0.0;
10155             }
10156           if (attribute_flag[1] != 0)
10157             geometry_info.rho=argument_list[1].real_reference;
10158           if (attribute_flag[2] != 0)
10159             geometry_info.sigma=argument_list[2].real_reference;
10160           if (attribute_flag[3] != 0)
10161             channel=(ChannelType) argument_list[3].integer_reference;
10162           channel_mask=SetImageChannelMask(image,channel);
10163           image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10164             exception);
10165           if (image != (Image *) NULL)
10166             (void) SetImageChannelMask(image,channel_mask);
10167           break;
10168         }
10169         case 103:  /* Sketch */
10170         {
10171           if (attribute_flag[0] != 0)
10172             {
10173               flags=ParseGeometry(argument_list[0].string_reference,
10174                 &geometry_info);
10175               if ((flags & SigmaValue) == 0)
10176                 geometry_info.sigma=1.0;
10177               if ((flags & XiValue) == 0)
10178                 geometry_info.xi=1.0;
10179             }
10180           if (attribute_flag[1] != 0)
10181             geometry_info.rho=argument_list[1].real_reference;
10182           if (attribute_flag[2] != 0)
10183             geometry_info.sigma=argument_list[2].real_reference;
10184           if (attribute_flag[3] != 0)
10185             geometry_info.xi=argument_list[3].real_reference;
10186           image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10187             geometry_info.xi,exception);
10188           break;
10189         }
10190         case 104:  /* UniqueColors */
10191         {
10192           image=UniqueImageColors(image,exception);
10193           break;
10194         }
10195         case 105:  /* AdaptiveResize */
10196         {
10197           if (attribute_flag[0] != 0)
10198             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10199               &geometry,exception);
10200           if (attribute_flag[1] != 0)
10201             geometry.width=argument_list[1].integer_reference;
10202           if (attribute_flag[2] != 0)
10203             geometry.height=argument_list[2].integer_reference;
10204           if (attribute_flag[3] != 0)
10205             image->filter=(FilterTypes) argument_list[4].integer_reference;
10206           if (attribute_flag[4] != 0)
10207             SetImageArtifact(image,"filter:support",
10208               argument_list[4].string_reference);
10209           image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10210             exception);
10211           break;
10212         }
10213         case 106:  /* ClipMask */
10214         {
10215           Image
10216             *mask_image;
10217
10218           if (attribute_flag[0] == 0)
10219             {
10220               ThrowPerlException(exception,OptionError,"MaskImageRequired",
10221                 PackageName);
10222               goto PerlException;
10223             }
10224           mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10225             exception);
10226           (void) NegateImage(mask_image,MagickFalse,exception);
10227           (void) SetImageMask(image,mask_image,exception);
10228           mask_image=DestroyImage(mask_image);
10229           break;
10230         }
10231         case 107:  /* LinearStretch */
10232         {
10233            double
10234              black_point,
10235              white_point;
10236
10237            black_point=0.0;
10238            white_point=(double) image->columns*image->rows;
10239            if (attribute_flag[0] != 0)
10240              {
10241                flags=ParseGeometry(argument_list[0].string_reference,
10242                  &geometry_info);
10243                if ((flags & SigmaValue) != 0)
10244                   white_point=geometry_info.sigma;
10245                if ((flags & PercentValue) != 0)
10246                  {
10247                    black_point*=(double) image->columns*image->rows/100.0;
10248                    white_point*=(double) image->columns*image->rows/100.0;
10249                  }
10250                if ((flags & SigmaValue) == 0)
10251                  white_point=(double) image->columns*image->rows-black_point;
10252              }
10253           if (attribute_flag[1] != 0)
10254             black_point=argument_list[1].real_reference;
10255           if (attribute_flag[2] != 0)
10256             white_point=argument_list[2].real_reference;
10257           (void) LinearStretchImage(image,black_point,white_point,exception);
10258           break;
10259         }
10260         case 108:  /* ColorMatrix */
10261         {
10262           AV
10263             *av;
10264
10265           double
10266             *color_matrix;
10267
10268           KernelInfo
10269             *kernel_info;
10270
10271           size_t
10272             order;
10273
10274           if (attribute_flag[0] == 0)
10275             break;
10276           av=(AV *) argument_list[0].array_reference;
10277           order=(size_t) sqrt(av_len(av)+1);
10278           color_matrix=(double *) AcquireQuantumMemory(order,order*
10279             sizeof(*color_matrix));
10280           if (color_matrix == (double *) NULL)
10281             {
10282               ThrowPerlException(exception,ResourceLimitFatalError,
10283                 "MemoryAllocationFailed",PackageName);
10284               goto PerlException;
10285            }
10286           for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10287             color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10288           for ( ; j < (ssize_t) (order*order); j++)
10289             color_matrix[j]=0.0;
10290           kernel_info=AcquireKernelInfo((const char *) NULL);
10291           if (kernel_info == (KernelInfo *) NULL)
10292             break;
10293           kernel_info->width=order;
10294           kernel_info->height=order;
10295           kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10296             order*sizeof(*kernel_info->values));
10297           if (kernel_info->values != (MagickRealType *) NULL)
10298             {
10299               for (i=0; i < (ssize_t) (order*order); i++)
10300                 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10301               image=ColorMatrixImage(image,kernel_info,exception);
10302             }
10303           kernel_info=DestroyKernelInfo(kernel_info);
10304           color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10305           break;
10306         }
10307         case 109:  /* Mask */
10308         {
10309           Image
10310             *mask_image;
10311
10312           if (attribute_flag[0] == 0)
10313             {
10314               ThrowPerlException(exception,OptionError,"MaskImageRequired",
10315                 PackageName);
10316               goto PerlException;
10317             }
10318           mask_image=CloneImage(argument_list[0].image_reference,0,0,
10319             MagickTrue,exception);
10320           (void) NegateImage(mask_image,MagickFalse,exception);
10321           (void) SetImageMask(image,mask_image,exception);
10322           mask_image=DestroyImage(mask_image);
10323           break;
10324         }
10325         case 110:  /* Polaroid */
10326         {
10327           char
10328             *caption;
10329
10330           DrawInfo
10331             *draw_info;
10332
10333           double
10334             angle;
10335
10336           PixelInterpolateMethod
10337             method;
10338
10339           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10340             (DrawInfo *) NULL);
10341           caption=(char *) NULL;
10342           if (attribute_flag[0] != 0)
10343             caption=InterpretImageProperties(info ? info->image_info :
10344               (ImageInfo *) NULL,image,argument_list[0].string_reference,
10345               exception);
10346           angle=0.0;
10347           if (attribute_flag[1] != 0)
10348             angle=argument_list[1].real_reference;
10349           if (attribute_flag[2] != 0)
10350             (void) CloneString(&draw_info->font,
10351               argument_list[2].string_reference);
10352           if (attribute_flag[3] != 0)
10353             (void) QueryColorCompliance(argument_list[3].string_reference,
10354               AllCompliance,&draw_info->stroke,exception);
10355           if (attribute_flag[4] != 0)
10356             (void) QueryColorCompliance(argument_list[4].string_reference,
10357               AllCompliance,&draw_info->fill,exception);
10358           if (attribute_flag[5] != 0)
10359             draw_info->stroke_width=argument_list[5].real_reference;
10360           if (attribute_flag[6] != 0)
10361             draw_info->pointsize=argument_list[6].real_reference;
10362           if (attribute_flag[7] != 0)
10363             draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10364           if (attribute_flag[8] != 0)
10365             (void) QueryColorCompliance(argument_list[8].string_reference,
10366               AllCompliance,&image->background_color,exception);
10367           method=UndefinedInterpolatePixel;
10368           if (attribute_flag[9] != 0)
10369             method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10370           image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10371           draw_info=DestroyDrawInfo(draw_info);
10372           if (caption != (char *) NULL)
10373             caption=DestroyString(caption);
10374           break;
10375         }
10376         case 111:  /* FloodfillPaint */
10377         {
10378           DrawInfo
10379             *draw_info;
10380
10381           MagickBooleanType
10382             invert;
10383
10384           PixelInfo
10385             target;
10386
10387           draw_info=CloneDrawInfo(info ? info->image_info :
10388             (ImageInfo *) NULL,(DrawInfo *) NULL);
10389           if (attribute_flag[0] != 0)
10390             flags=ParsePageGeometry(image,argument_list[0].string_reference,
10391               &geometry,exception);
10392           if (attribute_flag[1] != 0)
10393             geometry.x=argument_list[1].integer_reference;
10394           if (attribute_flag[2] != 0)
10395             geometry.y=argument_list[2].integer_reference;
10396           if (attribute_flag[3] != 0)
10397             (void) QueryColorCompliance(argument_list[3].string_reference,
10398               AllCompliance,&draw_info->fill,exception);
10399           (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10400             geometry.x,geometry.y,&target,exception);
10401           if (attribute_flag[4] != 0)
10402             QueryColorCompliance(argument_list[4].string_reference,
10403               AllCompliance,&target,exception);
10404           if (attribute_flag[5] != 0)
10405             image->fuzz=StringToDoubleInterval(
10406               argument_list[5].string_reference,(double) QuantumRange+1.0);
10407           if (attribute_flag[6] != 0)
10408             channel=(ChannelType) argument_list[6].integer_reference;
10409           invert=MagickFalse;
10410           if (attribute_flag[7] != 0)
10411             invert=(MagickBooleanType) argument_list[7].integer_reference;
10412           channel_mask=SetImageChannelMask(image,channel);
10413           (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10414             geometry.y,invert,exception);
10415           (void) SetImageChannelMask(image,channel_mask);
10416           draw_info=DestroyDrawInfo(draw_info);
10417           break;
10418         }
10419         case 112:  /* Distort */
10420         {
10421           AV
10422             *av;
10423
10424           double
10425             *coordinates;
10426
10427           DistortImageMethod
10428             method;
10429
10430           size_t
10431             number_coordinates;
10432
10433           VirtualPixelMethod
10434             virtual_pixel;
10435
10436           if (attribute_flag[0] == 0)
10437             break;
10438           method=UndefinedDistortion;
10439           if (attribute_flag[1] != 0)
10440             method=(DistortImageMethod) argument_list[1].integer_reference;
10441           av=(AV *) argument_list[0].array_reference;
10442           number_coordinates=(size_t) av_len(av)+1;
10443           coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10444             sizeof(*coordinates));
10445           if (coordinates == (double *) NULL)
10446             {
10447               ThrowPerlException(exception,ResourceLimitFatalError,
10448                 "MemoryAllocationFailed",PackageName);
10449               goto PerlException;
10450             }
10451           for (j=0; j < (ssize_t) number_coordinates; j++)
10452             coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10453           virtual_pixel=UndefinedVirtualPixelMethod;
10454           if (attribute_flag[2] != 0)
10455             virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10456               argument_list[2].integer_reference,exception);
10457           image=DistortImage(image,method,number_coordinates,coordinates,
10458             argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10459             exception);
10460           if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10461             virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10462               exception);
10463           coordinates=(double *) RelinquishMagickMemory(coordinates);
10464           break;
10465         }
10466         case 113:  /* Clut */
10467         {
10468           PixelInterpolateMethod
10469             method;
10470
10471           if (attribute_flag[0] == 0)
10472             {
10473               ThrowPerlException(exception,OptionError,"ClutImageRequired",
10474                 PackageName);
10475               goto PerlException;
10476             }
10477           method=UndefinedInterpolatePixel;
10478           if (attribute_flag[1] != 0)
10479             method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10480           if (attribute_flag[2] != 0)
10481             channel=(ChannelType) argument_list[2].integer_reference;
10482           channel_mask=SetImageChannelMask(image,channel);
10483           (void) ClutImage(image,argument_list[0].image_reference,method,
10484             exception);
10485           (void) SetImageChannelMask(image,channel_mask);
10486           break;
10487         }
10488         case 114:  /* LiquidRescale */
10489         {
10490           if (attribute_flag[0] != 0)
10491             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10492               &geometry,exception);
10493           if (attribute_flag[1] != 0)
10494             geometry.width=argument_list[1].integer_reference;
10495           if (attribute_flag[2] != 0)
10496             geometry.height=argument_list[2].integer_reference;
10497           if (attribute_flag[3] == 0)
10498             argument_list[3].real_reference=1.0;
10499           if (attribute_flag[4] == 0)
10500             argument_list[4].real_reference=0.0;
10501           image=LiquidRescaleImage(image,geometry.width,geometry.height,
10502             argument_list[3].real_reference,argument_list[4].real_reference,
10503             exception);
10504           break;
10505         }
10506         case 115:  /* EncipherImage */
10507         {
10508           (void) EncipherImage(image,argument_list[0].string_reference,
10509             exception);
10510           break;
10511         }
10512         case 116:  /* DecipherImage */
10513         {
10514           (void) DecipherImage(image,argument_list[0].string_reference,
10515             exception);
10516           break;
10517         }
10518         case 117:  /* Deskew */
10519         {
10520           geometry_info.rho=QuantumRange/2.0;
10521           if (attribute_flag[0] != 0)
10522             flags=ParseGeometry(argument_list[0].string_reference,
10523               &geometry_info);
10524           if (attribute_flag[1] != 0)
10525             geometry_info.rho=StringToDoubleInterval(
10526               argument_list[1].string_reference,(double) QuantumRange+1.0);
10527           image=DeskewImage(image,geometry_info.rho,exception);
10528           break;
10529         }
10530         case 118:  /* Remap */
10531         {
10532           QuantizeInfo
10533             *quantize_info;
10534
10535           if (attribute_flag[0] == 0)
10536             {
10537               ThrowPerlException(exception,OptionError,"RemapImageRequired",
10538                 PackageName);
10539               goto PerlException;
10540             }
10541           quantize_info=AcquireQuantizeInfo(info->image_info);
10542           if (attribute_flag[1] != 0)
10543             quantize_info->dither_method=(DitherMethod)
10544               argument_list[1].integer_reference;
10545           (void) RemapImages(quantize_info,image,
10546             argument_list[0].image_reference,exception);
10547           quantize_info=DestroyQuantizeInfo(quantize_info);
10548           break;
10549         }
10550         case 119:  /* SparseColor */
10551         {
10552           AV
10553             *av;
10554
10555           double
10556             *coordinates;
10557
10558           SparseColorMethod
10559             method;
10560
10561           size_t
10562             number_coordinates;
10563
10564           VirtualPixelMethod
10565             virtual_pixel;
10566
10567           if (attribute_flag[0] == 0)
10568             break;
10569           method=UndefinedColorInterpolate;
10570           if (attribute_flag[1] != 0)
10571             method=(SparseColorMethod) argument_list[1].integer_reference;
10572           av=(AV *) argument_list[0].array_reference;
10573           number_coordinates=(size_t) av_len(av)+1;
10574           coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10575             sizeof(*coordinates));
10576           if (coordinates == (double *) NULL)
10577             {
10578               ThrowPerlException(exception,ResourceLimitFatalError,
10579                 "MemoryAllocationFailed",PackageName);
10580               goto PerlException;
10581             }
10582           for (j=0; j < (ssize_t) number_coordinates; j++)
10583             coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10584           virtual_pixel=UndefinedVirtualPixelMethod;
10585           if (attribute_flag[2] != 0)
10586             virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10587               argument_list[2].integer_reference,exception);
10588           if (attribute_flag[3] != 0)
10589             channel=(ChannelType) argument_list[3].integer_reference;
10590           channel_mask=SetImageChannelMask(image,channel);
10591           image=SparseColorImage(image,method,number_coordinates,coordinates,
10592             exception);
10593           if (image != (Image *) NULL)
10594             (void) SetImageChannelMask(image,channel_mask);
10595           if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10596             virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10597               exception);
10598           coordinates=(double *) RelinquishMagickMemory(coordinates);
10599           break;
10600         }
10601         case 120:  /* Function */
10602         {
10603           AV
10604             *av;
10605
10606           double
10607             *parameters;
10608
10609           MagickFunction
10610             function;
10611
10612           size_t
10613             number_parameters;
10614
10615           VirtualPixelMethod
10616             virtual_pixel;
10617
10618           if (attribute_flag[0] == 0)
10619             break;
10620           function=UndefinedFunction;
10621           if (attribute_flag[1] != 0)
10622             function=(MagickFunction) argument_list[1].integer_reference;
10623           av=(AV *) argument_list[0].array_reference;
10624           number_parameters=(size_t) av_len(av)+1;
10625           parameters=(double *) AcquireQuantumMemory(number_parameters,
10626             sizeof(*parameters));
10627           if (parameters == (double *) NULL)
10628             {
10629               ThrowPerlException(exception,ResourceLimitFatalError,
10630                 "MemoryAllocationFailed",PackageName);
10631               goto PerlException;
10632             }
10633           for (j=0; j < (ssize_t) number_parameters; j++)
10634             parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10635           virtual_pixel=UndefinedVirtualPixelMethod;
10636           if (attribute_flag[2] != 0)
10637             virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10638               argument_list[2].integer_reference,exception);
10639           (void) FunctionImage(image,function,number_parameters,parameters,
10640             exception);
10641           if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10642             virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10643               exception);
10644           parameters=(double *) RelinquishMagickMemory(parameters);
10645           break;
10646         }
10647         case 121:  /* SelectiveBlur */
10648         {
10649           if (attribute_flag[0] != 0)
10650             {
10651               flags=ParseGeometry(argument_list[0].string_reference,
10652                 &geometry_info);
10653               if ((flags & SigmaValue) == 0)
10654                 geometry_info.sigma=1.0;
10655               if ((flags & PercentValue) != 0)
10656                 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10657             }
10658           if (attribute_flag[1] != 0)
10659             geometry_info.rho=argument_list[1].real_reference;
10660           if (attribute_flag[2] != 0)
10661             geometry_info.sigma=argument_list[2].real_reference;
10662           if (attribute_flag[3] != 0)
10663             geometry_info.xi=argument_list[3].integer_reference;;
10664           if (attribute_flag[5] != 0)
10665             channel=(ChannelType) argument_list[5].integer_reference;
10666           channel_mask=SetImageChannelMask(image,channel);
10667           image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10668             geometry_info.xi,exception);
10669           if (image != (Image *) NULL)
10670             (void) SetImageChannelMask(image,channel_mask);
10671           break;
10672         }
10673         case 122:  /* HaldClut */
10674         {
10675           if (attribute_flag[0] == 0)
10676             {
10677               ThrowPerlException(exception,OptionError,"ClutImageRequired",
10678                 PackageName);
10679               goto PerlException;
10680             }
10681           if (attribute_flag[1] != 0)
10682             channel=(ChannelType) argument_list[1].integer_reference;
10683           channel_mask=SetImageChannelMask(image,channel);
10684           (void) HaldClutImage(image,argument_list[0].image_reference,
10685             exception);
10686           (void) SetImageChannelMask(image,channel_mask);
10687           break;
10688         }
10689         case 123:  /* BlueShift */
10690         {
10691           if (attribute_flag[0] != 0)
10692             (void) ParseGeometry(argument_list[0].string_reference,
10693               &geometry_info);
10694           image=BlueShiftImage(image,geometry_info.rho,exception);
10695           break;
10696         }
10697         case 124:  /* ForwardFourierTransformImage */
10698         {
10699           image=ForwardFourierTransformImage(image,
10700             argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10701             exception);
10702           break;
10703         }
10704         case 125:  /* InverseFourierTransformImage */
10705         {
10706           image=InverseFourierTransformImage(image,image->next,
10707             argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10708             exception);
10709           break;
10710         }
10711         case 126:  /* ColorDecisionList */
10712         {
10713           if (attribute_flag[0] == 0)
10714             argument_list[0].string_reference=(char *) NULL;
10715           (void) ColorDecisionListImage(image,
10716             argument_list[0].string_reference,exception);
10717           break;
10718         }
10719         case 127:  /* AutoGamma */
10720         {
10721           if (attribute_flag[0] != 0)
10722             channel=(ChannelType) argument_list[0].integer_reference;
10723           channel_mask=SetImageChannelMask(image,channel);
10724           (void) AutoGammaImage(image,exception);
10725           (void) SetImageChannelMask(image,channel_mask);
10726           break;
10727         }
10728         case 128:  /* AutoLevel */
10729         {
10730           if (attribute_flag[0] != 0)
10731             channel=(ChannelType) argument_list[0].integer_reference;
10732           channel_mask=SetImageChannelMask(image,channel);
10733           (void) AutoLevelImage(image,exception);
10734           (void) SetImageChannelMask(image,channel_mask);
10735           break;
10736         }
10737         case 129:  /* LevelColors */
10738         {
10739           PixelInfo
10740             black_point,
10741             white_point;
10742
10743           (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
10744             exception);
10745           (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
10746             exception);
10747           if (attribute_flag[1] != 0)
10748              (void) QueryColorCompliance(
10749                argument_list[1].string_reference,AllCompliance,&black_point,
10750                exception);
10751           if (attribute_flag[2] != 0)
10752              (void) QueryColorCompliance(
10753                argument_list[2].string_reference,AllCompliance,&white_point,
10754                exception);
10755           if (attribute_flag[3] != 0)
10756             channel=(ChannelType) argument_list[3].integer_reference;
10757           channel_mask=SetImageChannelMask(image,channel);
10758           (void) LevelImageColors(image,&black_point,&white_point,
10759             argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10760             exception);
10761           (void) SetImageChannelMask(image,channel_mask);
10762           break;
10763         }
10764         case 130:  /* Clamp */
10765         {
10766           if (attribute_flag[0] != 0)
10767             channel=(ChannelType) argument_list[0].integer_reference;
10768           channel_mask=SetImageChannelMask(image,channel);
10769           (void) ClampImage(image,exception);
10770           (void) SetImageChannelMask(image,channel_mask);
10771           break;
10772         }
10773         case 131:  /* BrightnessContrast */
10774         {
10775           double
10776             brightness,
10777             contrast;
10778
10779           brightness=0.0;
10780           contrast=0.0;
10781           if (attribute_flag[0] != 0)
10782             {
10783               flags=ParseGeometry(argument_list[0].string_reference,
10784                 &geometry_info);
10785               brightness=geometry_info.rho;
10786               if ((flags & SigmaValue) == 0)
10787                 contrast=geometry_info.sigma;
10788             }
10789           if (attribute_flag[1] != 0)
10790             brightness=argument_list[1].real_reference;
10791           if (attribute_flag[2] != 0)
10792             contrast=argument_list[2].real_reference;
10793           if (attribute_flag[4] != 0)
10794             channel=(ChannelType) argument_list[4].integer_reference;
10795           channel_mask=SetImageChannelMask(image,channel);
10796           (void) BrightnessContrastImage(image,brightness,contrast,exception);
10797           (void) SetImageChannelMask(image,channel_mask);
10798           break;
10799         }
10800         case 132:  /* Morphology */
10801         {
10802           KernelInfo
10803             *kernel;
10804
10805           MorphologyMethod
10806             method;
10807
10808           ssize_t
10809             iterations;
10810
10811           if (attribute_flag[0] == 0)
10812             break;
10813           kernel=AcquireKernelInfo(argument_list[0].string_reference);
10814           if (kernel == (KernelInfo *) NULL)
10815             break;
10816           if (attribute_flag[1] != 0)
10817             channel=(ChannelType) argument_list[1].integer_reference;
10818           method=UndefinedMorphology;
10819           if (attribute_flag[2] != 0)
10820             method=argument_list[2].integer_reference;
10821           iterations=1;
10822           if (attribute_flag[3] != 0)
10823             iterations=argument_list[3].integer_reference;
10824           channel_mask=SetImageChannelMask(image,channel);
10825           image=MorphologyImage(image,method,iterations,kernel,exception);
10826           if (image != (Image *) NULL)
10827             (void) SetImageChannelMask(image,channel_mask);
10828           kernel=DestroyKernelInfo(kernel);
10829           break;
10830         }
10831         case 133:  /* Mode */
10832         {
10833           if (attribute_flag[0] != 0)
10834             {
10835               flags=ParseGeometry(argument_list[0].string_reference,
10836                 &geometry_info);
10837               if ((flags & SigmaValue) == 0)
10838                 geometry_info.sigma=1.0;
10839             }
10840           if (attribute_flag[1] != 0)
10841             geometry_info.rho=argument_list[1].real_reference;
10842           if (attribute_flag[2] != 0)
10843             geometry_info.sigma=argument_list[2].real_reference;
10844           if (attribute_flag[3] != 0)
10845             channel=(ChannelType) argument_list[3].integer_reference;
10846           channel_mask=SetImageChannelMask(image,channel);
10847           image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
10848             (size_t) geometry_info.sigma,exception);
10849           if (image != (Image *) NULL)
10850             (void) SetImageChannelMask(image,channel_mask);
10851           break;
10852         }
10853         case 134:  /* Statistic */
10854         {
10855           StatisticType
10856             statistic;
10857
10858           statistic=UndefinedStatistic;
10859           if (attribute_flag[0] != 0)
10860             {
10861               flags=ParseGeometry(argument_list[0].string_reference,
10862                 &geometry_info);
10863               if ((flags & SigmaValue) == 0)
10864                 geometry_info.sigma=1.0;
10865             }
10866           if (attribute_flag[1] != 0)
10867             geometry_info.rho=argument_list[1].real_reference;
10868           if (attribute_flag[2] != 0)
10869             geometry_info.sigma=argument_list[2].real_reference;
10870           if (attribute_flag[3] != 0)
10871             channel=(ChannelType) argument_list[3].integer_reference;
10872           if (attribute_flag[4] != 0)
10873             statistic=(StatisticType) argument_list[4].integer_reference;
10874           channel_mask=SetImageChannelMask(image,channel);
10875           image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
10876             (size_t) geometry_info.sigma,exception);
10877           if (image != (Image *) NULL)
10878             (void) SetImageChannelMask(image,channel_mask);
10879           break;
10880         }
10881         case 135:  /* Perceptible */
10882         {
10883           double
10884             epsilon;
10885
10886           epsilon=MagickEpsilon;
10887           if (attribute_flag[0] != 0)
10888             epsilon=argument_list[0].real_reference;
10889           if (attribute_flag[1] != 0)
10890             channel=(ChannelType) argument_list[1].integer_reference;
10891           channel_mask=SetImageChannelMask(image,channel);
10892           (void) PerceptibleImage(image,epsilon,exception);
10893           (void) SetImageChannelMask(image,channel_mask);
10894           break;
10895         }
10896         case 136:  /* Poly */
10897         {
10898           AV
10899             *av;
10900
10901           double
10902             *terms;
10903
10904           size_t
10905             number_terms;
10906
10907           if (attribute_flag[0] == 0)
10908             break;
10909           if (attribute_flag[1] != 0)
10910             channel=(ChannelType) argument_list[1].integer_reference;
10911           av=(AV *) argument_list[0].array_reference;
10912           number_terms=(size_t) av_len(av);
10913           terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
10914           if (terms == (double *) NULL)
10915             {
10916               ThrowPerlException(exception,ResourceLimitFatalError,
10917                 "MemoryAllocationFailed",PackageName);
10918               goto PerlException;
10919             }
10920           for (j=0; j < av_len(av); j++)
10921             terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
10922           image=PolynomialImage(image,number_terms >> 1,terms,exception);
10923           terms=(double *) RelinquishMagickMemory(terms);
10924           break;
10925         }
10926       }
10927       if (next != (Image *) NULL)
10928         (void) CatchImageException(next);
10929       if (region_image != (Image *) NULL)
10930         {
10931           /*
10932             Composite region.
10933           */ 
10934           status=CompositeImage(region_image,image,CopyCompositeOp,MagickTrue,
10935             region_info.x,region_info.y,exception);
10936           (void) status;
10937           (void) CatchImageException(region_image);
10938           image=DestroyImage(image);
10939           image=region_image;
10940         }
10941       if (image != (Image *) NULL)
10942         {
10943           number_images++;
10944           if (next && (next != image))
10945             {
10946               image->next=next->next;
10947               if (image->next != (Image *) NULL)
10948                 image->next->previous=image;
10949               DeleteImageFromRegistry(*pv,next);
10950             }
10951           sv_setiv(*pv,PTR2IV(image));
10952           next=image;
10953         }
10954       if (*pv)
10955         pv++;
10956     }
10957
10958   PerlException:
10959     if (reference_vector)
10960       reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
10961     InheritPerlException(exception,perl_exception);
10962     exception=DestroyExceptionInfo(exception);
10963     sv_setiv(perl_exception,(IV) number_images);
10964     SvPOK_on(perl_exception);
10965     ST(0)=sv_2mortal(perl_exception);
10966     XSRETURN(1);
10967   }
10968 \f
10969 #
10970 ###############################################################################
10971 #                                                                             #
10972 #                                                                             #
10973 #                                                                             #
10974 #   M o n t a g e                                                             #
10975 #                                                                             #
10976 #                                                                             #
10977 #                                                                             #
10978 ###############################################################################
10979 #
10980 #
10981 void
10982 Montage(ref,...)
10983   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
10984   ALIAS:
10985     MontageImage  = 1
10986     montage       = 2
10987     montageimage  = 3
10988   PPCODE:
10989   {
10990     AV
10991       *av;
10992
10993     char
10994       *attribute;
10995
10996     ExceptionInfo
10997       *exception;
10998
10999     HV
11000       *hv;
11001
11002     Image
11003       *image,
11004       *next;
11005
11006     PixelInfo
11007       transparent_color;
11008
11009     MontageInfo
11010       *montage_info;
11011
11012     register ssize_t
11013       i;
11014
11015     ssize_t
11016       sp;
11017
11018     struct PackageInfo
11019       *info;
11020
11021     SV
11022       *av_reference,
11023       *perl_exception,
11024       *reference,
11025       *rv,
11026       *sv;
11027
11028     PERL_UNUSED_VAR(ref);
11029     PERL_UNUSED_VAR(ix);
11030     exception=AcquireExceptionInfo();
11031     perl_exception=newSVpv("",0);
11032     sv=NULL;
11033     attribute=NULL;
11034     if (sv_isobject(ST(0)) == 0)
11035       {
11036         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11037           PackageName);
11038         goto PerlException;
11039       }
11040     reference=SvRV(ST(0));
11041     hv=SvSTASH(reference);
11042     av=newAV();
11043     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11044     SvREFCNT_dec(av);
11045     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11046     if (image == (Image *) NULL)
11047       {
11048         ThrowPerlException(exception,OptionError,"NoImagesDefined",
11049           PackageName);
11050         goto PerlException;
11051       }
11052     /*
11053       Get options.
11054     */
11055     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11056     montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11057     (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11058       exception);
11059     for (i=2; i < items; i+=2)
11060     {
11061       attribute=(char *) SvPV(ST(i-1),na);
11062       switch (*attribute)
11063       {
11064         case 'B':
11065         case 'b':
11066         {
11067           if (LocaleCompare(attribute,"background") == 0)
11068             {
11069               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11070                 &montage_info->background_color,exception);
11071               for (next=image; next; next=next->next)
11072                 next->background_color=montage_info->background_color;
11073               break;
11074             }
11075           if (LocaleCompare(attribute,"border") == 0)
11076             {
11077               montage_info->border_width=SvIV(ST(i));
11078               break;
11079             }
11080           if (LocaleCompare(attribute,"bordercolor") == 0)
11081             {
11082               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11083                 &montage_info->border_color,exception);
11084               for (next=image; next; next=next->next)
11085                 next->border_color=montage_info->border_color;
11086               break;
11087             }
11088           if (LocaleCompare(attribute,"borderwidth") == 0)
11089             {
11090               montage_info->border_width=SvIV(ST(i));
11091               break;
11092             }
11093           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11094             attribute);
11095           break;
11096         }
11097         case 'C':
11098         case 'c':
11099         {
11100           if (LocaleCompare(attribute,"compose") == 0)
11101             {
11102               sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11103                 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11104               if (sp < 0)
11105                 {
11106                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
11107                     SvPV(ST(i),na));
11108                   break;
11109                 }
11110               for (next=image; next; next=next->next)
11111                 next->compose=(CompositeOperator) sp;
11112               break;
11113             }
11114           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11115             attribute);
11116           break;
11117         }
11118         case 'F':
11119         case 'f':
11120         {
11121           if (LocaleCompare(attribute,"fill") == 0)
11122             {
11123               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11124                 &montage_info->fill,exception);
11125               break;
11126             }
11127           if (LocaleCompare(attribute,"font") == 0)
11128             {
11129               (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11130               break;
11131             }
11132           if (LocaleCompare(attribute,"frame") == 0)
11133             {
11134               char
11135                 *p;
11136
11137               p=SvPV(ST(i),na);
11138               if (IsGeometry(p) == MagickFalse)
11139                 {
11140                   ThrowPerlException(exception,OptionError,"MissingGeometry",
11141                     p);
11142                   break;
11143                 }
11144               (void) CloneString(&montage_info->frame,p);
11145               if (*p == '\0')
11146                 montage_info->frame=(char *) NULL;
11147               break;
11148             }
11149           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11150             attribute);
11151           break;
11152         }
11153         case 'G':
11154         case 'g':
11155         {
11156           if (LocaleCompare(attribute,"geometry") == 0)
11157             {
11158               char
11159                 *p;
11160
11161               p=SvPV(ST(i),na);
11162               if (IsGeometry(p) == MagickFalse)
11163                 {
11164                   ThrowPerlException(exception,OptionError,"MissingGeometry",
11165                     p);
11166                   break;
11167                 }
11168              (void) CloneString(&montage_info->geometry,p);
11169              if (*p == '\0')
11170                montage_info->geometry=(char *) NULL;
11171              break;
11172            }
11173          if (LocaleCompare(attribute,"gravity") == 0)
11174            {
11175              ssize_t
11176                in;
11177
11178              in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11179                MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11180              if (in < 0)
11181                {
11182                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
11183                    SvPV(ST(i),na));
11184                  return;
11185                }
11186              montage_info->gravity=(GravityType) in;
11187              for (next=image; next; next=next->next)
11188                next->gravity=(GravityType) in;
11189              break;
11190            }
11191           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11192             attribute);
11193           break;
11194         }
11195         case 'L':
11196         case 'l':
11197         {
11198           if (LocaleCompare(attribute,"label") == 0)
11199             {
11200               for (next=image; next; next=next->next)
11201                 (void) SetImageProperty(next,"label",InterpretImageProperties(
11202                   info ? info->image_info : (ImageInfo *) NULL,next,
11203                   SvPV(ST(i),na),exception),exception);
11204               break;
11205             }
11206           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11207             attribute);
11208           break;
11209         }
11210         case 'M':
11211         case 'm':
11212         {
11213           if (LocaleCompare(attribute,"mattecolor") == 0)
11214             {
11215               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11216                 &montage_info->matte_color,exception);
11217               for (next=image; next; next=next->next)
11218                 next->matte_color=montage_info->matte_color;
11219               break;
11220             }
11221           if (LocaleCompare(attribute,"mode") == 0)
11222             {
11223               ssize_t
11224                 in;
11225
11226               in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11227                 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11228               switch (in)
11229               {
11230                 default:
11231                 {
11232                   ThrowPerlException(exception,OptionError,
11233                     "UnrecognizedModeType",SvPV(ST(i),na));
11234                   break;
11235                 }
11236                 case FrameMode:
11237                 {
11238                   (void) CloneString(&montage_info->frame,"15x15+3+3");
11239                   montage_info->shadow=MagickTrue;
11240                   break;
11241                 }
11242                 case UnframeMode:
11243                 {
11244                   montage_info->frame=(char *) NULL;
11245                   montage_info->shadow=MagickFalse;
11246                   montage_info->border_width=0;
11247                   break;
11248                 }
11249                 case ConcatenateMode:
11250                 {
11251                   montage_info->frame=(char *) NULL;
11252                   montage_info->shadow=MagickFalse;
11253                   (void) CloneString(&montage_info->geometry,"+0+0");
11254                   montage_info->border_width=0;
11255                 }
11256               }
11257               break;
11258             }
11259           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11260             attribute);
11261           break;
11262         }
11263         case 'P':
11264         case 'p':
11265         {
11266           if (LocaleCompare(attribute,"pointsize") == 0)
11267             {
11268               montage_info->pointsize=SvIV(ST(i));
11269               break;
11270             }
11271           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11272             attribute);
11273           break;
11274         }
11275         case 'S':
11276         case 's':
11277         {
11278           if (LocaleCompare(attribute,"shadow") == 0)
11279             {
11280               sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11281                 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11282               if (sp < 0)
11283                 {
11284                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
11285                     SvPV(ST(i),na));
11286                   break;
11287                 }
11288              montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11289              break;
11290             }
11291           if (LocaleCompare(attribute,"stroke") == 0)
11292             {
11293               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11294                 &montage_info->stroke,exception);
11295               break;
11296             }
11297           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11298             attribute);
11299           break;
11300         }
11301         case 'T':
11302         case 't':
11303         {
11304           if (LocaleCompare(attribute,"texture") == 0)
11305             {
11306               (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11307               break;
11308             }
11309           if (LocaleCompare(attribute,"tile") == 0)
11310             {
11311               char *p=SvPV(ST(i),na);
11312               if (IsGeometry(p) == MagickFalse)
11313                 {
11314                   ThrowPerlException(exception,OptionError,"MissingGeometry",
11315                     p);
11316                   break;
11317                 }
11318               (void) CloneString(&montage_info->tile,p);
11319               if (*p == '\0')
11320                 montage_info->tile=(char *) NULL;
11321               break;
11322             }
11323           if (LocaleCompare(attribute,"title") == 0)
11324             {
11325               (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11326               break;
11327             }
11328           if (LocaleCompare(attribute,"transparent") == 0)
11329             {
11330               PixelInfo
11331                 transparent_color;
11332
11333               QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11334                 &transparent_color,exception);
11335               for (next=image; next; next=next->next)
11336                 (void) TransparentPaintImage(next,&transparent_color,
11337                   TransparentAlpha,MagickFalse,exception);
11338               break;
11339             }
11340           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11341             attribute);
11342           break;
11343         }
11344         default:
11345         {
11346           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11347             attribute);
11348           break;
11349         }
11350       }
11351     }
11352     image=MontageImageList(info->image_info,montage_info,image,exception);
11353     montage_info=DestroyMontageInfo(montage_info);
11354     if (image == (Image *) NULL)
11355       goto PerlException;
11356     if (transparent_color.alpha != TransparentAlpha)
11357       for (next=image; next; next=next->next)
11358         (void) TransparentPaintImage(next,&transparent_color,
11359           TransparentAlpha,MagickFalse,exception);
11360     for (  ; image; image=image->next)
11361     {
11362       AddImageToRegistry(sv,image);
11363       rv=newRV(sv);
11364       av_push(av,sv_bless(rv,hv));
11365       SvREFCNT_dec(sv);
11366     }
11367     exception=DestroyExceptionInfo(exception);
11368     ST(0)=av_reference;
11369     SvREFCNT_dec(perl_exception);
11370     XSRETURN(1);
11371
11372   PerlException:
11373     InheritPerlException(exception,perl_exception);
11374     exception=DestroyExceptionInfo(exception);
11375     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11376     SvPOK_on(perl_exception);
11377     ST(0)=sv_2mortal(perl_exception);
11378     XSRETURN(1);
11379   }
11380 \f
11381 #
11382 ###############################################################################
11383 #                                                                             #
11384 #                                                                             #
11385 #                                                                             #
11386 #   M o r p h                                                                 #
11387 #                                                                             #
11388 #                                                                             #
11389 #                                                                             #
11390 ###############################################################################
11391 #
11392 #
11393 void
11394 Morph(ref,...)
11395   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
11396   ALIAS:
11397     MorphImage  = 1
11398     morph       = 2
11399     morphimage  = 3
11400   PPCODE:
11401   {
11402     AV
11403       *av;
11404
11405     char
11406       *attribute;
11407
11408     ExceptionInfo
11409       *exception;
11410
11411     HV
11412       *hv;
11413
11414     Image
11415       *image;
11416
11417     register ssize_t
11418       i;
11419
11420     ssize_t
11421       number_frames;
11422
11423     struct PackageInfo
11424       *info;
11425
11426     SV
11427       *av_reference,
11428       *perl_exception,
11429       *reference,
11430       *rv,
11431       *sv;
11432
11433     PERL_UNUSED_VAR(ref);
11434     PERL_UNUSED_VAR(ix);
11435     exception=AcquireExceptionInfo();
11436     perl_exception=newSVpv("",0);
11437     sv=NULL;
11438     av=NULL;
11439     attribute=NULL;
11440     if (sv_isobject(ST(0)) == 0)
11441       {
11442         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11443           PackageName);
11444         goto PerlException;
11445       }
11446     reference=SvRV(ST(0));
11447     hv=SvSTASH(reference);
11448     av=newAV();
11449     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11450     SvREFCNT_dec(av);
11451     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11452     if (image == (Image *) NULL)
11453       {
11454         ThrowPerlException(exception,OptionError,"NoImagesDefined",
11455           PackageName);
11456         goto PerlException;
11457       }
11458     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11459     /*
11460       Get attribute.
11461     */
11462     number_frames=30;
11463     for (i=2; i < items; i+=2)
11464     {
11465       attribute=(char *) SvPV(ST(i-1),na);
11466       switch (*attribute)
11467       {
11468         case 'F':
11469         case 'f':
11470         {
11471           if (LocaleCompare(attribute,"frames") == 0)
11472             {
11473               number_frames=SvIV(ST(i));
11474               break;
11475             }
11476           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11477             attribute);
11478           break;
11479         }
11480         default:
11481         {
11482           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11483             attribute);
11484           break;
11485         }
11486       }
11487     }
11488     image=MorphImages(image,number_frames,exception);
11489     if (image == (Image *) NULL)
11490       goto PerlException;
11491     for ( ; image; image=image->next)
11492     {
11493       AddImageToRegistry(sv,image);
11494       rv=newRV(sv);
11495       av_push(av,sv_bless(rv,hv));
11496       SvREFCNT_dec(sv);
11497     }
11498     exception=DestroyExceptionInfo(exception);
11499     ST(0)=av_reference;
11500     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
11501     XSRETURN(1);
11502
11503   PerlException:
11504     InheritPerlException(exception,perl_exception);
11505     exception=DestroyExceptionInfo(exception);
11506     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11507     SvPOK_on(perl_exception);
11508     ST(0)=sv_2mortal(perl_exception);
11509     XSRETURN(1);
11510   }
11511 \f
11512 #
11513 ###############################################################################
11514 #                                                                             #
11515 #                                                                             #
11516 #                                                                             #
11517 #   M o s a i c                                                               #
11518 #                                                                             #
11519 #                                                                             #
11520 #                                                                             #
11521 ###############################################################################
11522 #
11523 #
11524 void
11525 Mosaic(ref)
11526   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
11527   ALIAS:
11528     MosaicImage   = 1
11529     mosaic        = 2
11530     mosaicimage   = 3
11531   PPCODE:
11532   {
11533     AV
11534       *av;
11535
11536     ExceptionInfo
11537       *exception;
11538
11539     HV
11540       *hv;
11541
11542     Image
11543       *image;
11544
11545     struct PackageInfo
11546       *info;
11547
11548     SV
11549       *perl_exception,
11550       *reference,
11551       *rv,
11552       *sv;
11553
11554     PERL_UNUSED_VAR(ref);
11555     PERL_UNUSED_VAR(ix);
11556     exception=AcquireExceptionInfo();
11557     perl_exception=newSVpv("",0);
11558     sv=NULL;
11559     if (sv_isobject(ST(0)) == 0)
11560       {
11561         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11562           PackageName);
11563         goto PerlException;
11564       }
11565     reference=SvRV(ST(0));
11566     hv=SvSTASH(reference);
11567     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11568     if (image == (Image *) NULL)
11569       {
11570         ThrowPerlException(exception,OptionError,"NoImagesDefined",
11571           PackageName);
11572         goto PerlException;
11573       }
11574     image=MergeImageLayers(image,MosaicLayer,exception);
11575     /*
11576       Create blessed Perl array for the returned image.
11577     */
11578     av=newAV();
11579     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11580     SvREFCNT_dec(av);
11581     AddImageToRegistry(sv,image);
11582     rv=newRV(sv);
11583     av_push(av,sv_bless(rv,hv));
11584     SvREFCNT_dec(sv);
11585     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11586     (void) CopyMagickString(info->image_info->filename,image->filename,
11587       MaxTextExtent);
11588     SetImageInfo(info->image_info,0,exception);
11589     exception=DestroyExceptionInfo(exception);
11590     SvREFCNT_dec(perl_exception);
11591     XSRETURN(1);
11592
11593   PerlException:
11594     InheritPerlException(exception,perl_exception);
11595     exception=DestroyExceptionInfo(exception);
11596     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11597     SvPOK_on(perl_exception);  /* return messages in string context */
11598     ST(0)=sv_2mortal(perl_exception);
11599     XSRETURN(1);
11600   }
11601 \f
11602 #
11603 ###############################################################################
11604 #                                                                             #
11605 #                                                                             #
11606 #                                                                             #
11607 #   P i n g                                                                   #
11608 #                                                                             #
11609 #                                                                             #
11610 #                                                                             #
11611 ###############################################################################
11612 #
11613 #
11614 void
11615 Ping(ref,...)
11616   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
11617   ALIAS:
11618     PingImage  = 1
11619     ping       = 2
11620     pingimage  = 3
11621   PPCODE:
11622   {
11623     AV
11624       *av;
11625
11626     char
11627       **keep,
11628       **list;
11629
11630     ExceptionInfo
11631       *exception;
11632
11633     Image
11634       *image,
11635       *next;
11636
11637     int
11638       n;
11639
11640     MagickBooleanType
11641       status;
11642
11643     register char
11644       **p;
11645
11646     register ssize_t
11647       i;
11648
11649     ssize_t
11650       ac;
11651
11652     STRLEN
11653       *length;
11654
11655     struct PackageInfo
11656       *info,
11657       *package_info;
11658
11659     SV
11660       *perl_exception,
11661       *reference;
11662
11663     size_t
11664       count;
11665
11666     PERL_UNUSED_VAR(ref);
11667     PERL_UNUSED_VAR(ix);
11668     exception=AcquireExceptionInfo();
11669     perl_exception=newSVpv("",0);
11670     package_info=(struct PackageInfo *) NULL;
11671     ac=(items < 2) ? 1 : items-1;
11672     list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
11673     keep=list;
11674     length=(STRLEN *) NULL;
11675     if (list == (char **) NULL)
11676       {
11677         ThrowPerlException(exception,ResourceLimitError,
11678           "MemoryAllocationFailed",PackageName);
11679         goto PerlException;
11680       }
11681     keep=list;
11682     length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
11683     if (length == (STRLEN *) NULL)
11684       {
11685         ThrowPerlException(exception,ResourceLimitError,
11686           "MemoryAllocationFailed",PackageName);
11687         goto PerlException;
11688       }
11689     if (sv_isobject(ST(0)) == 0)
11690       {
11691         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11692           PackageName);
11693         goto PerlException;
11694       }
11695     reference=SvRV(ST(0));
11696     if (SvTYPE(reference) != SVt_PVAV)
11697       {
11698         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11699           PackageName);
11700         goto PerlException;
11701       }
11702     av=(AV *) reference;
11703     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
11704       exception);
11705     package_info=ClonePackageInfo(info,exception);
11706     n=1;
11707     if (items <= 1)
11708       *list=(char *) (*package_info->image_info->filename ?
11709         package_info->image_info->filename : "XC:black");
11710     else
11711       for (n=0, i=0; i < ac; i++)
11712       {
11713         list[n]=(char *) SvPV(ST(i+1),length[n]);
11714         if ((items >= 3) && strEQcase(list[n],"blob"))
11715           {
11716             void
11717               *blob;
11718
11719             i++;
11720             blob=(void *) (SvPV(ST(i+1),length[n]));
11721             SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
11722           }
11723         if ((items >= 3) && strEQcase(list[n],"filename"))
11724           continue;
11725         if ((items >= 3) && strEQcase(list[n],"file"))
11726           {
11727             FILE
11728               *file;
11729
11730             PerlIO
11731               *io_info;
11732
11733             i++;
11734             io_info=IoIFP(sv_2io(ST(i+1)));
11735             if (io_info == (PerlIO *) NULL)
11736               {
11737                 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
11738                   PackageName);
11739                 continue;
11740               }
11741             file=PerlIO_findFILE(io_info);
11742             if (file == (FILE *) NULL)
11743               {
11744                 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
11745                   PackageName);
11746                 continue;
11747               }
11748             SetImageInfoFile(package_info->image_info,file);
11749           }
11750         if ((items >= 3) && strEQcase(list[n],"magick"))
11751           continue;
11752         n++;
11753       }
11754     list[n]=(char *) NULL;
11755     keep=list;
11756     status=ExpandFilenames(&n,&list);
11757     if (status == MagickFalse)
11758       {
11759         ThrowPerlException(exception,ResourceLimitError,
11760           "MemoryAllocationFailed",PackageName);
11761         goto PerlException;
11762       }
11763     count=0;
11764     for (i=0; i < n; i++)
11765     {
11766       (void) CopyMagickString(package_info->image_info->filename,list[i],
11767         MaxTextExtent);
11768       image=PingImage(package_info->image_info,exception);
11769       if (image == (Image *) NULL)
11770         break;
11771       if ((package_info->image_info->file != (FILE *) NULL) ||
11772           (package_info->image_info->blob != (void *) NULL))
11773         DisassociateImageStream(image);
11774       count+=GetImageListLength(image);
11775       EXTEND(sp,4*count);
11776       for (next=image; next; next=next->next)
11777       {
11778         PUSHs(sv_2mortal(newSViv(next->columns)));
11779         PUSHs(sv_2mortal(newSViv(next->rows)));
11780         PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
11781         PUSHs(sv_2mortal(newSVpv(next->magick,0)));
11782       }
11783       image=DestroyImageList(image);
11784     }
11785     /*
11786       Free resources.
11787     */
11788     for (i=0; i < n; i++)
11789       if (list[i] != (char *) NULL)
11790         for (p=keep; list[i] != *p++; )
11791           if (*p == NULL)
11792             {
11793               list[i]=(char *) RelinquishMagickMemory(list[i]);
11794               break;
11795             }
11796
11797   PerlException:
11798     if (package_info != (struct PackageInfo *) NULL)
11799       DestroyPackageInfo(package_info);
11800     if (list && (list != keep))
11801       list=(char **) RelinquishMagickMemory(list);
11802     if (keep)
11803       keep=(char **) RelinquishMagickMemory(keep);
11804     if (length)
11805       length=(STRLEN *) RelinquishMagickMemory(length);
11806     InheritPerlException(exception,perl_exception);
11807     exception=DestroyExceptionInfo(exception);
11808     SvREFCNT_dec(perl_exception);  /* throw away all errors */
11809   }
11810 \f
11811 #
11812 ###############################################################################
11813 #                                                                             #
11814 #                                                                             #
11815 #                                                                             #
11816 #   P r e v i e w                                                             #
11817 #                                                                             #
11818 #                                                                             #
11819 #                                                                             #
11820 ###############################################################################
11821 #
11822 #
11823 void
11824 Preview(ref,...)
11825   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
11826   ALIAS:
11827     PreviewImage = 1
11828     preview      = 2
11829     previewimage = 3
11830   PPCODE:
11831   {
11832     AV
11833       *av;
11834
11835     ExceptionInfo
11836       *exception;
11837
11838     HV
11839       *hv;
11840
11841     Image
11842       *image,
11843       *preview_image;
11844
11845     PreviewType
11846       preview_type;
11847
11848     struct PackageInfo
11849       *info;
11850
11851     SV
11852       *av_reference,
11853       *perl_exception,
11854       *reference,
11855       *rv,
11856       *sv;
11857
11858     PERL_UNUSED_VAR(ref);
11859     PERL_UNUSED_VAR(ix);
11860     exception=AcquireExceptionInfo();
11861     perl_exception=newSVpv("",0);
11862     sv=NULL;
11863     av=NULL;
11864     if (sv_isobject(ST(0)) == 0)
11865       {
11866         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11867           PackageName);
11868         goto PerlException;
11869       }
11870     reference=SvRV(ST(0));
11871     hv=SvSTASH(reference);
11872     av=newAV();
11873     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11874     SvREFCNT_dec(av);
11875     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11876     if (image == (Image *) NULL)
11877       {
11878         ThrowPerlException(exception,OptionError,"NoImagesDefined",
11879           PackageName);
11880         goto PerlException;
11881       }
11882     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11883     preview_type=GammaPreview;
11884     if (items > 1)
11885       preview_type=(PreviewType)
11886         ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
11887     for ( ; image; image=image->next)
11888     {
11889       preview_image=PreviewImage(image,preview_type,exception);
11890       if (preview_image == (Image *) NULL)
11891         goto PerlException;
11892       AddImageToRegistry(sv,preview_image);
11893       rv=newRV(sv);
11894       av_push(av,sv_bless(rv,hv));
11895       SvREFCNT_dec(sv);
11896     }
11897     exception=DestroyExceptionInfo(exception);
11898     ST(0)=av_reference;
11899     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
11900     XSRETURN(1);
11901
11902   PerlException:
11903     InheritPerlException(exception,perl_exception);
11904     exception=DestroyExceptionInfo(exception);
11905     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11906     SvPOK_on(perl_exception);
11907     ST(0)=sv_2mortal(perl_exception);
11908     XSRETURN(1);
11909   }
11910 \f
11911 #
11912 ###############################################################################
11913 #                                                                             #
11914 #                                                                             #
11915 #                                                                             #
11916 #   Q u e r y C o l o r                                                       #
11917 #                                                                             #
11918 #                                                                             #
11919 #                                                                             #
11920 ###############################################################################
11921 #
11922 #
11923 void
11924 QueryColor(ref,...)
11925   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
11926   ALIAS:
11927     querycolor = 1
11928   PPCODE:
11929   {
11930     char
11931       *name;
11932
11933     ExceptionInfo
11934       *exception;
11935
11936     PixelInfo
11937       color;
11938
11939     register ssize_t
11940       i;
11941
11942     SV
11943       *perl_exception;
11944
11945     PERL_UNUSED_VAR(ref);
11946     PERL_UNUSED_VAR(ix);
11947     exception=AcquireExceptionInfo();
11948     perl_exception=newSVpv("",0);
11949     if (items == 1)
11950       {
11951         const ColorInfo
11952           **colorlist;
11953
11954         size_t
11955           colors;
11956
11957         colorlist=GetColorInfoList("*",&colors,exception);
11958         EXTEND(sp,colors);
11959         for (i=0; i < (ssize_t) colors; i++)
11960         {
11961           PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
11962         }
11963         colorlist=(const ColorInfo **)
11964           RelinquishMagickMemory((ColorInfo **) colorlist);
11965         goto PerlException;
11966       }
11967     EXTEND(sp,5*items);
11968     for (i=1; i < items; i++)
11969     {
11970       name=(char *) SvPV(ST(i),na);
11971       if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
11972         {
11973           PUSHs(&sv_undef);
11974           continue;
11975         }
11976       PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
11977       PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
11978       PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
11979       if (color.colorspace == CMYKColorspace)
11980         PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
11981       if (color.alpha_trait == BlendPixelTrait)
11982         PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
11983     }
11984
11985   PerlException:
11986     InheritPerlException(exception,perl_exception);
11987     exception=DestroyExceptionInfo(exception);
11988     SvREFCNT_dec(perl_exception);
11989   }
11990 \f
11991 #
11992 ###############################################################################
11993 #                                                                             #
11994 #                                                                             #
11995 #                                                                             #
11996 #   Q u e r y C o l o r N a m e                                               #
11997 #                                                                             #
11998 #                                                                             #
11999 #                                                                             #
12000 ###############################################################################
12001 #
12002 #
12003 void
12004 QueryColorname(ref,...)
12005   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
12006   ALIAS:
12007     querycolorname = 1
12008   PPCODE:
12009   {
12010     AV
12011       *av;
12012
12013     char
12014       message[MaxTextExtent];
12015
12016     ExceptionInfo
12017       *exception;
12018
12019     Image
12020       *image;
12021
12022     PixelInfo
12023       target_color;
12024
12025     register ssize_t
12026       i;
12027
12028     struct PackageInfo
12029       *info;
12030
12031     SV
12032       *perl_exception,
12033       *reference;  /* reference is the SV* of ref=SvIV(reference) */
12034
12035     PERL_UNUSED_VAR(ref);
12036     PERL_UNUSED_VAR(ix);
12037     exception=AcquireExceptionInfo();
12038     perl_exception=newSVpv("",0);
12039     reference=SvRV(ST(0));
12040     av=(AV *) reference;
12041     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12042       exception);
12043     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12044     if (image == (Image *) NULL)
12045       {
12046         ThrowPerlException(exception,OptionError,"NoImagesDefined",
12047           PackageName);
12048         goto PerlException;
12049       }
12050     EXTEND(sp,items);
12051     for (i=1; i < items; i++)
12052     {
12053       (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12054         exception);
12055       (void) QueryColorname(image,&target_color,SVGCompliance,message,
12056         exception);
12057       PUSHs(sv_2mortal(newSVpv(message,0)));
12058     }
12059
12060   PerlException:
12061     InheritPerlException(exception,perl_exception);
12062     exception=DestroyExceptionInfo(exception);
12063     SvREFCNT_dec(perl_exception);
12064   }
12065 \f
12066 #
12067 ###############################################################################
12068 #                                                                             #
12069 #                                                                             #
12070 #                                                                             #
12071 #   Q u e r y F o n t                                                         #
12072 #                                                                             #
12073 #                                                                             #
12074 #                                                                             #
12075 ###############################################################################
12076 #
12077 #
12078 void
12079 QueryFont(ref,...)
12080   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
12081   ALIAS:
12082     queryfont = 1
12083   PPCODE:
12084   {
12085     char
12086       *name,
12087       message[MaxTextExtent];
12088
12089     ExceptionInfo
12090       *exception;
12091
12092     register ssize_t
12093       i;
12094
12095     SV
12096       *perl_exception;
12097
12098     volatile const TypeInfo
12099       *type_info;
12100
12101     PERL_UNUSED_VAR(ref);
12102     PERL_UNUSED_VAR(ix);
12103     exception=AcquireExceptionInfo();
12104     perl_exception=newSVpv("",0);
12105     if (items == 1)
12106       {
12107         const TypeInfo
12108           **typelist;
12109
12110         size_t
12111           types;
12112
12113         typelist=GetTypeInfoList("*",&types,exception);
12114         EXTEND(sp,types);
12115         for (i=0; i < (ssize_t) types; i++)
12116         {
12117           PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12118         }
12119         typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12120           typelist);
12121         goto PerlException;
12122       }
12123     EXTEND(sp,10*items);
12124     for (i=1; i < items; i++)
12125     {
12126       name=(char *) SvPV(ST(i),na);
12127       type_info=GetTypeInfo(name,exception);
12128       if (type_info == (TypeInfo *) NULL)
12129         {
12130           PUSHs(&sv_undef);
12131           continue;
12132         }
12133       if (type_info->name == (char *) NULL)
12134         PUSHs(&sv_undef);
12135       else
12136         PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12137       if (type_info->description == (char *) NULL)
12138         PUSHs(&sv_undef);
12139       else
12140         PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12141       if (type_info->family == (char *) NULL)
12142         PUSHs(&sv_undef);
12143       else
12144         PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12145       if (type_info->style == UndefinedStyle)
12146         PUSHs(&sv_undef);
12147       else
12148         PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12149           type_info->style),0)));
12150       if (type_info->stretch == UndefinedStretch)
12151         PUSHs(&sv_undef);
12152       else
12153         PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12154           type_info->stretch),0)));
12155       (void) FormatLocaleString(message,MaxTextExtent,"%.20g",(double)
12156         type_info->weight);
12157       PUSHs(sv_2mortal(newSVpv(message,0)));
12158       if (type_info->encoding == (char *) NULL)
12159         PUSHs(&sv_undef);
12160       else
12161         PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12162       if (type_info->foundry == (char *) NULL)
12163         PUSHs(&sv_undef);
12164       else
12165         PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12166       if (type_info->format == (char *) NULL)
12167         PUSHs(&sv_undef);
12168       else
12169         PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12170       if (type_info->metrics == (char *) NULL)
12171         PUSHs(&sv_undef);
12172       else
12173         PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12174       if (type_info->glyphs == (char *) NULL)
12175         PUSHs(&sv_undef);
12176       else
12177         PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12178     }
12179
12180   PerlException:
12181     InheritPerlException(exception,perl_exception);
12182     exception=DestroyExceptionInfo(exception);
12183     SvREFCNT_dec(perl_exception);
12184   }
12185 \f
12186 #
12187 ###############################################################################
12188 #                                                                             #
12189 #                                                                             #
12190 #                                                                             #
12191 #   Q u e r y F o n t M e t r i c s                                           #
12192 #                                                                             #
12193 #                                                                             #
12194 #                                                                             #
12195 ###############################################################################
12196 #
12197 #
12198 void
12199 QueryFontMetrics(ref,...)
12200   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
12201   ALIAS:
12202     queryfontmetrics = 1
12203   PPCODE:
12204   {
12205     AffineMatrix
12206       affine,
12207       current;
12208
12209     AV
12210       *av;
12211
12212     char
12213       *attribute;
12214
12215     double
12216       x,
12217       y;
12218
12219     DrawInfo
12220       *draw_info;
12221
12222     ExceptionInfo
12223       *exception;
12224
12225     GeometryInfo
12226       geometry_info;
12227
12228     Image
12229       *image;
12230
12231     MagickBooleanType
12232       status;
12233
12234     MagickStatusType
12235       flags;
12236
12237     register ssize_t
12238       i;
12239
12240     ssize_t
12241       type;
12242
12243     struct PackageInfo
12244       *info,
12245       *package_info;
12246
12247     SV
12248       *perl_exception,
12249       *reference;  /* reference is the SV* of ref=SvIV(reference) */
12250
12251     TypeMetric
12252       metrics;
12253
12254     PERL_UNUSED_VAR(ref);
12255     PERL_UNUSED_VAR(ix);
12256     exception=AcquireExceptionInfo();
12257     package_info=(struct PackageInfo *) NULL;
12258     perl_exception=newSVpv("",0);
12259     reference=SvRV(ST(0));
12260     av=(AV *) reference;
12261     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12262       exception);
12263     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12264     if (image == (Image *) NULL)
12265       {
12266         ThrowPerlException(exception,OptionError,"NoImagesDefined",
12267           PackageName);
12268         goto PerlException;
12269       }
12270     package_info=ClonePackageInfo(info,exception);
12271     draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12272     CloneString(&draw_info->text,"");
12273     current=draw_info->affine;
12274     GetAffineMatrix(&affine);
12275     x=0.0;
12276     y=0.0;
12277     EXTEND(sp,7*items);
12278     for (i=2; i < items; i+=2)
12279     {
12280       attribute=(char *) SvPV(ST(i-1),na);
12281       switch (*attribute)
12282       {
12283         case 'A':
12284         case 'a':
12285         {
12286           if (LocaleCompare(attribute,"antialias") == 0)
12287             {
12288               type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12289                 SvPV(ST(i),na));
12290               if (type < 0)
12291                 {
12292                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
12293                     SvPV(ST(i),na));
12294                   break;
12295                 }
12296               draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12297               break;
12298             }
12299           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12300             attribute);
12301           break;
12302         }
12303         case 'd':
12304         case 'D':
12305         {
12306           if (LocaleCompare(attribute,"density") == 0)
12307             {
12308               CloneString(&draw_info->density,SvPV(ST(i),na));
12309               break;
12310             }
12311           if (LocaleCompare(attribute,"direction") == 0)
12312             {
12313               draw_info->direction=(DirectionType) ParseCommandOption(
12314                 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12315               break;
12316             }
12317           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12318             attribute);
12319           break;
12320         }
12321         case 'e':
12322         case 'E':
12323         {
12324           if (LocaleCompare(attribute,"encoding") == 0)
12325             {
12326               CloneString(&draw_info->encoding,SvPV(ST(i),na));
12327               break;
12328             }
12329           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12330             attribute);
12331           break;
12332         }
12333         case 'f':
12334         case 'F':
12335         {
12336           if (LocaleCompare(attribute,"family") == 0)
12337             {
12338               CloneString(&draw_info->family,SvPV(ST(i),na));
12339               break;
12340             }
12341           if (LocaleCompare(attribute,"fill") == 0)
12342             {
12343               if (info)
12344                 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12345                   &draw_info->fill,exception);
12346               break;
12347             }
12348           if (LocaleCompare(attribute,"font") == 0)
12349             {
12350               CloneString(&draw_info->font,SvPV(ST(i),na));
12351               break;
12352             }
12353           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12354             attribute);
12355           break;
12356         }
12357         case 'g':
12358         case 'G':
12359         {
12360           if (LocaleCompare(attribute,"geometry") == 0)
12361             {
12362               CloneString(&draw_info->geometry,SvPV(ST(i),na));
12363               break;
12364             }
12365           if (LocaleCompare(attribute,"gravity") == 0)
12366             {
12367               draw_info->gravity=(GravityType) ParseCommandOption(
12368                 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12369               break;
12370             }
12371           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12372             attribute);
12373           break;
12374         }
12375         case 'i':
12376         case 'I':
12377         {
12378           if (LocaleCompare(attribute,"interline-spacing") == 0)
12379             {
12380               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12381               draw_info->interline_spacing=geometry_info.rho;
12382               break;
12383             }
12384           if (LocaleCompare(attribute,"interword-spacing") == 0)
12385             {
12386               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12387               draw_info->interword_spacing=geometry_info.rho;
12388               break;
12389             }
12390           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12391             attribute);
12392           break;
12393         }
12394         case 'k':
12395         case 'K':
12396         {
12397           if (LocaleCompare(attribute,"kerning") == 0)
12398             {
12399               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12400               draw_info->kerning=geometry_info.rho;
12401               break;
12402             }
12403           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12404             attribute);
12405           break;
12406         }
12407         case 'p':
12408         case 'P':
12409         {
12410           if (LocaleCompare(attribute,"pointsize") == 0)
12411             {
12412               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12413               draw_info->pointsize=geometry_info.rho;
12414               break;
12415             }
12416           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12417             attribute);
12418           break;
12419         }
12420         case 'r':
12421         case 'R':
12422         {
12423           if (LocaleCompare(attribute,"rotate") == 0)
12424             {
12425               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12426               affine.rx=geometry_info.rho;
12427               affine.ry=geometry_info.sigma;
12428               if ((flags & SigmaValue) == 0)
12429                 affine.ry=affine.rx;
12430               break;
12431             }
12432           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12433             attribute);
12434           break;
12435         }
12436         case 's':
12437         case 'S':
12438         {
12439           if (LocaleCompare(attribute,"scale") == 0)
12440             {
12441               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12442               affine.sx=geometry_info.rho;
12443               affine.sy=geometry_info.sigma;
12444               if ((flags & SigmaValue) == 0)
12445                 affine.sy=affine.sx;
12446               break;
12447             }
12448           if (LocaleCompare(attribute,"skew") == 0)
12449             {
12450               double
12451                 x_angle,
12452                 y_angle;
12453
12454               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12455               x_angle=geometry_info.rho;
12456               y_angle=geometry_info.sigma;
12457               if ((flags & SigmaValue) == 0)
12458                 y_angle=x_angle;
12459               affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12460               affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12461               break;
12462             }
12463           if (LocaleCompare(attribute,"stroke") == 0)
12464             {
12465               if (info)
12466                 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12467                   &draw_info->stroke,exception);
12468               break;
12469             }
12470           if (LocaleCompare(attribute,"style") == 0)
12471             {
12472               type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12473                 SvPV(ST(i),na));
12474               if (type < 0)
12475                 {
12476                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
12477                     SvPV(ST(i),na));
12478                   break;
12479                 }
12480               draw_info->style=(StyleType) type;
12481               break;
12482             }
12483           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12484             attribute);
12485           break;
12486         }
12487         case 't':
12488         case 'T':
12489         {
12490           if (LocaleCompare(attribute,"text") == 0)
12491             {
12492               CloneString(&draw_info->text,SvPV(ST(i),na));
12493               break;
12494             }
12495           if (LocaleCompare(attribute,"translate") == 0)
12496             {
12497               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12498               affine.tx=geometry_info.rho;
12499               affine.ty=geometry_info.sigma;
12500               if ((flags & SigmaValue) == 0)
12501                 affine.ty=affine.tx;
12502               break;
12503             }
12504           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12505             attribute);
12506           break;
12507         }
12508         case 'w':
12509         case 'W':
12510         {
12511           if (LocaleCompare(attribute,"weight") == 0)
12512             {
12513               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12514               draw_info->weight=(size_t) geometry_info.rho;
12515               break;
12516             }
12517           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12518             attribute);
12519           break;
12520         }
12521         case 'x':
12522         case 'X':
12523         {
12524           if (LocaleCompare(attribute,"x") == 0)
12525             {
12526               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12527               x=geometry_info.rho;
12528               break;
12529             }
12530           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12531             attribute);
12532           break;
12533         }
12534         case 'y':
12535         case 'Y':
12536         {
12537           if (LocaleCompare(attribute,"y") == 0)
12538             {
12539               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12540               y=geometry_info.rho;
12541               break;
12542             }
12543           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12544             attribute);
12545           break;
12546         }
12547         default:
12548         {
12549           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12550             attribute);
12551           break;
12552         }
12553       }
12554     }
12555     draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
12556     draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
12557     draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
12558     draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
12559     draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
12560     draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
12561     if (draw_info->geometry == (char *) NULL)
12562       {
12563         draw_info->geometry=AcquireString((char *) NULL);
12564         (void) FormatLocaleString(draw_info->geometry,MaxTextExtent,
12565           "%.15g,%.15g",x,y);
12566       }
12567     status=GetTypeMetrics(image,draw_info,&metrics,exception);
12568     (void) CatchImageException(image);
12569     if (status == MagickFalse)
12570       PUSHs(&sv_undef);
12571     else
12572       {
12573         PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
12574         PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
12575         PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
12576         PUSHs(sv_2mortal(newSVnv(metrics.descent)));
12577         PUSHs(sv_2mortal(newSVnv(metrics.width)));
12578         PUSHs(sv_2mortal(newSVnv(metrics.height)));
12579         PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
12580         PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
12581         PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
12582         PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
12583         PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
12584         PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
12585         PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
12586       }
12587     draw_info=DestroyDrawInfo(draw_info);
12588
12589   PerlException:
12590     if (package_info != (struct PackageInfo *) NULL)
12591       DestroyPackageInfo(package_info);
12592     InheritPerlException(exception,perl_exception);
12593     exception=DestroyExceptionInfo(exception);
12594     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
12595   }
12596 \f
12597 #
12598 ###############################################################################
12599 #                                                                             #
12600 #                                                                             #
12601 #                                                                             #
12602 #   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                         #
12603 #                                                                             #
12604 #                                                                             #
12605 #                                                                             #
12606 ###############################################################################
12607 #
12608 #
12609 void
12610 QueryMultilineFontMetrics(ref,...)
12611   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
12612   ALIAS:
12613     querymultilinefontmetrics = 1
12614   PPCODE:
12615   {
12616     AffineMatrix
12617       affine,
12618       current;
12619
12620     AV
12621       *av;
12622
12623     char
12624       *attribute;
12625
12626     double
12627       x,
12628       y;
12629
12630     DrawInfo
12631       *draw_info;
12632
12633     ExceptionInfo
12634       *exception;
12635
12636     GeometryInfo
12637       geometry_info;
12638
12639     Image
12640       *image;
12641
12642     MagickBooleanType
12643       status;
12644
12645     MagickStatusType
12646       flags;
12647
12648     register ssize_t
12649       i;
12650
12651     ssize_t
12652       type;
12653
12654     struct PackageInfo
12655       *info,
12656       *package_info;
12657
12658     SV
12659       *perl_exception,
12660       *reference;  /* reference is the SV* of ref=SvIV(reference) */
12661
12662     TypeMetric
12663       metrics;
12664
12665     PERL_UNUSED_VAR(ref);
12666     PERL_UNUSED_VAR(ix);
12667     exception=AcquireExceptionInfo();
12668     package_info=(struct PackageInfo *) NULL;
12669     perl_exception=newSVpv("",0);
12670     reference=SvRV(ST(0));
12671     av=(AV *) reference;
12672     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12673       exception);
12674     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12675     if (image == (Image *) NULL)
12676       {
12677         ThrowPerlException(exception,OptionError,"NoImagesDefined",
12678           PackageName);
12679         goto PerlException;
12680       }
12681     package_info=ClonePackageInfo(info,exception);
12682     draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12683     CloneString(&draw_info->text,"");
12684     current=draw_info->affine;
12685     GetAffineMatrix(&affine);
12686     x=0.0;
12687     y=0.0;
12688     EXTEND(sp,7*items);
12689     for (i=2; i < items; i+=2)
12690     {
12691       attribute=(char *) SvPV(ST(i-1),na);
12692       switch (*attribute)
12693       {
12694         case 'A':
12695         case 'a':
12696         {
12697           if (LocaleCompare(attribute,"antialias") == 0)
12698             {
12699               type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12700                 SvPV(ST(i),na));
12701               if (type < 0)
12702                 {
12703                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
12704                     SvPV(ST(i),na));
12705                   break;
12706                 }
12707               draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12708               break;
12709             }
12710           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12711             attribute);
12712           break;
12713         }
12714         case 'd':
12715         case 'D':
12716         {
12717           if (LocaleCompare(attribute,"density") == 0)
12718             {
12719               CloneString(&draw_info->density,SvPV(ST(i),na));
12720               break;
12721             }
12722           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12723             attribute);
12724           break;
12725         }
12726         case 'e':
12727         case 'E':
12728         {
12729           if (LocaleCompare(attribute,"encoding") == 0)
12730             {
12731               CloneString(&draw_info->encoding,SvPV(ST(i),na));
12732               break;
12733             }
12734           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12735             attribute);
12736           break;
12737         }
12738         case 'f':
12739         case 'F':
12740         {
12741           if (LocaleCompare(attribute,"family") == 0)
12742             {
12743               CloneString(&draw_info->family,SvPV(ST(i),na));
12744               break;
12745             }
12746           if (LocaleCompare(attribute,"fill") == 0)
12747             {
12748               if (info)
12749                 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12750                   &draw_info->fill,exception);
12751               break;
12752             }
12753           if (LocaleCompare(attribute,"font") == 0)
12754             {
12755               CloneString(&draw_info->font,SvPV(ST(i),na));
12756               break;
12757             }
12758           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12759             attribute);
12760           break;
12761         }
12762         case 'g':
12763         case 'G':
12764         {
12765           if (LocaleCompare(attribute,"geometry") == 0)
12766             {
12767               CloneString(&draw_info->geometry,SvPV(ST(i),na));
12768               break;
12769             }
12770           if (LocaleCompare(attribute,"gravity") == 0)
12771             {
12772               draw_info->gravity=(GravityType) ParseCommandOption(
12773                 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12774               break;
12775             }
12776           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12777             attribute);
12778           break;
12779         }
12780         case 'p':
12781         case 'P':
12782         {
12783           if (LocaleCompare(attribute,"pointsize") == 0)
12784             {
12785               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12786               draw_info->pointsize=geometry_info.rho;
12787               break;
12788             }
12789           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12790             attribute);
12791           break;
12792         }
12793         case 'r':
12794         case 'R':
12795         {
12796           if (LocaleCompare(attribute,"rotate") == 0)
12797             {
12798               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12799               affine.rx=geometry_info.rho;
12800               affine.ry=geometry_info.sigma;
12801               if ((flags & SigmaValue) == 0)
12802                 affine.ry=affine.rx;
12803               break;
12804             }
12805           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12806             attribute);
12807           break;
12808         }
12809         case 's':
12810         case 'S':
12811         {
12812           if (LocaleCompare(attribute,"scale") == 0)
12813             {
12814               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12815               affine.sx=geometry_info.rho;
12816               affine.sy=geometry_info.sigma;
12817               if ((flags & SigmaValue) == 0)
12818                 affine.sy=affine.sx;
12819               break;
12820             }
12821           if (LocaleCompare(attribute,"skew") == 0)
12822             {
12823               double
12824                 x_angle,
12825                 y_angle;
12826
12827               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12828               x_angle=geometry_info.rho;
12829               y_angle=geometry_info.sigma;
12830               if ((flags & SigmaValue) == 0)
12831                 y_angle=x_angle;
12832               affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12833               affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12834               break;
12835             }
12836           if (LocaleCompare(attribute,"stroke") == 0)
12837             {
12838               if (info)
12839                 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12840                   &draw_info->stroke,exception);
12841               break;
12842             }
12843           if (LocaleCompare(attribute,"style") == 0)
12844             {
12845               type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12846                 SvPV(ST(i),na));
12847               if (type < 0)
12848                 {
12849                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
12850                     SvPV(ST(i),na));
12851                   break;
12852                 }
12853               draw_info->style=(StyleType) type;
12854               break;
12855             }
12856           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12857             attribute);
12858           break;
12859         }
12860         case 't':
12861         case 'T':
12862         {
12863           if (LocaleCompare(attribute,"text") == 0)
12864             {
12865               CloneString(&draw_info->text,SvPV(ST(i),na));
12866               break;
12867             }
12868           if (LocaleCompare(attribute,"translate") == 0)
12869             {
12870               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12871               affine.tx=geometry_info.rho;
12872               affine.ty=geometry_info.sigma;
12873               if ((flags & SigmaValue) == 0)
12874                 affine.ty=affine.tx;
12875               break;
12876             }
12877           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12878             attribute);
12879           break;
12880         }
12881         case 'w':
12882         case 'W':
12883         {
12884           if (LocaleCompare(attribute,"weight") == 0)
12885             {
12886               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12887               draw_info->weight=(size_t) geometry_info.rho;
12888               break;
12889             }
12890           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12891             attribute);
12892           break;
12893         }
12894         case 'x':
12895         case 'X':
12896         {
12897           if (LocaleCompare(attribute,"x") == 0)
12898             {
12899               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12900               x=geometry_info.rho;
12901               break;
12902             }
12903           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12904             attribute);
12905           break;
12906         }
12907         case 'y':
12908         case 'Y':
12909         {
12910           if (LocaleCompare(attribute,"y") == 0)
12911             {
12912               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12913               y=geometry_info.rho;
12914               break;
12915             }
12916           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12917             attribute);
12918           break;
12919         }
12920         default:
12921         {
12922           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12923             attribute);
12924           break;
12925         }
12926       }
12927     }
12928     draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
12929     draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
12930     draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
12931     draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
12932     draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
12933     draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
12934     if (draw_info->geometry == (char *) NULL)
12935       {
12936         draw_info->geometry=AcquireString((char *) NULL);
12937         (void) FormatLocaleString(draw_info->geometry,MaxTextExtent,
12938           "%.15g,%.15g",x,y);
12939       }
12940     status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
12941     (void) CatchException(exception);
12942     if (status == MagickFalse)
12943       PUSHs(&sv_undef);
12944     else
12945       {
12946         PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
12947         PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
12948         PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
12949         PUSHs(sv_2mortal(newSVnv(metrics.descent)));
12950         PUSHs(sv_2mortal(newSVnv(metrics.width)));
12951         PUSHs(sv_2mortal(newSVnv(metrics.height)));
12952         PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
12953         PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
12954         PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
12955         PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
12956         PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
12957         PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
12958         PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
12959       }
12960     draw_info=DestroyDrawInfo(draw_info);
12961
12962   PerlException:
12963     if (package_info != (struct PackageInfo *) NULL)
12964       DestroyPackageInfo(package_info);
12965     InheritPerlException(exception,perl_exception);
12966     exception=DestroyExceptionInfo(exception);
12967     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
12968   }
12969 \f
12970 #
12971 ###############################################################################
12972 #                                                                             #
12973 #                                                                             #
12974 #                                                                             #
12975 #   Q u e r y F o r m a t                                                     #
12976 #                                                                             #
12977 #                                                                             #
12978 #                                                                             #
12979 ###############################################################################
12980 #
12981 #
12982 void
12983 QueryFormat(ref,...)
12984   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
12985   ALIAS:
12986     queryformat = 1
12987   PPCODE:
12988   {
12989     char
12990       *name;
12991
12992     ExceptionInfo
12993       *exception;
12994
12995     register ssize_t
12996       i;
12997
12998     SV
12999       *perl_exception;
13000
13001     volatile const MagickInfo
13002       *magick_info;
13003
13004     PERL_UNUSED_VAR(ref);
13005     PERL_UNUSED_VAR(ix);
13006     exception=AcquireExceptionInfo();
13007     perl_exception=newSVpv("",0);
13008     if (items == 1)
13009       {
13010         char
13011           format[MaxTextExtent];
13012
13013         const MagickInfo
13014           **format_list;
13015
13016         size_t
13017           types;
13018
13019         format_list=GetMagickInfoList("*",&types,exception);
13020         EXTEND(sp,types);
13021         for (i=0; i < (ssize_t) types; i++)
13022         {
13023           (void) CopyMagickString(format,format_list[i]->name,MaxTextExtent);
13024           LocaleLower(format);
13025           PUSHs(sv_2mortal(newSVpv(format,0)));
13026         }
13027         format_list=(const MagickInfo **)
13028           RelinquishMagickMemory((MagickInfo *) format_list);
13029         goto PerlException;
13030       }
13031     EXTEND(sp,8*items);
13032     for (i=1; i < items; i++)
13033     {
13034       name=(char *) SvPV(ST(i),na);
13035       magick_info=GetMagickInfo(name,exception);
13036       if (magick_info == (const MagickInfo *) NULL)
13037         {
13038           PUSHs(&sv_undef);
13039           continue;
13040         }
13041       PUSHs(sv_2mortal(newSViv(magick_info->adjoin)));
13042       PUSHs(sv_2mortal(newSViv(magick_info->blob_support)));
13043       PUSHs(sv_2mortal(newSViv(magick_info->raw)));
13044       PUSHs(sv_2mortal(newSViv((long) magick_info->decoder)));
13045       PUSHs(sv_2mortal(newSViv((long) magick_info->encoder)));
13046       if (magick_info->description == (char *) NULL)
13047         PUSHs(&sv_undef);
13048       else
13049         PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13050       if (magick_info->module == (char *) NULL)
13051         PUSHs(&sv_undef);
13052       else
13053         PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
13054     }
13055
13056   PerlException:
13057     InheritPerlException(exception,perl_exception);
13058     exception=DestroyExceptionInfo(exception);
13059     SvREFCNT_dec(perl_exception);
13060   }
13061 \f
13062 #
13063 ###############################################################################
13064 #                                                                             #
13065 #                                                                             #
13066 #                                                                             #
13067 #   Q u e r y O p t i o n                                                     #
13068 #                                                                             #
13069 #                                                                             #
13070 #                                                                             #
13071 ###############################################################################
13072 #
13073 #
13074 void
13075 QueryOption(ref,...)
13076   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
13077   ALIAS:
13078     queryoption = 1
13079   PPCODE:
13080   {
13081     char
13082       **options;
13083
13084     ExceptionInfo
13085       *exception;
13086
13087     register ssize_t
13088       i;
13089
13090     ssize_t
13091       j,
13092       option;
13093
13094     SV
13095       *perl_exception;
13096
13097     PERL_UNUSED_VAR(ref);
13098     PERL_UNUSED_VAR(ix);
13099     exception=AcquireExceptionInfo();
13100     perl_exception=newSVpv("",0);
13101     EXTEND(sp,8*items);
13102     for (i=1; i < items; i++)
13103     {
13104       option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13105         SvPV(ST(i),na));
13106       options=GetCommandOptions((CommandOption) option);
13107       if (options == (char **) NULL)
13108         PUSHs(&sv_undef);
13109       else
13110         {
13111           for (j=0; options[j] != (char *) NULL; j++)
13112             PUSHs(sv_2mortal(newSVpv(options[j],0)));
13113           options=DestroyStringList(options);
13114         }
13115     }
13116
13117     InheritPerlException(exception,perl_exception);
13118     exception=DestroyExceptionInfo(exception);
13119     SvREFCNT_dec(perl_exception);
13120   }
13121 \f
13122 #
13123 ###############################################################################
13124 #                                                                             #
13125 #                                                                             #
13126 #                                                                             #
13127 #   R e a d                                                                   #
13128 #                                                                             #
13129 #                                                                             #
13130 #                                                                             #
13131 ###############################################################################
13132 #
13133 #
13134 void
13135 Read(ref,...)
13136   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
13137   ALIAS:
13138     ReadImage  = 1
13139     read       = 2
13140     readimage  = 3
13141   PPCODE:
13142   {
13143     AV
13144       *av;
13145
13146     char
13147       **keep,
13148       **list;
13149
13150     ExceptionInfo
13151       *exception;
13152
13153     HV
13154       *hv;
13155
13156     Image
13157       *image;
13158
13159     int
13160       n;
13161
13162     MagickBooleanType
13163       status;
13164
13165     register char
13166       **p;
13167
13168     register ssize_t
13169       i;
13170
13171     ssize_t
13172       ac,
13173       number_images;
13174
13175     STRLEN
13176       *length;
13177
13178     struct PackageInfo
13179       *info,
13180       *package_info;
13181
13182     SV
13183       *perl_exception,  /* Perl variable for storing messages */
13184       *reference,
13185       *rv,
13186       *sv;
13187
13188     PERL_UNUSED_VAR(ref);
13189     PERL_UNUSED_VAR(ix);
13190     exception=AcquireExceptionInfo();
13191     perl_exception=newSVpv("",0);
13192     sv=NULL;
13193     package_info=(struct PackageInfo *) NULL;
13194     number_images=0;
13195     ac=(items < 2) ? 1 : items-1;
13196     list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13197     keep=list;
13198     length=(STRLEN *) NULL;
13199     if (list == (char **) NULL)
13200       {
13201         ThrowPerlException(exception,ResourceLimitError,
13202           "MemoryAllocationFailed",PackageName);
13203         goto PerlException;
13204       }
13205     length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13206     if (length == (STRLEN *) NULL)
13207       {
13208         ThrowPerlException(exception,ResourceLimitError,
13209           "MemoryAllocationFailed",PackageName);
13210         goto PerlException;
13211       }
13212     if (sv_isobject(ST(0)) == 0)
13213       {
13214         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13215           PackageName);
13216         goto PerlException;
13217       }
13218     reference=SvRV(ST(0));
13219     hv=SvSTASH(reference);
13220     if (SvTYPE(reference) != SVt_PVAV)
13221       {
13222         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13223           PackageName);
13224         goto PerlException;
13225       }
13226     av=(AV *) reference;
13227     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13228       exception);
13229     package_info=ClonePackageInfo(info,exception);
13230     n=1;
13231     if (items <= 1)
13232       *list=(char *) (*package_info->image_info->filename ?
13233         package_info->image_info->filename : "XC:black");
13234     else
13235       for (n=0, i=0; i < ac; i++)
13236       {
13237         list[n]=(char *) SvPV(ST(i+1),length[n]);
13238         if ((items >= 3) && strEQcase(list[n],"blob"))
13239           {
13240             void
13241               *blob;
13242
13243             i++;
13244             blob=(void *) (SvPV(ST(i+1),length[n]));
13245             SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13246           }
13247         if ((items >= 3) && strEQcase(list[n],"filename"))
13248           continue;
13249         if ((items >= 3) && strEQcase(list[n],"file"))
13250           {
13251             FILE
13252               *file;
13253
13254             PerlIO
13255               *io_info;
13256
13257             i++;
13258             io_info=IoIFP(sv_2io(ST(i+1)));
13259             if (io_info == (PerlIO *) NULL)
13260               {
13261                 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13262                   PackageName);
13263                 continue;
13264               }
13265             file=PerlIO_findFILE(io_info);
13266             if (file == (FILE *) NULL)
13267               {
13268                 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13269                   PackageName);
13270                 continue;
13271               }
13272             SetImageInfoFile(package_info->image_info,file);
13273           }
13274         if ((items >= 3) && strEQcase(list[n],"magick"))
13275           continue;
13276         n++;
13277       }
13278     list[n]=(char *) NULL;
13279     keep=list;
13280     status=ExpandFilenames(&n,&list);
13281     if (status == MagickFalse)
13282       {
13283         ThrowPerlException(exception,ResourceLimitError,
13284           "MemoryAllocationFailed",PackageName);
13285         goto PerlException;
13286       }
13287     number_images=0;
13288     for (i=0; i < n; i++)
13289     {
13290       if ((package_info->image_info->file == (FILE *) NULL) &&
13291           (package_info->image_info->blob == (void *) NULL))
13292         image=ReadImages(package_info->image_info,list[i],exception);
13293       else
13294         {
13295           image=ReadImages(package_info->image_info,
13296             package_info->image_info->filename,exception);
13297           if (image != (Image *) NULL)
13298             DisassociateImageStream(image);
13299         }
13300       if (image == (Image *) NULL)
13301         break;
13302       for ( ; image; image=image->next)
13303       {
13304         AddImageToRegistry(sv,image);
13305         rv=newRV(sv);
13306         av_push(av,sv_bless(rv,hv));
13307         SvREFCNT_dec(sv);
13308         number_images++;
13309       }
13310     }
13311     /*
13312       Free resources.
13313     */
13314     for (i=0; i < n; i++)
13315       if (list[i] != (char *) NULL)
13316         for (p=keep; list[i] != *p++; )
13317           if (*p == (char *) NULL)
13318             {
13319               list[i]=(char *) RelinquishMagickMemory(list[i]);
13320               break;
13321             }
13322
13323   PerlException:
13324     if (package_info != (struct PackageInfo *) NULL)
13325       DestroyPackageInfo(package_info);
13326     if (list && (list != keep))
13327       list=(char **) RelinquishMagickMemory(list);
13328     if (keep)
13329       keep=(char **) RelinquishMagickMemory(keep);
13330     if (length)
13331       length=(STRLEN *) RelinquishMagickMemory(length);
13332     InheritPerlException(exception,perl_exception);
13333     exception=DestroyExceptionInfo(exception);
13334     sv_setiv(perl_exception,(IV) number_images);
13335     SvPOK_on(perl_exception);
13336     ST(0)=sv_2mortal(perl_exception);
13337     XSRETURN(1);
13338   }
13339 \f
13340 #
13341 ###############################################################################
13342 #                                                                             #
13343 #                                                                             #
13344 #                                                                             #
13345 #   R e m o t e                                                               #
13346 #                                                                             #
13347 #                                                                             #
13348 #                                                                             #
13349 ###############################################################################
13350 #
13351 #
13352 void
13353 Remote(ref,...)
13354   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
13355   ALIAS:
13356     RemoteCommand  = 1
13357     remote         = 2
13358     remoteCommand  = 3
13359   PPCODE:
13360   {
13361     AV
13362       *av;
13363
13364     ExceptionInfo
13365       *exception;
13366
13367     register ssize_t
13368       i;
13369
13370     SV
13371       *perl_exception,
13372       *reference;
13373
13374     struct PackageInfo
13375       *info;
13376
13377     PERL_UNUSED_VAR(ref);
13378     PERL_UNUSED_VAR(ix);
13379     exception=AcquireExceptionInfo();
13380     perl_exception=newSVpv("",0);
13381     reference=SvRV(ST(0));
13382     av=(AV *) reference;
13383     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13384       exception);
13385     for (i=1; i < items; i++)
13386       (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13387         SvPV(ST(i),na),exception);
13388     InheritPerlException(exception,perl_exception);
13389     exception=DestroyExceptionInfo(exception);
13390     SvREFCNT_dec(perl_exception);    /* throw away all errors */
13391   }
13392 \f
13393 #
13394 ###############################################################################
13395 #                                                                             #
13396 #                                                                             #
13397 #                                                                             #
13398 #   S e t                                                                     #
13399 #                                                                             #
13400 #                                                                             #
13401 #                                                                             #
13402 ###############################################################################
13403 #
13404 #
13405 void
13406 Set(ref,...)
13407   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
13408   ALIAS:
13409     SetAttributes  = 1
13410     SetAttribute   = 2
13411     set            = 3
13412     setattributes  = 4
13413     setattribute   = 5
13414   PPCODE:
13415   {
13416     ExceptionInfo
13417       *exception;
13418
13419     Image
13420       *image;
13421
13422     register ssize_t
13423       i;
13424
13425     struct PackageInfo
13426       *info;
13427
13428     SV
13429       *perl_exception,
13430       *reference;  /* reference is the SV* of ref=SvIV(reference) */
13431
13432     PERL_UNUSED_VAR(ref);
13433     PERL_UNUSED_VAR(ix);
13434     exception=AcquireExceptionInfo();
13435     perl_exception=newSVpv("",0);
13436     if (sv_isobject(ST(0)) == 0)
13437       {
13438         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13439           PackageName);
13440         goto PerlException;
13441       }
13442     reference=SvRV(ST(0));
13443     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13444     if (items == 2)
13445       SetAttribute(aTHX_ info,image,"size",ST(1),exception);
13446     else
13447       for (i=2; i < items; i+=2)
13448         SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
13449
13450   PerlException:
13451     InheritPerlException(exception,perl_exception);
13452     exception=DestroyExceptionInfo(exception);
13453     sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
13454     SvPOK_on(perl_exception);
13455     ST(0)=sv_2mortal(perl_exception);
13456     XSRETURN(1);
13457   }
13458 \f
13459 #
13460 ###############################################################################
13461 #                                                                             #
13462 #                                                                             #
13463 #                                                                             #
13464 #   S e t P i x e l                                                           #
13465 #                                                                             #
13466 #                                                                             #
13467 #                                                                             #
13468 ###############################################################################
13469 #
13470 #
13471 void
13472 SetPixel(ref,...)
13473   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
13474   ALIAS:
13475     setpixel = 1
13476     setPixel = 2
13477   PPCODE:
13478   {
13479     AV
13480       *av;
13481
13482     char
13483       *attribute;
13484
13485     ChannelType
13486       channel,
13487       channel_mask;
13488
13489     ExceptionInfo
13490       *exception;
13491
13492     Image
13493       *image;
13494
13495     MagickBooleanType
13496       normalize;
13497
13498     RectangleInfo
13499       region;
13500
13501     register ssize_t
13502       i;
13503
13504     register Quantum
13505       *q;
13506
13507     ssize_t
13508       option;
13509
13510     struct PackageInfo
13511       *info;
13512
13513     SV
13514       *perl_exception,
13515       *reference;  /* reference is the SV* of ref=SvIV(reference) */
13516
13517     PERL_UNUSED_VAR(ref);
13518     PERL_UNUSED_VAR(ix);
13519     exception=AcquireExceptionInfo();
13520     perl_exception=newSVpv("",0);
13521     reference=SvRV(ST(0));
13522     av=(AV *) reference;
13523     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13524       exception);
13525     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13526     if (image == (Image *) NULL)
13527       {
13528         ThrowPerlException(exception,OptionError,"NoImagesDefined",
13529           PackageName);
13530         goto PerlException;
13531       }
13532     av=(AV *) NULL;
13533     normalize=MagickTrue;
13534     region.x=0;
13535     region.y=0;
13536     region.width=image->columns;
13537     region.height=1;
13538     if (items == 1)
13539       (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
13540     channel=DefaultChannels;
13541     for (i=2; i < items; i+=2)
13542     {
13543       attribute=(char *) SvPV(ST(i-1),na);
13544       switch (*attribute)
13545       {
13546         case 'C':
13547         case 'c':
13548         {
13549           if (LocaleCompare(attribute,"channel") == 0)
13550             {
13551               ssize_t
13552                 option;
13553
13554               option=ParseChannelOption(SvPV(ST(i),na));
13555               if (option < 0)
13556                 {
13557                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
13558                     SvPV(ST(i),na));
13559                   return;
13560                 }
13561               channel=(ChannelType) option;
13562               break;
13563             }
13564           if (LocaleCompare(attribute,"color") == 0)
13565             {
13566               if (SvTYPE(ST(i)) != SVt_RV)
13567                 {
13568                   char
13569                     message[MaxTextExtent];
13570
13571                   (void) FormatLocaleString(message,MaxTextExtent,
13572                     "invalid %.60s value",attribute);
13573                   ThrowPerlException(exception,OptionError,message,
13574                     SvPV(ST(i),na));
13575                 }
13576               av=(AV *) SvRV(ST(i));
13577               break;
13578             }
13579           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13580             attribute);
13581           break;
13582         }
13583         case 'g':
13584         case 'G':
13585         {
13586           if (LocaleCompare(attribute,"geometry") == 0)
13587             {
13588               (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
13589               break;
13590             }
13591           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13592             attribute);
13593           break;
13594         }
13595         case 'N':
13596         case 'n':
13597         {
13598           if (LocaleCompare(attribute,"normalize") == 0)
13599             {
13600               option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13601                 SvPV(ST(i),na));
13602               if (option < 0)
13603                 {
13604                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
13605                     SvPV(ST(i),na));
13606                   break;
13607                 }
13608              normalize=option != 0 ? MagickTrue : MagickFalse;
13609              break;
13610             }
13611           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13612             attribute);
13613           break;
13614         }
13615         case 'x':
13616         case 'X':
13617         {
13618           if (LocaleCompare(attribute,"x") == 0)
13619             {
13620               region.x=SvIV(ST(i));
13621               break;
13622             }
13623           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13624             attribute);
13625           break;
13626         }
13627         case 'y':
13628         case 'Y':
13629         {
13630           if (LocaleCompare(attribute,"y") == 0)
13631             {
13632               region.y=SvIV(ST(i));
13633               break;
13634             }
13635           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13636             attribute);
13637           break;
13638         }
13639         default:
13640         {
13641           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13642             attribute);
13643           break;
13644         }
13645       }
13646     }
13647     (void) SetImageStorageClass(image,DirectClass,exception);
13648     channel_mask=SetImageChannelMask(image,channel);
13649     q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
13650     if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
13651         (SvTYPE(av) != SVt_PVAV))
13652       PUSHs(&sv_undef);
13653     else
13654       {
13655         double
13656           scale;
13657
13658         register ssize_t
13659           i;
13660
13661         i=0;
13662         scale=1.0;
13663         if (normalize != MagickFalse)
13664           scale=QuantumRange;
13665         if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
13666             (i <= av_len(av)))
13667           {
13668             SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
13669               av_fetch(av,i,0)))),q);
13670             i++;
13671           }
13672         if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
13673             (i <= av_len(av)))
13674           {
13675             SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
13676               av_fetch(av,i,0)))),q);
13677             i++;
13678           }
13679         if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
13680             (i <= av_len(av)))
13681           {
13682             SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
13683               av_fetch(av,i,0)))),q);
13684             i++;
13685           }
13686         if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
13687             (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
13688           {
13689             SetPixelBlack(image,ClampToQuantum(scale*
13690               SvNV(*(av_fetch(av,i,0)))),q);
13691             i++;
13692           }
13693         if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
13694             (i <= av_len(av)))
13695           {
13696             SetPixelAlpha(image,ClampToQuantum(scale*
13697               SvNV(*(av_fetch(av,i,0)))),q);
13698             i++;
13699           }
13700         (void) SyncAuthenticPixels(image,exception);
13701       }
13702     (void) SetImageChannelMask(image,channel_mask);
13703
13704   PerlException:
13705     InheritPerlException(exception,perl_exception);
13706     exception=DestroyExceptionInfo(exception);
13707     SvREFCNT_dec(perl_exception);
13708   }
13709 \f
13710 #
13711 ###############################################################################
13712 #                                                                             #
13713 #                                                                             #
13714 #                                                                             #
13715 #   S m u s h                                                                 #
13716 #                                                                             #
13717 #                                                                             #
13718 #                                                                             #
13719 ###############################################################################
13720 #
13721 #
13722 void
13723 Smush(ref,...)
13724   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
13725   ALIAS:
13726     SmushImage  = 1
13727     smush       = 2
13728     smushimage  = 3
13729   PPCODE:
13730   {
13731     AV
13732       *av;
13733
13734     char
13735       *attribute;
13736
13737     ExceptionInfo
13738       *exception;
13739
13740     HV
13741       *hv;
13742
13743     Image
13744       *image;
13745
13746     register ssize_t
13747       i;
13748
13749     ssize_t
13750       offset,
13751       stack;
13752
13753     struct PackageInfo
13754       *info;
13755
13756     SV
13757       *av_reference,
13758       *perl_exception,
13759       *reference,
13760       *rv,
13761       *sv;
13762
13763     PERL_UNUSED_VAR(ref);
13764     PERL_UNUSED_VAR(ix);
13765     exception=AcquireExceptionInfo();
13766     perl_exception=newSVpv("",0);
13767     sv=NULL;
13768     attribute=NULL;
13769     av=NULL;
13770     if (sv_isobject(ST(0)) == 0)
13771       {
13772         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13773           PackageName);
13774         goto PerlException;
13775       }
13776     reference=SvRV(ST(0));
13777     hv=SvSTASH(reference);
13778     av=newAV();
13779     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
13780     SvREFCNT_dec(av);
13781     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13782     if (image == (Image *) NULL)
13783       {
13784         ThrowPerlException(exception,OptionError,"NoImagesDefined",
13785           PackageName);
13786         goto PerlException;
13787       }
13788     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
13789     /*
13790       Get options.
13791     */
13792     offset=0;
13793     stack=MagickTrue;
13794     for (i=2; i < items; i+=2)
13795     {
13796       attribute=(char *) SvPV(ST(i-1),na);
13797       switch (*attribute)
13798       {
13799         case 'O':
13800         case 'o':
13801         {
13802           if (LocaleCompare(attribute,"offset") == 0)
13803             {
13804               offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
13805               break;
13806             }
13807           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13808             attribute);
13809           break;
13810         }
13811         case 'S':
13812         case 's':
13813         {
13814           if (LocaleCompare(attribute,"stack") == 0)
13815             {
13816               stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13817                 SvPV(ST(i),na));
13818               if (stack < 0)
13819                 {
13820                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
13821                     SvPV(ST(i),na));
13822                   return;
13823                 }
13824               break;
13825             }
13826           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13827             attribute);
13828           break;
13829         }
13830         default:
13831         {
13832           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13833             attribute);
13834           break;
13835         }
13836       }
13837     }
13838     image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
13839       exception);
13840     if (image == (Image *) NULL)
13841       goto PerlException;
13842     for ( ; image; image=image->next)
13843     {
13844       AddImageToRegistry(sv,image);
13845       rv=newRV(sv);
13846       av_push(av,sv_bless(rv,hv));
13847       SvREFCNT_dec(sv);
13848     }
13849     exception=DestroyExceptionInfo(exception);
13850     ST(0)=av_reference;
13851     SvREFCNT_dec(perl_exception);
13852     XSRETURN(1);
13853
13854   PerlException:
13855     InheritPerlException(exception,perl_exception);
13856     exception=DestroyExceptionInfo(exception);
13857     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
13858     SvPOK_on(perl_exception);
13859     ST(0)=sv_2mortal(perl_exception);
13860     XSRETURN(1);
13861   }
13862 \f
13863 #
13864 ###############################################################################
13865 #                                                                             #
13866 #                                                                             #
13867 #                                                                             #
13868 #   S t a t i s t i c s                                                       #
13869 #                                                                             #
13870 #                                                                             #
13871 #                                                                             #
13872 ###############################################################################
13873 #
13874 #
13875 void
13876 Statistics(ref,...)
13877   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
13878   ALIAS:
13879     StatisticsImage = 1
13880     statistics      = 2
13881     statisticsimage = 3
13882   PPCODE:
13883   {
13884 #define ChannelStatistics(channel) \
13885 { \
13886   (void) FormatLocaleString(message,MaxTextExtent,"%.20g", \
13887     (double) channel_statistics[channel].depth); \
13888   PUSHs(sv_2mortal(newSVpv(message,0))); \
13889   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
13890     channel_statistics[channel].minima/scale); \
13891   PUSHs(sv_2mortal(newSVpv(message,0))); \
13892   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
13893     channel_statistics[channel].maxima/scale); \
13894   PUSHs(sv_2mortal(newSVpv(message,0))); \
13895   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
13896     channel_statistics[channel].mean/scale); \
13897   PUSHs(sv_2mortal(newSVpv(message,0))); \
13898   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
13899     channel_statistics[channel].standard_deviation/scale); \
13900   PUSHs(sv_2mortal(newSVpv(message,0))); \
13901   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
13902     channel_statistics[channel].kurtosis); \
13903   PUSHs(sv_2mortal(newSVpv(message,0))); \
13904   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
13905     channel_statistics[channel].skewness); \
13906   PUSHs(sv_2mortal(newSVpv(message,0))); \
13907 }
13908
13909     AV
13910       *av;
13911
13912     char
13913       message[MaxTextExtent];
13914
13915     ChannelStatistics
13916       *channel_statistics;
13917
13918     double
13919       scale;
13920
13921     ExceptionInfo
13922       *exception;
13923
13924     Image
13925       *image;
13926
13927     ssize_t
13928       count;
13929
13930     struct PackageInfo
13931       *info;
13932
13933     SV
13934       *perl_exception,
13935       *reference;
13936
13937     PERL_UNUSED_VAR(ref);
13938     PERL_UNUSED_VAR(ix);
13939     exception=AcquireExceptionInfo();
13940     perl_exception=newSVpv("",0);
13941     av=NULL;
13942     if (sv_isobject(ST(0)) == 0)
13943       {
13944         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13945           PackageName);
13946         goto PerlException;
13947       }
13948     reference=SvRV(ST(0));
13949     av=newAV();
13950     SvREFCNT_dec(av);
13951     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13952     if (image == (Image *) NULL)
13953       {
13954         ThrowPerlException(exception,OptionError,"NoImagesDefined",
13955           PackageName);
13956         goto PerlException;
13957       }
13958     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
13959     count=0;
13960     for ( ; image; image=image->next)
13961     {
13962       channel_statistics=GetImageStatistics(image,exception);
13963       if (channel_statistics == (ChannelStatistics *) NULL)
13964         continue;
13965       count++;
13966       EXTEND(sp,35*count);
13967       scale=(double) QuantumRange;
13968       ChannelStatistics(RedChannel);
13969       ChannelStatistics(GreenChannel);
13970       ChannelStatistics(BlueChannel);
13971       if (image->colorspace == CMYKColorspace)
13972         ChannelStatistics(BlackChannel);
13973       if (image->alpha_trait == BlendPixelTrait)
13974         ChannelStatistics(AlphaChannel);
13975       channel_statistics=(ChannelStatistics *)
13976         RelinquishMagickMemory(channel_statistics);
13977     }
13978
13979   PerlException:
13980     InheritPerlException(exception,perl_exception);
13981     exception=DestroyExceptionInfo(exception);
13982     SvREFCNT_dec(perl_exception);
13983   }
13984 \f
13985 #
13986 ###############################################################################
13987 #                                                                             #
13988 #                                                                             #
13989 #                                                                             #
13990 #   S y n c A u t h e n t i c P i x e l s                                     #
13991 #                                                                             #
13992 #                                                                             #
13993 #                                                                             #
13994 ###############################################################################
13995 #
13996 #
13997 void
13998 SyncAuthenticPixels(ref,...)
13999   Image::Magick::@MAGICK_ABI_SUFFIX@ ref = NO_INIT
14000   ALIAS:
14001     Syncauthenticpixels = 1
14002     SyncImagePixels = 2
14003     syncimagepixels = 3
14004   CODE:
14005   {
14006     ExceptionInfo
14007       *exception;
14008
14009     Image
14010       *image;
14011
14012     MagickBooleanType
14013       status;
14014
14015     struct PackageInfo
14016       *info;
14017
14018     SV
14019       *perl_exception,
14020       *reference;
14021
14022     PERL_UNUSED_VAR(ref);
14023     PERL_UNUSED_VAR(ix);
14024     exception=AcquireExceptionInfo();
14025     perl_exception=newSVpv("",0);
14026     if (sv_isobject(ST(0)) == 0)
14027       {
14028         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14029           PackageName);
14030         goto PerlException;
14031       }
14032
14033     reference=SvRV(ST(0));
14034     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14035     if (image == (Image *) NULL)
14036       {
14037         ThrowPerlException(exception,OptionError,"NoImagesDefined",
14038           PackageName);
14039         goto PerlException;
14040       }
14041
14042     status=SyncAuthenticPixels(image,exception);
14043     if (status != MagickFalse)
14044       return;
14045
14046   PerlException:
14047     InheritPerlException(exception,perl_exception);
14048     exception=DestroyExceptionInfo(exception);
14049     SvREFCNT_dec(perl_exception);  /* throw away all errors */
14050   }
14051 \f
14052 #
14053 ###############################################################################
14054 #                                                                             #
14055 #                                                                             #
14056 #                                                                             #
14057 #   T r a n s f o r m                                                         #
14058 #                                                                             #
14059 #                                                                             #
14060 #                                                                             #
14061 ###############################################################################
14062 #
14063 #
14064 void
14065 Transform(ref,...)
14066   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
14067   ALIAS:
14068     TransformImage = 1
14069     transform      = 2
14070     transformimage = 3
14071   PPCODE:
14072   {
14073     AV
14074       *av;
14075
14076     char
14077       *attribute,
14078       *crop_geometry,
14079       *geometry;
14080
14081     ExceptionInfo
14082       *exception;
14083
14084     HV
14085       *hv;
14086
14087     Image
14088       *clone,
14089       *image;
14090
14091     register ssize_t
14092       i;
14093
14094     struct PackageInfo
14095       *info;
14096
14097     SV
14098       *av_reference,
14099       *perl_exception,
14100       *reference,
14101       *rv,
14102       *sv;
14103
14104     PERL_UNUSED_VAR(ref);
14105     PERL_UNUSED_VAR(ix);
14106     exception=AcquireExceptionInfo();
14107     perl_exception=newSVpv("",0);
14108     sv=NULL;
14109     av=NULL;
14110     attribute=NULL;
14111     if (sv_isobject(ST(0)) == 0)
14112       {
14113         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14114           PackageName);
14115         goto PerlException;
14116       }
14117     reference=SvRV(ST(0));
14118     hv=SvSTASH(reference);
14119     av=newAV();
14120     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14121     SvREFCNT_dec(av);
14122     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14123     if (image == (Image *) NULL)
14124       {
14125         ThrowPerlException(exception,OptionError,"NoImagesDefined",
14126           PackageName);
14127         goto PerlException;
14128       }
14129     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14130     /*
14131       Get attribute.
14132     */
14133     crop_geometry=(char *) NULL;
14134     geometry=(char *) NULL;
14135     for (i=2; i < items; i+=2)
14136     {
14137       attribute=(char *) SvPV(ST(i-1),na);
14138       switch (*attribute)
14139       {
14140         case 'c':
14141         case 'C':
14142         {
14143           if (LocaleCompare(attribute,"crop") == 0)
14144             {
14145               crop_geometry=SvPV(ST(i),na);
14146               break;
14147             }
14148           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14149             attribute);
14150           break;
14151         }
14152         case 'g':
14153         case 'G':
14154         {
14155           if (LocaleCompare(attribute,"geometry") == 0)
14156             {
14157               geometry=SvPV(ST(i),na);
14158               break;
14159             }
14160           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14161             attribute);
14162           break;
14163         }
14164         default:
14165         {
14166           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14167             attribute);
14168           break;
14169         }
14170       }
14171     }
14172     for ( ; image; image=image->next)
14173     {
14174       clone=CloneImage(image,0,0,MagickTrue,exception);
14175       if (clone == (Image *) NULL)
14176         goto PerlException;
14177       TransformImage(&clone,crop_geometry,geometry,exception);
14178       for ( ; clone; clone=clone->next)
14179       {
14180         AddImageToRegistry(sv,clone);
14181         rv=newRV(sv);
14182         av_push(av,sv_bless(rv,hv));
14183         SvREFCNT_dec(sv);
14184       }
14185     }
14186     exception=DestroyExceptionInfo(exception);
14187     ST(0)=av_reference;
14188     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
14189     XSRETURN(1);
14190
14191   PerlException:
14192     InheritPerlException(exception,perl_exception);
14193     exception=DestroyExceptionInfo(exception);
14194     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14195     SvPOK_on(perl_exception);
14196     ST(0)=sv_2mortal(perl_exception);
14197     XSRETURN(1);
14198   }
14199 \f
14200 #
14201 ###############################################################################
14202 #                                                                             #
14203 #                                                                             #
14204 #                                                                             #
14205 #   W r i t e                                                                 #
14206 #                                                                             #
14207 #                                                                             #
14208 #                                                                             #
14209 ###############################################################################
14210 #
14211 #
14212 void
14213 Write(ref,...)
14214   Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
14215   ALIAS:
14216     WriteImage    = 1
14217     write         = 2
14218     writeimage    = 3
14219   PPCODE:
14220   {
14221     char
14222       filename[MaxTextExtent];
14223
14224     ExceptionInfo
14225       *exception;
14226
14227     Image
14228       *image,
14229       *next;
14230
14231     register ssize_t
14232       i;
14233
14234     ssize_t
14235       number_images,
14236       scene;
14237
14238     struct PackageInfo
14239       *info,
14240       *package_info;
14241
14242     SV
14243       *perl_exception,
14244       *reference;
14245
14246     PERL_UNUSED_VAR(ref);
14247     PERL_UNUSED_VAR(ix);
14248     exception=AcquireExceptionInfo();
14249     perl_exception=newSVpv("",0);
14250     number_images=0;
14251     package_info=(struct PackageInfo *) NULL;
14252     if (sv_isobject(ST(0)) == 0)
14253       {
14254         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14255           PackageName);
14256         goto PerlException;
14257       }
14258     reference=SvRV(ST(0));
14259     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14260     if (image == (Image *) NULL)
14261       {
14262         ThrowPerlException(exception,OptionError,"NoImagesDefined",
14263           PackageName);
14264         goto PerlException;
14265       }
14266     package_info=ClonePackageInfo(info,exception);
14267     if (items == 2)
14268       SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14269     else
14270       if (items > 2)
14271         for (i=2; i < items; i+=2)
14272           SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14273             exception);
14274     (void) CopyMagickString(filename,package_info->image_info->filename,
14275       MaxTextExtent);
14276     scene=0;
14277     for (next=image; next; next=next->next)
14278     {
14279       (void) CopyMagickString(next->filename,filename,MaxTextExtent);
14280       next->scene=scene++;
14281     }
14282     SetImageInfo(package_info->image_info,(unsigned int)
14283       GetImageListLength(image),exception);
14284     for (next=image; next; next=next->next)
14285     {
14286       (void) WriteImage(package_info->image_info,next,exception);
14287       number_images++;
14288       if (package_info->image_info->adjoin)
14289         break;
14290     }
14291
14292   PerlException:
14293     if (package_info != (struct PackageInfo *) NULL)
14294       DestroyPackageInfo(package_info);
14295     InheritPerlException(exception,perl_exception);
14296     exception=DestroyExceptionInfo(exception);
14297     sv_setiv(perl_exception,(IV) number_images);
14298     SvPOK_on(perl_exception);
14299     ST(0)=sv_2mortal(perl_exception);
14300     XSRETURN(1);
14301   }