]> granicus.if.org Git - imagemagick/blob - PerlMagick/quantum/quantum.xs
9aab0b5e8320cb12a317c0bfe8f6034c3fefce2e
[imagemagick] / PerlMagick / quantum / quantum.xs
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__Q16HDRI;  /* 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}, {"channel", MagickChannelOptions} } },
394     { "MotionBlur", { {"geometry", StringReference},
395       {"radius", RealReference}, {"sigma", RealReference},
396       {"angle", RealReference}, {"channel", MagickChannelOptions} } },
397     { "OrderedDither", { {"threshold", StringReference},
398       {"channel", MagickChannelOptions} } },
399     { "Shave", { {"geometry", StringReference}, {"width", IntegerReference},
400       {"height", IntegerReference} } },
401     { "Level", { {"levels", StringReference}, {"black-point", RealReference},
402       {"white-point", RealReference}, {"gamma", RealReference},
403       {"channel", MagickChannelOptions}, {"level", StringReference} } },
404     { "Clip", { {"id", StringReference}, {"inside", MagickBooleanOptions} } },
405     { "AffineTransform", { {"affine", ArrayReference},
406       {"translate", StringReference}, {"scale", StringReference},
407       {"rotate", RealReference}, {"skewX", RealReference},
408       {"skewY", RealReference}, {"interpolate", MagickInterpolateOptions},
409       {"background", StringReference} } },
410     { "Difference", { {"image", ImageReference}, {"fuzz", StringReference} } },
411     { "AdaptiveThreshold", { {"geometry", StringReference},
412       {"width", IntegerReference}, {"height", IntegerReference} } },
413     { "Resample", { {"density", StringReference}, {"x", RealReference},
414       {"y", RealReference}, {"filter", MagickFilterOptions},
415       {"support", RealReference } } },
416     { "Describe", { {"file", FileReference} } },
417     { "BlackThreshold", { {"threshold", StringReference},
418       {"channel", MagickChannelOptions} } },
419     { "WhiteThreshold", { {"threshold", StringReference},
420       {"channel", MagickChannelOptions} } },
421     { "RadialBlur", { {"geometry", StringReference}, {"angle", RealReference},
422       {"channel", MagickChannelOptions} } },
423     { "Thumbnail", { {"geometry", StringReference}, {"width", IntegerReference},
424       {"height", IntegerReference} } },
425     { "Strip", },
426     { "Tint", { {"fill", StringReference}, {"blend", StringReference} } },
427     { "Channel", { {"channel", MagickChannelOptions} } },
428     { "Splice", { {"geometry", StringReference}, {"width", IntegerReference},
429       {"height", IntegerReference}, {"x", IntegerReference},
430       {"y", IntegerReference}, {"fuzz", StringReference},
431       {"background", StringReference}, {"gravity", MagickGravityOptions} } },
432     { "Posterize", { {"levels", IntegerReference},
433       {"dither", MagickBooleanOptions} } },
434     { "Shadow", { {"geometry", StringReference}, {"alpha", RealReference},
435       {"sigma", RealReference}, {"x", IntegerReference},
436       {"y", IntegerReference} } },
437     { "Identify", { {"file", FileReference}, {"features", StringReference},
438       {"unique", MagickBooleanOptions} } },
439     { "SepiaTone", { {"threshold", RealReference} } },
440     { "SigmoidalContrast", { {"geometry", StringReference},
441       {"contrast", RealReference}, {"mid-point", RealReference},
442       {"channel", MagickChannelOptions}, {"sharpen", MagickBooleanOptions} } },
443     { "Extent", { {"geometry", StringReference}, {"width", IntegerReference},
444       {"height", IntegerReference}, {"x", IntegerReference},
445       {"y", IntegerReference}, {"fuzz", StringReference},
446       {"background", StringReference}, {"gravity", MagickGravityOptions} } },
447     { "Vignette", { {"geometry", StringReference}, {"radius", RealReference},
448       {"sigma", RealReference}, {"x", IntegerReference},
449       {"y", IntegerReference}, {"background", StringReference} } },
450     { "ContrastStretch", { {"levels", StringReference},
451       {"black-point", RealReference},{"white-point", RealReference},
452       {"channel", MagickChannelOptions} } },
453     { "Sans0", },
454     { "Sans1", },
455     { "AdaptiveSharpen", { {"geometry", StringReference},
456       {"radius", RealReference}, {"sigma", RealReference},
457       {"bias", RealReference}, {"channel", MagickChannelOptions} } },
458     { "Transpose", },
459     { "Transverse", },
460     { "AutoOrient", },
461     { "AdaptiveBlur", { {"geometry", StringReference},
462       {"radius", RealReference}, {"sigma", RealReference},
463       {"channel", MagickChannelOptions} } },
464     { "Sketch", { {"geometry", StringReference},
465       {"radius", RealReference}, {"sigma", RealReference},
466       {"angle", RealReference} } },
467     { "UniqueColors", },
468     { "AdaptiveResize", { {"geometry", StringReference},
469       {"width", IntegerReference}, {"height", IntegerReference},
470       {"filter", MagickFilterOptions}, {"support", StringReference },
471       {"blur", RealReference } } },
472     { "ClipMask", { {"mask", ImageReference} } },
473     { "LinearStretch", { {"levels", StringReference},
474       {"black-point", RealReference},{"white-point", RealReference} } },
475     { "ColorMatrix", { {"matrix", ArrayReference} } },
476     { "Mask", { {"mask", ImageReference} } },
477     { "Polaroid", { {"caption", StringReference}, {"angle", RealReference},
478       {"font", StringReference}, {"stroke", StringReference},
479       {"fill", StringReference}, {"strokewidth", RealReference},
480       {"pointsize", RealReference}, {"gravity", MagickGravityOptions},
481       {"background", StringReference},
482       {"interpolate", MagickInterpolateOptions} } },
483     { "FloodfillPaint", { {"geometry", StringReference},
484       {"x", IntegerReference}, {"y", IntegerReference},
485       {"fill", StringReference}, {"bordercolor", StringReference},
486       {"fuzz", StringReference}, {"channel", MagickChannelOptions},
487       {"invert", MagickBooleanOptions} } },
488     { "Distort", { {"points", ArrayReference}, {"method", MagickDistortOptions},
489       {"virtual-pixel", MagickVirtualPixelOptions},
490       {"best-fit", MagickBooleanOptions} } },
491     { "Clut", { {"image", ImageReference},
492       {"interpolate", MagickInterpolateOptions},
493       {"channel", MagickChannelOptions} } },
494     { "LiquidRescale", { {"geometry", StringReference},
495       {"width", IntegerReference}, {"height", IntegerReference},
496       {"delta-x", RealReference}, {"rigidity", RealReference } } },
497     { "Encipher", { {"passphrase", StringReference} } },
498     { "Decipher", { {"passphrase", StringReference} } },
499     { "Deskew", { {"geometry", StringReference},
500       {"threshold", StringReference} } },
501     { "Remap", { {"image", ImageReference},
502       {"dither-method", MagickDitherOptions} } },
503     { "SparseColor", { {"points", ArrayReference},
504       {"method", MagickSparseColorOptions},
505       {"virtual-pixel", MagickVirtualPixelOptions},
506       {"channel", MagickChannelOptions} } },
507     { "Function", { {"parameters", ArrayReference},
508       {"function", MagickFunctionOptions},
509       {"virtual-pixel", MagickVirtualPixelOptions} } },
510     { "SelectiveBlur", { {"geometry", StringReference},
511       {"radius", RealReference}, {"sigma", RealReference},
512       {"threshold", RealReference}, {"channel", MagickChannelOptions} } },
513     { "HaldClut", { {"image", ImageReference},
514       {"channel", MagickChannelOptions} } },
515     { "BlueShift", { {"factor", StringReference} } },
516     { "ForwardFourierTransform", { {"magnitude", MagickBooleanOptions} } },
517     { "InverseFourierTransform", { {"magnitude", MagickBooleanOptions} } },
518     { "ColorDecisionList", {
519       {"color-correction-collection", StringReference} } },
520     { "AutoGamma", { {"channel", MagickChannelOptions} } },
521     { "AutoLevel", { {"channel", MagickChannelOptions} } },
522     { "LevelColors", { {"invert", MagickBooleanOptions},
523       {"black-point", StringReference}, {"white-point", StringReference},
524       {"channel", MagickChannelOptions}, {"invert", MagickBooleanOptions} } },
525     { "Clamp", { {"channel", MagickChannelOptions} } },
526     { "BrightnessContrast", { {"levels", StringReference},
527       {"brightness", RealReference},{"contrast", RealReference},
528       {"channel", MagickChannelOptions} } },
529     { "Morphology", { {"kernel", StringReference},
530       {"channel", MagickChannelOptions}, {"method", MagickMorphologyOptions},
531       {"iterations", IntegerReference} } },
532     { "Sans", { {"matrix", ArrayReference} } },
533     { "Color", { {"color", StringReference} } },
534     { "Mode", { {"geometry", StringReference},
535       {"width", IntegerReference},{"height", IntegerReference},
536       {"channel", MagickChannelOptions} } },
537     { "Statistic", { {"geometry", StringReference},
538       {"width", IntegerReference},{"height", IntegerReference},
539       {"channel", MagickChannelOptions}, {"type", MagickStatisticOptions} } },
540     { "Perceptible", { {"epsilon", RealReference},
541       {"channel", MagickChannelOptions} } },
542     { "Poly", { {"terms", ArrayReference},
543       {"channel", MagickChannelOptions} } }
544   };
545
546 static SplayTreeInfo
547   *magick_registry = (SplayTreeInfo *) NULL;
548 \f
549 /*
550   Forward declarations.
551 */
552 static Image
553   *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
554
555 static ssize_t
556   strEQcase(const char *,const char *);
557 \f
558 /*
559 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
560 %                                                                             %
561 %                                                                             %
562 %                                                                             %
563 %   C l o n e P a c k a g e I n f o                                           %
564 %                                                                             %
565 %                                                                             %
566 %                                                                             %
567 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
568 %
569 %  ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
570 %  a new one.
571 %
572 %  The format of the ClonePackageInfo routine is:
573 %
574 %      struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
575 %        exception)
576 %
577 %  A description of each parameter follows:
578 %
579 %    o info: a structure of type info.
580 %
581 %    o exception: Return any errors or warnings in this structure.
582 %
583 */
584 static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
585   ExceptionInfo *exception)
586 {
587   struct PackageInfo
588     *clone_info;
589
590   clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
591   if (clone_info == (struct PackageInfo *) NULL)
592     {
593       ThrowPerlException(exception,ResourceLimitError,
594         "UnableToClonePackageInfo",PackageName);
595       return((struct PackageInfo *) NULL);
596     }
597   if (info == (struct PackageInfo *) NULL)
598     {
599       clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
600       return(clone_info);
601     }
602   *clone_info=(*info);
603   clone_info->image_info=CloneImageInfo(info->image_info);
604   return(clone_info);
605 }
606 \f
607 /*
608 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
609 %                                                                             %
610 %                                                                             %
611 %                                                                             %
612 %   c o n s t a n t                                                           %
613 %                                                                             %
614 %                                                                             %
615 %                                                                             %
616 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
617 %
618 %  constant() returns a double value for the specified name.
619 %
620 %  The format of the constant routine is:
621 %
622 %      double constant(char *name,ssize_t sans)
623 %
624 %  A description of each parameter follows:
625 %
626 %    o value: Method constant returns a double value for the specified name.
627 %
628 %    o name: The name of the constant.
629 %
630 %    o sans: This integer value is not used.
631 %
632 */
633 static double constant(char *name,ssize_t sans)
634 {
635   (void) sans;
636   errno=0;
637   switch (*name)
638   {
639     case 'B':
640     {
641       if (strEQ(name,"BlobError"))
642         return(BlobError);
643       if (strEQ(name,"BlobWarning"))
644         return(BlobWarning);
645       break;
646     }
647     case 'C':
648     {
649       if (strEQ(name,"CacheError"))
650         return(CacheError);
651       if (strEQ(name,"CacheWarning"))
652         return(CacheWarning);
653       if (strEQ(name,"CoderError"))
654         return(CoderError);
655       if (strEQ(name,"CoderWarning"))
656         return(CoderWarning);
657       if (strEQ(name,"ConfigureError"))
658         return(ConfigureError);
659       if (strEQ(name,"ConfigureWarning"))
660         return(ConfigureWarning);
661       if (strEQ(name,"CorruptImageError"))
662         return(CorruptImageError);
663       if (strEQ(name,"CorruptImageWarning"))
664         return(CorruptImageWarning);
665       break;
666     }
667     case 'D':
668     {
669       if (strEQ(name,"DelegateError"))
670         return(DelegateError);
671       if (strEQ(name,"DelegateWarning"))
672         return(DelegateWarning);
673       if (strEQ(name,"DrawError"))
674         return(DrawError);
675       if (strEQ(name,"DrawWarning"))
676         return(DrawWarning);
677       break;
678     }
679     case 'E':
680     {
681       if (strEQ(name,"ErrorException"))
682         return(ErrorException);
683       if (strEQ(name,"ExceptionError"))
684         return(CoderError);
685       if (strEQ(name,"ExceptionWarning"))
686         return(CoderWarning);
687       break;
688     }
689     case 'F':
690     {
691       if (strEQ(name,"FatalErrorException"))
692         return(FatalErrorException);
693       if (strEQ(name,"FileOpenError"))
694         return(FileOpenError);
695       if (strEQ(name,"FileOpenWarning"))
696         return(FileOpenWarning);
697       break;
698     }
699     case 'I':
700     {
701       if (strEQ(name,"ImageError"))
702         return(ImageError);
703       if (strEQ(name,"ImageWarning"))
704         return(ImageWarning);
705       break;
706     }
707     case 'M':
708     {
709       if (strEQ(name,"MaxRGB"))
710         return(QuantumRange);
711       if (strEQ(name,"MissingDelegateError"))
712         return(MissingDelegateError);
713       if (strEQ(name,"MissingDelegateWarning"))
714         return(MissingDelegateWarning);
715       if (strEQ(name,"ModuleError"))
716         return(ModuleError);
717       if (strEQ(name,"ModuleWarning"))
718         return(ModuleWarning);
719       break;
720     }
721     case 'O':
722     {
723       if (strEQ(name,"Opaque"))
724         return(OpaqueAlpha);
725       if (strEQ(name,"OptionError"))
726         return(OptionError);
727       if (strEQ(name,"OptionWarning"))
728         return(OptionWarning);
729       break;
730     }
731     case 'Q':
732     {
733       if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
734         return(MAGICKCORE_QUANTUM_DEPTH);
735       if (strEQ(name,"QuantumDepth"))
736         return(MAGICKCORE_QUANTUM_DEPTH);
737       if (strEQ(name,"QuantumRange"))
738         return(QuantumRange);
739       break;
740     }
741     case 'R':
742     {
743       if (strEQ(name,"ResourceLimitError"))
744         return(ResourceLimitError);
745       if (strEQ(name,"ResourceLimitWarning"))
746         return(ResourceLimitWarning);
747       if (strEQ(name,"RegistryError"))
748         return(RegistryError);
749       if (strEQ(name,"RegistryWarning"))
750         return(RegistryWarning);
751       break;
752     }
753     case 'S':
754     {
755       if (strEQ(name,"StreamError"))
756         return(StreamError);
757       if (strEQ(name,"StreamWarning"))
758         return(StreamWarning);
759       if (strEQ(name,"Success"))
760         return(0);
761       break;
762     }
763     case 'T':
764     {
765       if (strEQ(name,"Transparent"))
766         return(TransparentAlpha);
767       if (strEQ(name,"TypeError"))
768         return(TypeError);
769       if (strEQ(name,"TypeWarning"))
770         return(TypeWarning);
771       break;
772     }
773     case 'W':
774     {
775       if (strEQ(name,"WarningException"))
776         return(WarningException);
777       break;
778     }
779     case 'X':
780     {
781       if (strEQ(name,"XServerError"))
782         return(XServerError);
783       if (strEQ(name,"XServerWarning"))
784         return(XServerWarning);
785       break;
786     }
787   }
788   errno=EINVAL;
789   return(0);
790 }
791 \f
792 /*
793 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
794 %                                                                             %
795 %                                                                             %
796 %                                                                             %
797 %   D e s t r o y P a c k a g e I n f o                                       %
798 %                                                                             %
799 %                                                                             %
800 %                                                                             %
801 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
802 %
803 %  Method DestroyPackageInfo frees a previously created info structure.
804 %
805 %  The format of the DestroyPackageInfo routine is:
806 %
807 %      DestroyPackageInfo(struct PackageInfo *info)
808 %
809 %  A description of each parameter follows:
810 %
811 %    o info: a structure of type info.
812 %
813 */
814 static void DestroyPackageInfo(struct PackageInfo *info)
815 {
816   info->image_info=DestroyImageInfo(info->image_info);
817   info=(struct PackageInfo *) RelinquishMagickMemory(info);
818 }
819 \f
820 /*
821 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
822 %                                                                             %
823 %                                                                             %
824 %                                                                             %
825 %   G e t L i s t                                                             %
826 %                                                                             %
827 %                                                                             %
828 %                                                                             %
829 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
830 %
831 %  Method GetList is recursively called by SetupList to traverse the
832 %  Image__Magick reference.  If building an reference_vector (see SetupList),
833 %  *current is the current position in *reference_vector and *last is the final
834 %  entry in *reference_vector.
835 %
836 %  The format of the GetList routine is:
837 %
838 %      GetList(info)
839 %
840 %  A description of each parameter follows:
841 %
842 %    o info: a structure of type info.
843 %
844 */
845 static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
846   ssize_t *current,ssize_t *last,ExceptionInfo *exception)
847 {
848   Image
849     *image;
850
851   if (reference == (SV *) NULL)
852     return(NULL);
853   switch (SvTYPE(reference))
854   {
855     case SVt_PVAV:
856     {
857       AV
858         *av;
859
860       Image
861         *head,
862         *previous;
863
864       register ssize_t
865         i;
866
867       ssize_t
868         n;
869
870       /*
871         Array of images.
872       */
873       previous=(Image *) NULL;
874       head=(Image *) NULL;
875       av=(AV *) reference;
876       n=av_len(av);
877       for (i=0; i <= n; i++)
878       {
879         SV
880           **rv;
881
882         rv=av_fetch(av,i,0);
883         if (rv && *rv && sv_isobject(*rv))
884           {
885             image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
886               exception);
887             if (image == (Image *) NULL)
888               continue;
889             if (image == previous)
890               {
891                 image=CloneImage(image,0,0,MagickTrue,exception);
892                 if (image == (Image *) NULL)
893                   return(NULL);
894               }
895             image->previous=previous;
896             *(previous ? &previous->next : &head)=image;
897             for (previous=image; previous->next; previous=previous->next) ;
898           }
899       }
900       return(head);
901     }
902     case SVt_PVMG:
903     {
904       /*
905         Blessed scalar, one image.
906       */
907       image=INT2PTR(Image *,SvIV(reference));
908       if (image == (Image *) NULL)
909         return(NULL);
910       image->previous=(Image *) NULL;
911       image->next=(Image *) NULL;
912       if (reference_vector)
913         {
914           if (*current == *last)
915             {
916               *last+=256;
917               if (*reference_vector == (SV **) NULL)
918                 *reference_vector=(SV **) AcquireQuantumMemory(*last,
919                   sizeof(*reference_vector));
920               else
921                 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
922                   *last,sizeof(*reference_vector));
923             }
924           if (*reference_vector == (SV **) NULL)
925             {
926               ThrowPerlException(exception,ResourceLimitError,
927                 "MemoryAllocationFailed",PackageName);
928               return((Image *) NULL);
929             }
930           (*reference_vector)[*current]=reference;
931           (*reference_vector)[++(*current)]=NULL;
932         }
933       return(image);
934     }
935     default:
936       break;
937   }
938   (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
939     (double) SvTYPE(reference));
940   return((Image *) NULL);
941 }
942 \f
943 /*
944 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
945 %                                                                             %
946 %                                                                             %
947 %                                                                             %
948 %   G e t P a c k a g e I n f o                                               %
949 %                                                                             %
950 %                                                                             %
951 %                                                                             %
952 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
953 %
954 %  Method GetPackageInfo looks up or creates an info structure for the given
955 %  Image__Magick reference.  If it does create a new one, the information in
956 %  package_info is used to initialize it.
957 %
958 %  The format of the GetPackageInfo routine is:
959 %
960 %      struct PackageInfo *GetPackageInfo(void *reference,
961 %        struct PackageInfo *package_info,ExceptionInfo *exception)
962 %
963 %  A description of each parameter follows:
964 %
965 %    o info: a structure of type info.
966 %
967 %    o exception: Return any errors or warnings in this structure.
968 %
969 */
970 static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
971   struct PackageInfo *package_info,ExceptionInfo *exception)
972 {
973   char
974     message[MaxTextExtent];
975
976   struct PackageInfo
977     *clone_info;
978
979   SV
980     *sv;
981
982   (void) FormatLocaleString(message,MaxTextExtent,"%s::package%s%p",
983     PackageName,XS_VERSION,reference);
984   sv=perl_get_sv(message,(TRUE | 0x02));
985   if (sv == (SV *) NULL)
986     {
987       ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
988         message);
989       return(package_info);
990     }
991   if (SvREFCNT(sv) == 0)
992     (void) SvREFCNT_inc(sv);
993   if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
994     return(clone_info);
995   clone_info=ClonePackageInfo(package_info,exception);
996   sv_setiv(sv,PTR2IV(clone_info));
997   return(clone_info);
998 }
999 \f
1000 /*
1001 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1002 %                                                                             %
1003 %                                                                             %
1004 %                                                                             %
1005 %   S e t A t t r i b u t e                                                   %
1006 %                                                                             %
1007 %                                                                             %
1008 %                                                                             %
1009 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1010 %
1011 %  SetAttribute() sets the attribute to the value in sval.  This can change
1012 %  either or both of image or info.
1013 %
1014 %  The format of the SetAttribute routine is:
1015 %
1016 %      SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1017 %        SV *sval,ExceptionInfo *exception)
1018 %
1019 %  A description of each parameter follows:
1020 %
1021 %    o list: a list of strings.
1022 %
1023 %    o string: a character string.
1024 %
1025 */
1026
1027 static double SiPrefixToDoubleInterval(const char *string,const double interval)
1028 {
1029   char
1030     *q;
1031
1032   double
1033     value;
1034
1035   value=InterpretSiPrefixValue(string,&q);
1036   if (*q == '%')
1037     value*=interval/100.0;
1038   return(value);
1039 }
1040
1041 static inline double StringToDouble(const char *string,char **sentinal)
1042 {
1043   return(InterpretLocaleValue(string,sentinal));
1044 }
1045
1046 static double StringToDoubleInterval(const char *string,const double interval)
1047 {
1048   char
1049     *q;
1050
1051   double
1052     value;
1053
1054   value=InterpretLocaleValue(string,&q);
1055   if (*q == '%')
1056     value*=interval/100.0;
1057   return(value);
1058 }
1059
1060 static inline ssize_t StringToLong(const char *value)
1061 {
1062   return(strtol(value,(char **) NULL,10));
1063 }
1064
1065 static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1066   const char *attribute,SV *sval,ExceptionInfo *exception)
1067 {
1068   GeometryInfo
1069     geometry_info;
1070
1071   long
1072     x,
1073     y;
1074
1075   PixelInfo
1076     pixel;
1077
1078   MagickStatusType
1079     flags;
1080
1081   PixelInfo
1082     *color,
1083     target_color;
1084
1085   ssize_t
1086     sp;
1087
1088   switch (*attribute)
1089   {
1090     case 'A':
1091     case 'a':
1092     {
1093       if (LocaleCompare(attribute,"adjoin") == 0)
1094         {
1095           sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1096             SvPV(sval,na)) : SvIV(sval);
1097           if (sp < 0)
1098             {
1099               ThrowPerlException(exception,OptionError,"UnrecognizedType",
1100                 SvPV(sval,na));
1101               break;
1102             }
1103           if (info)
1104             info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1105           break;
1106         }
1107       if (LocaleCompare(attribute,"alpha") == 0)
1108         {
1109           sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1110             MagickFalse,SvPV(sval,na)) : SvIV(sval);
1111           if (sp < 0)
1112             {
1113               ThrowPerlException(exception,OptionError,"UnrecognizedType",
1114                 SvPV(sval,na));
1115               break;
1116             }
1117           for ( ; image; image=image->next)
1118             (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1119               exception);
1120           break;
1121         }
1122       if (LocaleCompare(attribute,"antialias") == 0)
1123         {
1124           sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1125             SvPV(sval,na)) : SvIV(sval);
1126           if (sp < 0)
1127             {
1128               ThrowPerlException(exception,OptionError,"UnrecognizedType",
1129                 SvPV(sval,na));
1130               break;
1131             }
1132           if (info)
1133             info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1134           break;
1135         }
1136       if (LocaleCompare(attribute,"area-limit") == 0)
1137         {
1138           MagickSizeType
1139             limit;
1140
1141           limit=MagickResourceInfinity;
1142           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1143             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1144               100.0);
1145           (void) SetMagickResourceLimit(AreaResource,limit);
1146           break;
1147         }
1148       if (LocaleCompare(attribute,"attenuate") == 0)
1149         {
1150           if (info)
1151             (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1152           break;
1153         }
1154       if (LocaleCompare(attribute,"authenticate") == 0)
1155         {
1156           if (info)
1157             SetImageOption(info->image_info,attribute,SvPV(sval,na));
1158           break;
1159         }
1160       if (info)
1161         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1162       for ( ; image; image=image->next)
1163         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1164       break;
1165     }
1166     case 'B':
1167     case 'b':
1168     {
1169       if (LocaleCompare(attribute,"background") == 0)
1170         {
1171           (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1172             exception);
1173           if (info)
1174             info->image_info->background_color=target_color;
1175           for ( ; image; image=image->next)
1176             image->background_color=target_color;
1177           break;
1178         }
1179       if (LocaleCompare(attribute,"blue-primary") == 0)
1180         {
1181           for ( ; image; image=image->next)
1182           {
1183             flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1184             image->chromaticity.blue_primary.x=geometry_info.rho;
1185             image->chromaticity.blue_primary.y=geometry_info.sigma;
1186             if ((flags & SigmaValue) == 0)
1187               image->chromaticity.blue_primary.y=
1188                 image->chromaticity.blue_primary.x;
1189           }
1190           break;
1191         }
1192       if (LocaleCompare(attribute,"bordercolor") == 0)
1193         {
1194           (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1195             exception);
1196           if (info)
1197             info->image_info->border_color=target_color;
1198           for ( ; image; image=image->next)
1199             image->border_color=target_color;
1200           break;
1201         }
1202       if (info)
1203         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1204       for ( ; image; image=image->next)
1205         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1206       break;
1207     }
1208     case 'C':
1209     case 'c':
1210     {
1211       if (LocaleCompare(attribute,"cache-threshold") == 0)
1212         {
1213           (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1214             SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1215           (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1216             (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1217           break;
1218         }
1219       if (LocaleCompare(attribute,"clip-mask") == 0)
1220         {
1221           Image
1222             *clip_mask;
1223
1224           clip_mask=(Image *) NULL;
1225           if (SvPOK(sval))
1226             clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1227           for ( ; image; image=image->next)
1228             SetImageMask(image,clip_mask,exception);
1229           break;
1230         }
1231       if (LocaleNCompare(attribute,"colormap",8) == 0)
1232         {
1233           for ( ; image; image=image->next)
1234           {
1235             int
1236               items;
1237
1238             long
1239               i;
1240
1241             if (image->storage_class == DirectClass)
1242               continue;
1243             i=0;
1244             items=sscanf(attribute,"%*[^[][%ld",&i);
1245             (void) items;
1246             if (i > (ssize_t) image->colors)
1247               i%=image->colors;
1248             if ((strchr(SvPV(sval,na),',') == 0) ||
1249                 (strchr(SvPV(sval,na),')') != 0))
1250               QueryColorCompliance(SvPV(sval,na),AllCompliance,
1251                 image->colormap+i,exception);
1252             else
1253               {
1254                 color=image->colormap+i;
1255                 pixel.red=color->red;
1256                 pixel.green=color->green;
1257                 pixel.blue=color->blue;
1258                 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1259                 pixel.red=geometry_info.rho;
1260                 pixel.green=geometry_info.sigma;
1261                 pixel.blue=geometry_info.xi;
1262                 color->red=ClampToQuantum(pixel.red);
1263                 color->green=ClampToQuantum(pixel.green);
1264                 color->blue=ClampToQuantum(pixel.blue);
1265               }
1266           }
1267           break;
1268         }
1269       if (LocaleCompare(attribute,"colorspace") == 0)
1270         {
1271           sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1272             MagickFalse,SvPV(sval,na)) : SvIV(sval);
1273           if (sp < 0)
1274             {
1275               ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1276                 SvPV(sval,na));
1277               break;
1278             }
1279           for ( ; image; image=image->next)
1280             (void) TransformImageColorspace(image,(ColorspaceType) sp,
1281               exception);
1282           break;
1283         }
1284       if (LocaleCompare(attribute,"comment") == 0)
1285         {
1286           for ( ; image; image=image->next)
1287             (void) SetImageProperty(image,"Comment",InterpretImageProperties(
1288               info ? info->image_info : (ImageInfo *) NULL,image,
1289               SvPV(sval,na),exception),exception);
1290           break;
1291         }
1292       if (LocaleCompare(attribute,"compression") == 0)
1293         {
1294           sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1295             MagickFalse,SvPV(sval,na)) : SvIV(sval);
1296           if (sp < 0)
1297             {
1298               ThrowPerlException(exception,OptionError,
1299                 "UnrecognizedImageCompression",SvPV(sval,na));
1300               break;
1301             }
1302           if (info)
1303             info->image_info->compression=(CompressionType) sp;
1304           for ( ; image; image=image->next)
1305             image->compression=(CompressionType) sp;
1306           break;
1307         }
1308       if (info)
1309         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1310       for ( ; image; image=image->next)
1311         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1312       break;
1313     }
1314     case 'D':
1315     case 'd':
1316     {
1317       if (LocaleCompare(attribute,"debug") == 0)
1318         {
1319           SetLogEventMask(SvPV(sval,na));
1320           break;
1321         }
1322       if (LocaleCompare(attribute,"delay") == 0)
1323         {
1324           flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1325           for ( ; image; image=image->next)
1326           {
1327             image->delay=(size_t) floor(geometry_info.rho+0.5);
1328             if ((flags & SigmaValue) != 0)
1329               image->ticks_per_second=(ssize_t)
1330                 floor(geometry_info.sigma+0.5);
1331           }
1332           break;
1333         }
1334       if (LocaleCompare(attribute,"disk-limit") == 0)
1335         {
1336           MagickSizeType
1337             limit;
1338
1339           limit=MagickResourceInfinity;
1340           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1341             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1342               100.0);
1343           (void) SetMagickResourceLimit(DiskResource,limit);
1344           break;
1345         }
1346       if (LocaleCompare(attribute,"density") == 0)
1347         {
1348           if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1349             {
1350               ThrowPerlException(exception,OptionError,"MissingGeometry",
1351                 SvPV(sval,na));
1352               break;
1353             }
1354           if (info)
1355             (void) CloneString(&info->image_info->density,SvPV(sval,na));
1356           for ( ; image; image=image->next)
1357           {
1358             flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1359             image->resolution.x=geometry_info.rho;
1360             image->resolution.y=geometry_info.sigma;
1361             if ((flags & SigmaValue) == 0)
1362               image->resolution.y=image->resolution.x;
1363           }
1364           break;
1365         }
1366       if (LocaleCompare(attribute,"depth") == 0)
1367         {
1368           if (info)
1369             info->image_info->depth=SvIV(sval);
1370           for ( ; image; image=image->next)
1371             (void) SetImageDepth(image,SvIV(sval),exception);
1372           break;
1373         }
1374       if (LocaleCompare(attribute,"dispose") == 0)
1375         {
1376           sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1377             SvPV(sval,na)) : SvIV(sval);
1378           if (sp < 0)
1379             {
1380               ThrowPerlException(exception,OptionError,
1381                 "UnrecognizedDisposeMethod",SvPV(sval,na));
1382               break;
1383             }
1384           for ( ; image; image=image->next)
1385             image->dispose=(DisposeType) sp;
1386           break;
1387         }
1388       if (LocaleCompare(attribute,"dither") == 0)
1389         {
1390           if (info)
1391             {
1392               sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1393                 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1394               if (sp < 0)
1395                 {
1396                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
1397                     SvPV(sval,na));
1398                   break;
1399                 }
1400               info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1401             }
1402           break;
1403         }
1404       if (LocaleCompare(attribute,"display") == 0)
1405         {
1406           display:
1407           if (info)
1408             (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1409           break;
1410         }
1411       if (info)
1412         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1413       for ( ; image; image=image->next)
1414         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1415       break;
1416     }
1417     case 'E':
1418     case 'e':
1419     {
1420       if (LocaleCompare(attribute,"endian") == 0)
1421         {
1422           sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1423             SvPV(sval,na)) : SvIV(sval);
1424           if (sp < 0)
1425             {
1426               ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1427                 SvPV(sval,na));
1428               break;
1429             }
1430           if (info)
1431             info->image_info->endian=(EndianType) sp;
1432           for ( ; image; image=image->next)
1433             image->endian=(EndianType) sp;
1434           break;
1435         }
1436       if (LocaleCompare(attribute,"extract") == 0)
1437         {
1438           /*
1439             Set image extract geometry.
1440           */
1441           (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1442           break;
1443         }
1444       if (info)
1445         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1446       for ( ; image; image=image->next)
1447         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1448       break;
1449     }
1450     case 'F':
1451     case 'f':
1452     {
1453       if (LocaleCompare(attribute,"filename") == 0)
1454         {
1455           if (info)
1456             (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
1457               MaxTextExtent);
1458           for ( ; image; image=image->next)
1459             (void) CopyMagickString(image->filename,SvPV(sval,na),
1460               MaxTextExtent);
1461           break;
1462         }
1463       if (LocaleCompare(attribute,"file") == 0)
1464         {
1465           FILE
1466             *file;
1467
1468           PerlIO
1469             *io_info;
1470
1471           if (info == (struct PackageInfo *) NULL)
1472             break;
1473           io_info=IoIFP(sv_2io(sval));
1474           if (io_info == (PerlIO *) NULL)
1475             {
1476               ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1477                 PackageName);
1478               break;
1479             }
1480           file=PerlIO_findFILE(io_info);
1481           if (file == (FILE *) NULL)
1482             {
1483               ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1484                 PackageName);
1485               break;
1486             }
1487           SetImageInfoFile(info->image_info,file);
1488           break;
1489         }
1490       if (LocaleCompare(attribute,"fill") == 0)
1491         {
1492           if (info)
1493             (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1494           break;
1495         }
1496       if (LocaleCompare(attribute,"font") == 0)
1497         {
1498           if (info)
1499             (void) CloneString(&info->image_info->font,SvPV(sval,na));
1500           break;
1501         }
1502       if (LocaleCompare(attribute,"foreground") == 0)
1503         break;
1504       if (LocaleCompare(attribute,"fuzz") == 0)
1505         {
1506           if (info)
1507             info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1508               QuantumRange+1.0);
1509           for ( ; image; image=image->next)
1510             image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1511               QuantumRange+1.0);
1512           break;
1513         }
1514       if (info)
1515         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1516       for ( ; image; image=image->next)
1517         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1518       break;
1519     }
1520     case 'G':
1521     case 'g':
1522     {
1523       if (LocaleCompare(attribute,"gamma") == 0)
1524         {
1525           for ( ; image; image=image->next)
1526             image->gamma=SvNV(sval);
1527           break;
1528         }
1529       if (LocaleCompare(attribute,"gravity") == 0)
1530         {
1531           sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1532             SvPV(sval,na)) : SvIV(sval);
1533           if (sp < 0)
1534             {
1535               ThrowPerlException(exception,OptionError,
1536                 "UnrecognizedGravityType",SvPV(sval,na));
1537               break;
1538             }
1539           if (info)
1540             SetImageOption(info->image_info,attribute,SvPV(sval,na));
1541           for ( ; image; image=image->next)
1542             image->gravity=(GravityType) sp;
1543           break;
1544         }
1545       if (LocaleCompare(attribute,"green-primary") == 0)
1546         {
1547           for ( ; image; image=image->next)
1548           {
1549             flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1550             image->chromaticity.green_primary.x=geometry_info.rho;
1551             image->chromaticity.green_primary.y=geometry_info.sigma;
1552             if ((flags & SigmaValue) == 0)
1553               image->chromaticity.green_primary.y=
1554                 image->chromaticity.green_primary.x;
1555           }
1556           break;
1557         }
1558       if (info)
1559         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1560       for ( ; image; image=image->next)
1561         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1562       break;
1563     }
1564     case 'I':
1565     case 'i':
1566     {
1567       if (LocaleNCompare(attribute,"index",5) == 0)
1568         {
1569           int
1570             items;
1571
1572           long
1573             index;
1574
1575           register Quantum
1576             *q;
1577
1578           CacheView
1579             *image_view;
1580
1581           for ( ; image; image=image->next)
1582           {
1583             if (image->storage_class != PseudoClass)
1584               continue;
1585             x=0;
1586             y=0;
1587             items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1588             (void) items;
1589             image_view=AcquireAuthenticCacheView(image,exception);
1590             q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1591             if (q != (Quantum *) NULL)
1592               {
1593                 items=sscanf(SvPV(sval,na),"%ld",&index);
1594                 if ((index >= 0) && (index < (ssize_t) image->colors))
1595                   SetPixelIndex(image,index,q);
1596                 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1597               }
1598             image_view=DestroyCacheView(image_view);
1599           }
1600           break;
1601         }
1602       if (LocaleCompare(attribute,"iterations") == 0)
1603         {
1604   iterations:
1605           for ( ; image; image=image->next)
1606             image->iterations=SvIV(sval);
1607           break;
1608         }
1609       if (LocaleCompare(attribute,"interlace") == 0)
1610         {
1611           sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1612             MagickFalse,SvPV(sval,na)) : SvIV(sval);
1613           if (sp < 0)
1614             {
1615               ThrowPerlException(exception,OptionError,
1616                 "UnrecognizedInterlaceType",SvPV(sval,na));
1617               break;
1618             }
1619           if (info)
1620             info->image_info->interlace=(InterlaceType) sp;
1621           for ( ; image; image=image->next)
1622             image->interlace=(InterlaceType) sp;
1623           break;
1624         }
1625       if (info)
1626         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1627       for ( ; image; image=image->next)
1628         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1629       break;
1630     }
1631     case 'L':
1632     case 'l':
1633     {
1634       if (LocaleCompare(attribute,"label") == 0)
1635         {
1636           for ( ; image; image=image->next)
1637             (void) SetImageProperty(image,"label",InterpretImageProperties(
1638               info ? info->image_info : (ImageInfo *) NULL,image,
1639               SvPV(sval,na),exception),exception);
1640           break;
1641         }
1642       if (LocaleCompare(attribute,"loop") == 0)
1643         goto iterations;
1644       if (info)
1645         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1646       for ( ; image; image=image->next)
1647         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1648       break;
1649     }
1650     case 'M':
1651     case 'm':
1652     {
1653       if (LocaleCompare(attribute,"magick") == 0)
1654         {
1655           if (info)
1656             (void) FormatLocaleString(info->image_info->filename,MaxTextExtent,
1657               "%s:",SvPV(sval,na));
1658           for ( ; image; image=image->next)
1659             (void) CopyMagickString(image->magick,SvPV(sval,na),MaxTextExtent);
1660           break;
1661         }
1662       if (LocaleCompare(attribute,"map-limit") == 0)
1663         {
1664           MagickSizeType
1665             limit;
1666
1667           limit=MagickResourceInfinity;
1668           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1669             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1670               100.0);
1671           (void) SetMagickResourceLimit(MapResource,limit);
1672           break;
1673         }
1674       if (LocaleCompare(attribute,"mask") == 0)
1675         {
1676           Image
1677             *mask;
1678
1679           mask=(Image *) NULL;
1680           if (SvPOK(sval))
1681             mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1682           for ( ; image; image=image->next)
1683             SetImageMask(image,mask,exception);
1684           break;
1685         }
1686       if (LocaleCompare(attribute,"mattecolor") == 0)
1687         {
1688           (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1689             exception);
1690           if (info)
1691             info->image_info->matte_color=target_color;
1692           for ( ; image; image=image->next)
1693             image->matte_color=target_color;
1694           break;
1695         }
1696       if (LocaleCompare(attribute,"matte") == 0)
1697         {
1698           sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1699             SvPV(sval,na)) : SvIV(sval);
1700           if (sp < 0)
1701             {
1702               ThrowPerlException(exception,OptionError,"UnrecognizedType",
1703                 SvPV(sval,na));
1704               break;
1705             }
1706           for ( ; image; image=image->next)
1707             image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1708           break;
1709         }
1710       if (LocaleCompare(attribute,"memory-limit") == 0)
1711         {
1712           MagickSizeType
1713             limit;
1714
1715           limit=MagickResourceInfinity;
1716           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1717             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1718               100.0);
1719           (void) SetMagickResourceLimit(MemoryResource,limit);
1720           break;
1721         }
1722       if (LocaleCompare(attribute,"monochrome") == 0)
1723         {
1724           sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1725             SvPV(sval,na)) : SvIV(sval);
1726           if (sp < 0)
1727             {
1728               ThrowPerlException(exception,OptionError,"UnrecognizedType",
1729                 SvPV(sval,na));
1730               break;
1731             }
1732           if (info)
1733             info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1734           for ( ; image; image=image->next)
1735             (void) SetImageType(image,BilevelType,exception);
1736           break;
1737         }
1738       if (info)
1739         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1740       for ( ; image; image=image->next)
1741         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1742       break;
1743     }
1744     case 'O':
1745     case 'o':
1746     {
1747       if (LocaleCompare(attribute,"option") == 0)
1748         {
1749           if (info)
1750             DefineImageOption(info->image_info,SvPV(sval,na));
1751           break;
1752         }
1753       if (LocaleCompare(attribute,"orientation") == 0)
1754         {
1755           sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1756             MagickFalse,SvPV(sval,na)) : SvIV(sval);
1757           if (sp < 0)
1758             {
1759               ThrowPerlException(exception,OptionError,
1760                 "UnrecognizedOrientationType",SvPV(sval,na));
1761               break;
1762             }
1763           if (info)
1764             info->image_info->orientation=(OrientationType) sp;
1765           for ( ; image; image=image->next)
1766             image->orientation=(OrientationType) sp;
1767           break;
1768         }
1769       if (info)
1770         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1771       for ( ; image; image=image->next)
1772         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1773       break;
1774     }
1775     case 'P':
1776     case 'p':
1777     {
1778       if (LocaleCompare(attribute,"page") == 0)
1779         {
1780           char
1781             *geometry;
1782
1783           geometry=GetPageGeometry(SvPV(sval,na));
1784           if (info)
1785             (void) CloneString(&info->image_info->page,geometry);
1786           for ( ; image; image=image->next)
1787             (void) ParsePageGeometry(image,geometry,&image->page,exception);
1788           geometry=(char *) RelinquishMagickMemory(geometry);
1789           break;
1790         }
1791       if (LocaleNCompare(attribute,"pixel",5) == 0)
1792         {
1793           int
1794             items;
1795
1796           PixelInfo
1797             pixel;
1798
1799           register Quantum
1800             *q;
1801
1802           CacheView
1803             *image_view;
1804
1805           for ( ; image; image=image->next)
1806           {
1807             if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1808               break;
1809             x=0;
1810             y=0;
1811             items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1812             (void) items;
1813             image_view=AcquireVirtualCacheView(image,exception);
1814             q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1815             if (q != (Quantum *) NULL)
1816               {
1817                 if ((strchr(SvPV(sval,na),',') == 0) ||
1818                     (strchr(SvPV(sval,na),')') != 0))
1819                   QueryColorCompliance(SvPV(sval,na),AllCompliance,
1820                     &pixel,exception);
1821                 else
1822                   {
1823                     GetPixelInfo(image,&pixel);
1824                     flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1825                     pixel.red=geometry_info.rho;
1826                     if ((flags & SigmaValue) != 0)
1827                       pixel.green=geometry_info.sigma;
1828                     if ((flags & XiValue) != 0)
1829                       pixel.blue=geometry_info.xi;
1830                     if ((flags & PsiValue) != 0)
1831                       pixel.alpha=geometry_info.psi;
1832                     if ((flags & ChiValue) != 0)
1833                       pixel.black=geometry_info.chi;
1834                   }
1835                 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1836                 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1837                 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1838                 if (image->colorspace == CMYKColorspace)
1839                   SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1840                 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1841                 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1842               }
1843             image_view=DestroyCacheView(image_view);
1844           }
1845           break;
1846         }
1847       if (LocaleCompare(attribute,"pointsize") == 0)
1848         {
1849           if (info)
1850             {
1851               (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1852               info->image_info->pointsize=geometry_info.rho;
1853             }
1854           break;
1855         }
1856       if (LocaleCompare(attribute,"preview") == 0)
1857         {
1858           sp=SvPOK(sval) ? ParseCommandOption(MagickPreviewOptions,MagickFalse,
1859             SvPV(sval,na)) : SvIV(sval);
1860           if (sp < 0)
1861             {
1862               ThrowPerlException(exception,OptionError,"UnrecognizedType",
1863                 SvPV(sval,na));
1864               break;
1865             }
1866           if (info)
1867             info->image_info->preview_type=(PreviewType) sp;
1868           break;
1869         }
1870       if (info)
1871         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1872       for ( ; image; image=image->next)
1873         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1874       break;
1875     }
1876     case 'Q':
1877     case 'q':
1878     {
1879       if (LocaleCompare(attribute,"quality") == 0)
1880         {
1881           if (info)
1882             info->image_info->quality=SvIV(sval);
1883           for ( ; image; image=image->next)
1884             image->quality=SvIV(sval);
1885           break;
1886         }
1887       if (info)
1888         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1889       for ( ; image; image=image->next)
1890         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1891       break;
1892     }
1893     case 'R':
1894     case 'r':
1895     {
1896       if (LocaleCompare(attribute,"red-primary") == 0)
1897         {
1898           for ( ; image; image=image->next)
1899           {
1900             flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1901             image->chromaticity.red_primary.x=geometry_info.rho;
1902             image->chromaticity.red_primary.y=geometry_info.sigma;
1903             if ((flags & SigmaValue) == 0)
1904               image->chromaticity.red_primary.y=
1905                 image->chromaticity.red_primary.x;
1906           }
1907           break;
1908         }
1909       if (LocaleCompare(attribute,"render") == 0)
1910         {
1911           sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1912             SvPV(sval,na)) : SvIV(sval);
1913           if (sp < 0)
1914             {
1915               ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1916                 SvPV(sval,na));
1917               break;
1918             }
1919          for ( ; image; image=image->next)
1920            image->rendering_intent=(RenderingIntent) sp;
1921          break;
1922        }
1923       if (LocaleCompare(attribute,"repage") == 0)
1924         {
1925           RectangleInfo
1926             geometry;
1927
1928           for ( ; image; image=image->next)
1929           {
1930             flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
1931             if ((flags & WidthValue) != 0)
1932               {
1933                 if ((flags & HeightValue) == 0)
1934                   geometry.height=geometry.width;
1935                 image->page.width=geometry.width;
1936                 image->page.height=geometry.height;
1937               }
1938             if ((flags & AspectValue) != 0)
1939               {
1940                 if ((flags & XValue) != 0)
1941                   image->page.x+=geometry.x;
1942                 if ((flags & YValue) != 0)
1943                   image->page.y+=geometry.y;
1944               }
1945             else
1946               {
1947                 if ((flags & XValue) != 0)
1948                   {
1949                     image->page.x=geometry.x;
1950                     if (((flags & WidthValue) != 0) && (geometry.x > 0))
1951                       image->page.width=image->columns+geometry.x;
1952                   }
1953                 if ((flags & YValue) != 0)
1954                   {
1955                     image->page.y=geometry.y;
1956                     if (((flags & HeightValue) != 0) && (geometry.y > 0))
1957                       image->page.height=image->rows+geometry.y;
1958                   }
1959               }
1960           }
1961           break;
1962         }
1963       if (info)
1964         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1965       for ( ; image; image=image->next)
1966         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1967       break;
1968     }
1969     case 'S':
1970     case 's':
1971     {
1972       if (LocaleCompare(attribute,"sampling-factor") == 0)
1973         {
1974           if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1975             {
1976               ThrowPerlException(exception,OptionError,"MissingGeometry",
1977                 SvPV(sval,na));
1978               break;
1979             }
1980           if (info)
1981             (void) CloneString(&info->image_info->sampling_factor,
1982               SvPV(sval,na));
1983           break;
1984         }
1985       if (LocaleCompare(attribute,"scene") == 0)
1986         {
1987           for ( ; image; image=image->next)
1988             image->scene=SvIV(sval);
1989           break;
1990         }
1991       if (LocaleCompare(attribute,"server") == 0)
1992         goto display;
1993       if (LocaleCompare(attribute,"size") == 0)
1994         {
1995           if (info)
1996             {
1997               if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1998                 {
1999                   ThrowPerlException(exception,OptionError,"MissingGeometry",
2000                     SvPV(sval,na));
2001                   break;
2002                 }
2003               (void) CloneString(&info->image_info->size,SvPV(sval,na));
2004             }
2005           break;
2006         }
2007       if (LocaleCompare(attribute,"stroke") == 0)
2008         {
2009           if (info)
2010             (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2011           break;
2012         }
2013       if (info)
2014         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2015       for ( ; image; image=image->next)
2016         SetImageProperty(image,attribute,SvPV(sval,na),exception);
2017       break;
2018     }
2019     case 'T':
2020     case 't':
2021     {
2022       if (LocaleCompare(attribute,"texture") == 0)
2023         {
2024           if (info)
2025             (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2026           break;
2027         }
2028       if (LocaleCompare(attribute,"thread-limit") == 0)
2029         {
2030           MagickSizeType
2031             limit;
2032
2033           limit=MagickResourceInfinity;
2034           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2035             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2036               100.0);
2037           (void) SetMagickResourceLimit(ThreadResource,limit);
2038           break;
2039         }
2040       if (LocaleCompare(attribute,"tile-offset") == 0)
2041         {
2042           char
2043             *geometry;
2044
2045           geometry=GetPageGeometry(SvPV(sval,na));
2046           if (info)
2047             (void) CloneString(&info->image_info->page,geometry);
2048           for ( ; image; image=image->next)
2049             (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2050               exception);
2051           geometry=(char *) RelinquishMagickMemory(geometry);
2052           break;
2053         }
2054       if (LocaleCompare(attribute,"time-limit") == 0)
2055         {
2056           MagickSizeType
2057             limit;
2058
2059           limit=MagickResourceInfinity;
2060           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2061             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2062               100.0);
2063           (void) SetMagickResourceLimit(TimeResource,limit);
2064           break;
2065         }
2066       if (LocaleCompare(attribute,"transparent-color") == 0)
2067         {
2068           (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2069             exception);
2070           if (info)
2071             info->image_info->transparent_color=target_color;
2072           for ( ; image; image=image->next)
2073             image->transparent_color=target_color;
2074           break;
2075         }
2076       if (LocaleCompare(attribute,"type") == 0)
2077         {
2078           sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2079             SvPV(sval,na)) : SvIV(sval);
2080           if (sp < 0)
2081             {
2082               ThrowPerlException(exception,OptionError,"UnrecognizedType",
2083                 SvPV(sval,na));
2084               break;
2085             }
2086           if (info)
2087             info->image_info->type=(ImageType) sp;
2088           for ( ; image; image=image->next)
2089             SetImageType(image,(ImageType) sp,exception);
2090           break;
2091         }
2092       if (info)
2093         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2094       for ( ; image; image=image->next)
2095         SetImageProperty(image,attribute,SvPV(sval,na),exception);
2096       break;
2097     }
2098     case 'U':
2099     case 'u':
2100     {
2101       if (LocaleCompare(attribute,"units") == 0)
2102         {
2103           sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2104             MagickFalse,SvPV(sval,na)) : SvIV(sval);
2105           if (sp < 0)
2106             {
2107               ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2108                 SvPV(sval,na));
2109               break;
2110             }
2111           if (info)
2112             info->image_info->units=(ResolutionType) sp;
2113           for ( ; image; image=image->next)
2114           {
2115             ResolutionType
2116               units;
2117
2118             units=(ResolutionType) sp;
2119             if (image->units != units)
2120               switch (image->units)
2121               {
2122                 case UndefinedResolution:
2123                 case PixelsPerInchResolution:
2124                 {
2125                   if (units == PixelsPerCentimeterResolution)
2126                     {
2127                       image->resolution.x*=2.54;
2128                       image->resolution.y*=2.54;
2129                     }
2130                   break;
2131                 }
2132                 case PixelsPerCentimeterResolution:
2133                 {
2134                   if (units == PixelsPerInchResolution)
2135                     {
2136                       image->resolution.x/=2.54;
2137                       image->resolution.y/=2.54;
2138                     }
2139                   break;
2140                 }
2141               }
2142             image->units=units;
2143           }
2144           break;
2145         }
2146       if (info)
2147         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2148       for ( ; image; image=image->next)
2149         SetImageProperty(image,attribute,SvPV(sval,na),exception);
2150       break;
2151     }
2152     case 'V':
2153     case 'v':
2154     {
2155       if (LocaleCompare(attribute,"verbose") == 0)
2156         {
2157           sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2158             SvPV(sval,na)) : SvIV(sval);
2159           if (sp < 0)
2160             {
2161               ThrowPerlException(exception,OptionError,"UnrecognizedType",
2162                 SvPV(sval,na));
2163               break;
2164             }
2165           if (info)
2166             info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2167           break;
2168         }
2169       if (LocaleCompare(attribute,"view") == 0)
2170         {
2171           if (info)
2172             (void) CloneString(&info->image_info->view,SvPV(sval,na));
2173           break;
2174         }
2175       if (LocaleCompare(attribute,"virtual-pixel") == 0)
2176         {
2177           sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2178             MagickFalse,SvPV(sval,na)) : SvIV(sval);
2179           if (sp < 0)
2180             {
2181               ThrowPerlException(exception,OptionError,
2182                 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2183               break;
2184             }
2185           for ( ; image; image=image->next)
2186             SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2187           break;
2188         }
2189       if (info)
2190         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2191       for ( ; image; image=image->next)
2192         SetImageProperty(image,attribute,SvPV(sval,na),exception);
2193       break;
2194     }
2195     case 'W':
2196     case 'w':
2197     {
2198       if (LocaleCompare(attribute,"white-point") == 0)
2199         {
2200           for ( ; image; image=image->next)
2201           {
2202             flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2203             image->chromaticity.white_point.x=geometry_info.rho;
2204             image->chromaticity.white_point.y=geometry_info.sigma;
2205             if ((flags & SigmaValue) == 0)
2206               image->chromaticity.white_point.y=
2207                 image->chromaticity.white_point.x;
2208           }
2209           break;
2210         }
2211       if (info)
2212         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2213       for ( ; image; image=image->next)
2214         SetImageProperty(image,attribute,SvPV(sval,na),exception);
2215       break;
2216     }
2217     default:
2218     {
2219       if (info)
2220         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2221       for ( ; image; image=image->next)
2222         SetImageProperty(image,attribute,SvPV(sval,na),exception);
2223       break;
2224     }
2225   }
2226 }
2227 \f
2228 /*
2229 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2230 %                                                                             %
2231 %                                                                             %
2232 %                                                                             %
2233 %   S e t u p L i s t                                                         %
2234 %                                                                             %
2235 %                                                                             %
2236 %                                                                             %
2237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2238 %
2239 %  Method SetupList returns the list of all the images linked by their
2240 %  image->next and image->previous link lists for use with ImageMagick.  If
2241 %  info is non-NULL, an info structure is returned in *info.  If
2242 %  reference_vector is non-NULL,an array of SV* are returned in
2243 %  *reference_vector.  Reference_vector is used when the images are going to be
2244 %  replaced with new Image*'s.
2245 %
2246 %  The format of the SetupList routine is:
2247 %
2248 %      Image *SetupList(SV *reference,struct PackageInfo **info,
2249 %        SV ***reference_vector,ExceptionInfo *exception)
2250 %
2251 %  A description of each parameter follows:
2252 %
2253 %    o list: a list of strings.
2254 %
2255 %    o string: a character string.
2256 %
2257 %    o exception: Return any errors or warnings in this structure.
2258 %
2259 */
2260 static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2261   SV ***reference_vector,ExceptionInfo *exception)
2262 {
2263   Image
2264     *image;
2265
2266   ssize_t
2267     current,
2268     last;
2269
2270   if (reference_vector)
2271     *reference_vector=NULL;
2272   if (info)
2273     *info=NULL;
2274   current=0;
2275   last=0;
2276   image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2277   if (info && (SvTYPE(reference) == SVt_PVAV))
2278     *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2279       exception);
2280   return(image);
2281 }
2282 \f
2283 /*
2284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2285 %                                                                             %
2286 %                                                                             %
2287 %                                                                             %
2288 %   s t r E Q c a s e                                                         %
2289 %                                                                             %
2290 %                                                                             %
2291 %                                                                             %
2292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2293 %
2294 %  strEQcase() compares two strings and returns 0 if they are the
2295 %  same or if the second string runs out first.  The comparison is case
2296 %  insensitive.
2297 %
2298 %  The format of the strEQcase routine is:
2299 %
2300 %      ssize_t strEQcase(const char *p,const char *q)
2301 %
2302 %  A description of each parameter follows:
2303 %
2304 %    o p: a character string.
2305 %
2306 %    o q: a character string.
2307 %
2308 %
2309 */
2310 static ssize_t strEQcase(const char *p,const char *q)
2311 {
2312   char
2313     c;
2314
2315   register ssize_t
2316     i;
2317
2318   for (i=0 ; (c=(*q)) != 0; i++)
2319   {
2320     if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2321         (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2322       return(0);
2323     p++;
2324     q++;
2325   }
2326   return(((*q == 0) && (*p == 0)) ? i : 0);
2327 }
2328 \f
2329 /*
2330 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2331 %                                                                             %
2332 %                                                                             %
2333 %                                                                             %
2334 %   I m a g e : : M a g i c k                                                 %
2335 %                                                                             %
2336 %                                                                             %
2337 %                                                                             %
2338 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2339 %
2340 %
2341 */
2342 MODULE = Image::Magick::Q16HDRI PACKAGE = Image::Magick::Q16HDRI
2343
2344 PROTOTYPES: ENABLE
2345
2346 BOOT:
2347   MagickCoreGenesis("PerlMagick",MagickFalse);
2348   SetWarningHandler(NULL);
2349   SetErrorHandler(NULL);
2350   magick_registry=NewSplayTree((int (*)(const void *,const void *))
2351     NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2352
2353 void
2354 UNLOAD()
2355   PPCODE:
2356   {
2357     if (magick_registry != (SplayTreeInfo *) NULL)
2358       magick_registry=DestroySplayTree(magick_registry);
2359     MagickCoreTerminus();
2360   }
2361
2362 double
2363 constant(name,argument)
2364   char *name
2365   ssize_t argument
2366 \f
2367 #
2368 ###############################################################################
2369 #                                                                             #
2370 #                                                                             #
2371 #                                                                             #
2372 #   A n i m a t e                                                             #
2373 #                                                                             #
2374 #                                                                             #
2375 #                                                                             #
2376 ###############################################################################
2377 #
2378 #
2379 void
2380 Animate(ref,...)
2381   Image::Magick::Q16HDRI ref=NO_INIT
2382   ALIAS:
2383     AnimateImage  = 1
2384     animate       = 2
2385     animateimage  = 3
2386   PPCODE:
2387   {
2388     ExceptionInfo
2389       *exception;
2390
2391     Image
2392       *image;
2393
2394     register ssize_t
2395       i;
2396
2397     struct PackageInfo
2398       *info,
2399       *package_info;
2400
2401     SV
2402       *perl_exception,
2403       *reference;
2404
2405     PERL_UNUSED_VAR(ref);
2406     PERL_UNUSED_VAR(ix);
2407     exception=AcquireExceptionInfo();
2408     perl_exception=newSVpv("",0);
2409     package_info=(struct PackageInfo *) NULL;
2410     if (sv_isobject(ST(0)) == 0)
2411       {
2412         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2413           PackageName);
2414         goto PerlException;
2415       }
2416     reference=SvRV(ST(0));
2417     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2418     if (image == (Image *) NULL)
2419       {
2420         ThrowPerlException(exception,OptionError,"NoImagesDefined",
2421           PackageName);
2422         goto PerlException;
2423       }
2424     package_info=ClonePackageInfo(info,exception);
2425     if (items == 2)
2426       SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2427     else
2428       if (items > 2)
2429         for (i=2; i < items; i+=2)
2430           SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2431             exception);
2432     (void) AnimateImages(package_info->image_info,image,exception);
2433     (void) CatchImageException(image);
2434
2435   PerlException:
2436     if (package_info != (struct PackageInfo *) NULL)
2437       DestroyPackageInfo(package_info);
2438     InheritPerlException(exception,perl_exception);
2439     exception=DestroyExceptionInfo(exception);
2440     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2441     SvPOK_on(perl_exception);
2442     ST(0)=sv_2mortal(perl_exception);
2443     XSRETURN(1);
2444   }
2445 \f
2446 #
2447 ###############################################################################
2448 #                                                                             #
2449 #                                                                             #
2450 #                                                                             #
2451 #   A p p e n d                                                               #
2452 #                                                                             #
2453 #                                                                             #
2454 #                                                                             #
2455 ###############################################################################
2456 #
2457 #
2458 void
2459 Append(ref,...)
2460   Image::Magick::Q16HDRI ref=NO_INIT
2461   ALIAS:
2462     AppendImage  = 1
2463     append       = 2
2464     appendimage  = 3
2465   PPCODE:
2466   {
2467     AV
2468       *av;
2469
2470     char
2471       *attribute;
2472
2473     ExceptionInfo
2474       *exception;
2475
2476     HV
2477       *hv;
2478
2479     Image
2480       *image;
2481
2482     register ssize_t
2483       i;
2484
2485     ssize_t
2486       stack;
2487
2488     struct PackageInfo
2489       *info;
2490
2491     SV
2492       *av_reference,
2493       *perl_exception,
2494       *reference,
2495       *rv,
2496       *sv;
2497
2498     PERL_UNUSED_VAR(ref);
2499     PERL_UNUSED_VAR(ix);
2500     exception=AcquireExceptionInfo();
2501     perl_exception=newSVpv("",0);
2502     sv=NULL;
2503     attribute=NULL;
2504     av=NULL;
2505     if (sv_isobject(ST(0)) == 0)
2506       {
2507         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2508           PackageName);
2509         goto PerlException;
2510       }
2511     reference=SvRV(ST(0));
2512     hv=SvSTASH(reference);
2513     av=newAV();
2514     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2515     SvREFCNT_dec(av);
2516     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2517     if (image == (Image *) NULL)
2518       {
2519         ThrowPerlException(exception,OptionError,"NoImagesDefined",
2520           PackageName);
2521         goto PerlException;
2522       }
2523     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2524     /*
2525       Get options.
2526     */
2527     stack=MagickTrue;
2528     for (i=2; i < items; i+=2)
2529     {
2530       attribute=(char *) SvPV(ST(i-1),na);
2531       switch (*attribute)
2532       {
2533         case 'S':
2534         case 's':
2535         {
2536           if (LocaleCompare(attribute,"stack") == 0)
2537             {
2538               stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2539                 SvPV(ST(i),na));
2540               if (stack < 0)
2541                 {
2542                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
2543                     SvPV(ST(i),na));
2544                   return;
2545                 }
2546               break;
2547             }
2548           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2549             attribute);
2550           break;
2551         }
2552         default:
2553         {
2554           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2555             attribute);
2556           break;
2557         }
2558       }
2559     }
2560     image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2561     if (image == (Image *) NULL)
2562       goto PerlException;
2563     for ( ; image; image=image->next)
2564     {
2565       AddImageToRegistry(sv,image);
2566       rv=newRV(sv);
2567       av_push(av,sv_bless(rv,hv));
2568       SvREFCNT_dec(sv);
2569     }
2570     exception=DestroyExceptionInfo(exception);
2571     ST(0)=av_reference;
2572     SvREFCNT_dec(perl_exception);
2573     XSRETURN(1);
2574
2575   PerlException:
2576     InheritPerlException(exception,perl_exception);
2577     exception=DestroyExceptionInfo(exception);
2578     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2579     SvPOK_on(perl_exception);
2580     ST(0)=sv_2mortal(perl_exception);
2581     XSRETURN(1);
2582   }
2583 \f
2584 #
2585 ###############################################################################
2586 #                                                                             #
2587 #                                                                             #
2588 #                                                                             #
2589 #   A v e r a g e                                                             #
2590 #                                                                             #
2591 #                                                                             #
2592 #                                                                             #
2593 ###############################################################################
2594 #
2595 #
2596 void
2597 Average(ref)
2598   Image::Magick::Q16HDRI ref=NO_INIT
2599   ALIAS:
2600     AverageImage   = 1
2601     average        = 2
2602     averageimage   = 3
2603   PPCODE:
2604   {
2605     AV
2606       *av;
2607
2608     char
2609       *p;
2610
2611     ExceptionInfo
2612       *exception;
2613
2614     HV
2615       *hv;
2616
2617     Image
2618       *image;
2619
2620     struct PackageInfo
2621       *info;
2622
2623     SV
2624       *perl_exception,
2625       *reference,
2626       *rv,
2627       *sv;
2628
2629     PERL_UNUSED_VAR(ref);
2630     PERL_UNUSED_VAR(ix);
2631     exception=AcquireExceptionInfo();
2632     perl_exception=newSVpv("",0);
2633     sv=NULL;
2634     if (sv_isobject(ST(0)) == 0)
2635       {
2636         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2637           PackageName);
2638         goto PerlException;
2639       }
2640     reference=SvRV(ST(0));
2641     hv=SvSTASH(reference);
2642     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2643     if (image == (Image *) NULL)
2644       {
2645         ThrowPerlException(exception,OptionError,"NoImagesDefined",
2646           PackageName);
2647         goto PerlException;
2648       }
2649     image=EvaluateImages(image,MeanEvaluateOperator,exception);
2650     if (image == (Image *) NULL)
2651       goto PerlException;
2652     /*
2653       Create blessed Perl array for the returned image.
2654     */
2655     av=newAV();
2656     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2657     SvREFCNT_dec(av);
2658     AddImageToRegistry(sv,image);
2659     rv=newRV(sv);
2660     av_push(av,sv_bless(rv,hv));
2661     SvREFCNT_dec(sv);
2662     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2663     (void) FormatLocaleString(info->image_info->filename,MaxTextExtent,
2664       "average-%.*s",(int) (MaxTextExtent-9),
2665       ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2666     (void) CopyMagickString(image->filename,info->image_info->filename,
2667       MaxTextExtent);
2668     SetImageInfo(info->image_info,0,exception);
2669     exception=DestroyExceptionInfo(exception);
2670     SvREFCNT_dec(perl_exception);
2671     XSRETURN(1);
2672
2673   PerlException:
2674     InheritPerlException(exception,perl_exception);
2675     exception=DestroyExceptionInfo(exception);
2676     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2677     SvPOK_on(perl_exception);
2678     ST(0)=sv_2mortal(perl_exception);
2679     XSRETURN(1);
2680   }
2681 \f
2682 #
2683 ###############################################################################
2684 #                                                                             #
2685 #                                                                             #
2686 #                                                                             #
2687 #   B l o b T o I m a g e                                                     #
2688 #                                                                             #
2689 #                                                                             #
2690 #                                                                             #
2691 ###############################################################################
2692 #
2693 #
2694 void
2695 BlobToImage(ref,...)
2696   Image::Magick::Q16HDRI ref=NO_INIT
2697   ALIAS:
2698     BlobToImage  = 1
2699     blobtoimage  = 2
2700     blobto       = 3
2701   PPCODE:
2702   {
2703     AV
2704       *av;
2705
2706     char
2707       **keep,
2708       **list;
2709
2710     ExceptionInfo
2711       *exception;
2712
2713     HV
2714       *hv;
2715
2716     Image
2717       *image;
2718
2719     register char
2720       **p;
2721
2722     register ssize_t
2723       i;
2724
2725     ssize_t
2726       ac,
2727       n,
2728       number_images;
2729
2730     STRLEN
2731       *length;
2732
2733     struct PackageInfo
2734       *info;
2735
2736     SV
2737       *perl_exception,
2738       *reference,
2739       *rv,
2740       *sv;
2741
2742     PERL_UNUSED_VAR(ref);
2743     PERL_UNUSED_VAR(ix);
2744     exception=AcquireExceptionInfo();
2745     perl_exception=newSVpv("",0);
2746     sv=NULL;
2747     number_images=0;
2748     ac=(items < 2) ? 1 : items-1;
2749     length=(STRLEN *) NULL;
2750     list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2751     if (list == (char **) NULL)
2752       {
2753         ThrowPerlException(exception,ResourceLimitError,
2754           "MemoryAllocationFailed",PackageName);
2755         goto PerlException;
2756       }
2757     length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2758     if (length == (STRLEN *) NULL)
2759       {
2760         ThrowPerlException(exception,ResourceLimitError,
2761           "MemoryAllocationFailed",PackageName);
2762         goto PerlException;
2763       }
2764     if (sv_isobject(ST(0)) == 0)
2765       {
2766         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2767           PackageName);
2768         goto PerlException;
2769       }
2770     reference=SvRV(ST(0));
2771     hv=SvSTASH(reference);
2772     if (SvTYPE(reference) != SVt_PVAV)
2773       {
2774         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2775           PackageName);
2776         goto PerlException;
2777       }
2778     av=(AV *) reference;
2779     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2780       exception);
2781     n=1;
2782     if (items <= 1)
2783       {
2784         ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2785         goto PerlException;
2786       }
2787     for (n=0, i=0; i < ac; i++)
2788     {
2789       list[n]=(char *) (SvPV(ST(i+1),length[n]));
2790       if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2791         {
2792           list[n]=(char *) (SvPV(ST(i+2),length[n]));
2793           continue;
2794         }
2795       n++;
2796     }
2797     list[n]=(char *) NULL;
2798     keep=list;
2799     for (i=number_images=0; i < n; i++)
2800     {
2801       image=BlobToImage(info->image_info,list[i],length[i],exception);
2802       if (image == (Image *) NULL)
2803         break;
2804       for ( ; image; image=image->next)
2805       {
2806         AddImageToRegistry(sv,image);
2807         rv=newRV(sv);
2808         av_push(av,sv_bless(rv,hv));
2809         SvREFCNT_dec(sv);
2810         number_images++;
2811       }
2812     }
2813     /*
2814       Free resources.
2815     */
2816     for (i=0; i < n; i++)
2817       if (list[i] != (char *) NULL)
2818         for (p=keep; list[i] != *p++; )
2819           if (*p == (char *) NULL)
2820             {
2821               list[i]=(char *) RelinquishMagickMemory(list[i]);
2822               break;
2823             }
2824
2825   PerlException:
2826     if (list)
2827       list=(char **) RelinquishMagickMemory(list);
2828     if (length)
2829       length=(STRLEN *) RelinquishMagickMemory(length);
2830     InheritPerlException(exception,perl_exception);
2831     exception=DestroyExceptionInfo(exception);
2832     sv_setiv(perl_exception,(IV) number_images);
2833     SvPOK_on(perl_exception);
2834     ST(0)=sv_2mortal(perl_exception);
2835     XSRETURN(1);
2836   }
2837 \f
2838 #
2839 ###############################################################################
2840 #                                                                             #
2841 #                                                                             #
2842 #                                                                             #
2843 #   C h a n n e l F x                                                         #
2844 #                                                                             #
2845 #                                                                             #
2846 #                                                                             #
2847 ###############################################################################
2848 #
2849 #
2850 void
2851 ChannelFx(ref,...)
2852   Image::Magick::Q16HDRI ref=NO_INIT
2853   ALIAS:
2854     ChannelFxImage  = 1
2855     channelfx       = 2
2856     channelfximage  = 3
2857   PPCODE:
2858   {
2859     AV
2860       *av;
2861
2862     char
2863       *attribute,
2864       expression[MaxTextExtent];
2865
2866     ChannelType
2867       channel,
2868       channel_mask;
2869
2870     ExceptionInfo
2871       *exception;
2872
2873     HV
2874       *hv;
2875
2876     Image
2877       *image;
2878
2879     register ssize_t
2880       i;
2881
2882     struct PackageInfo
2883       *info;
2884
2885     SV
2886       *av_reference,
2887       *perl_exception,
2888       *reference,
2889       *rv,
2890       *sv;
2891
2892     PERL_UNUSED_VAR(ref);
2893     PERL_UNUSED_VAR(ix);
2894     exception=AcquireExceptionInfo();
2895     perl_exception=newSVpv("",0);
2896     sv=NULL;
2897     attribute=NULL;
2898     av=NULL;
2899     if (sv_isobject(ST(0)) == 0)
2900       {
2901         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2902           PackageName);
2903         goto PerlException;
2904       }
2905     reference=SvRV(ST(0));
2906     hv=SvSTASH(reference);
2907     av=newAV();
2908     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2909     SvREFCNT_dec(av);
2910     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2911     if (image == (Image *) NULL)
2912       {
2913         ThrowPerlException(exception,OptionError,"NoImagesDefined",
2914           PackageName);
2915         goto PerlException;
2916       }
2917     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2918     /*
2919       Get options.
2920     */
2921     channel=DefaultChannels;
2922     (void) CopyMagickString(expression,"u",MaxTextExtent);
2923     if (items == 2)
2924       (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MaxTextExtent);
2925     else
2926       for (i=2; i < items; i+=2)
2927       {
2928         attribute=(char *) SvPV(ST(i-1),na);
2929         switch (*attribute)
2930         {
2931           case 'C':
2932           case 'c':
2933           {
2934             if (LocaleCompare(attribute,"channel") == 0)
2935               {
2936                 ssize_t
2937                   option;
2938
2939                 option=ParseChannelOption(SvPV(ST(i),na));
2940                 if (option < 0)
2941                   {
2942                     ThrowPerlException(exception,OptionError,
2943                       "UnrecognizedType",SvPV(ST(i),na));
2944                     return;
2945                   }
2946                 channel=(ChannelType) option;
2947                 break;
2948               }
2949             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2950               attribute);
2951             break;
2952           }
2953           case 'E':
2954           case 'e':
2955           {
2956             if (LocaleCompare(attribute,"expression") == 0)
2957               {
2958                 (void) CopyMagickString(expression,SvPV(ST(i),na),
2959                   MaxTextExtent);
2960                 break;
2961               }
2962             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2963               attribute);
2964             break;
2965           }
2966           default:
2967           {
2968             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2969               attribute);
2970             break;
2971           }
2972         }
2973       }
2974     channel_mask=SetImageChannelMask(image,channel);
2975     image=ChannelFxImage(image,expression,exception);
2976     if (image != (Image *) NULL)
2977       (void) SetImageChannelMask(image,channel_mask);
2978     if (image == (Image *) NULL)
2979       goto PerlException;
2980     for ( ; image; image=image->next)
2981     {
2982       AddImageToRegistry(sv,image);
2983       rv=newRV(sv);
2984       av_push(av,sv_bless(rv,hv));
2985       SvREFCNT_dec(sv);
2986     }
2987     exception=DestroyExceptionInfo(exception);
2988     ST(0)=av_reference;
2989     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
2990     XSRETURN(1);
2991
2992   PerlException:
2993     InheritPerlException(exception,perl_exception);
2994     exception=DestroyExceptionInfo(exception);
2995     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2996     SvPOK_on(perl_exception);
2997     ST(0)=sv_2mortal(perl_exception);
2998     XSRETURN(1);
2999   }
3000 \f
3001 #
3002 ###############################################################################
3003 #                                                                             #
3004 #                                                                             #
3005 #                                                                             #
3006 #   C l o n e                                                                 #
3007 #                                                                             #
3008 #                                                                             #
3009 #                                                                             #
3010 ###############################################################################
3011 #
3012 #
3013 void
3014 Clone(ref)
3015   Image::Magick::Q16HDRI ref=NO_INIT
3016   ALIAS:
3017     CopyImage   = 1
3018     copy        = 2
3019     copyimage   = 3
3020     CloneImage  = 4
3021     clone       = 5
3022     cloneimage  = 6
3023     Clone       = 7
3024   PPCODE:
3025   {
3026     AV
3027       *av;
3028
3029     ExceptionInfo
3030       *exception;
3031
3032     HV
3033       *hv;
3034
3035     Image
3036       *clone,
3037       *image;
3038
3039     struct PackageInfo
3040       *info;
3041
3042     SV
3043       *perl_exception,
3044       *reference,
3045       *rv,
3046       *sv;
3047
3048     PERL_UNUSED_VAR(ref);
3049     PERL_UNUSED_VAR(ix);
3050     exception=AcquireExceptionInfo();
3051     perl_exception=newSVpv("",0);
3052     sv=NULL;
3053     if (sv_isobject(ST(0)) == 0)
3054       {
3055         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3056           PackageName);
3057         goto PerlException;
3058       }
3059     reference=SvRV(ST(0));
3060     hv=SvSTASH(reference);
3061     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3062     if (image == (Image *) NULL)
3063       {
3064         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3065           PackageName);
3066         goto PerlException;
3067       }
3068     /*
3069       Create blessed Perl array for the returned image.
3070     */
3071     av=newAV();
3072     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3073     SvREFCNT_dec(av);
3074     for ( ; image; image=image->next)
3075     {
3076       clone=CloneImage(image,0,0,MagickTrue,exception);
3077       if (clone == (Image *) NULL)
3078         break;
3079       AddImageToRegistry(sv,clone);
3080       rv=newRV(sv);
3081       av_push(av,sv_bless(rv,hv));
3082       SvREFCNT_dec(sv);
3083     }
3084     exception=DestroyExceptionInfo(exception);
3085     SvREFCNT_dec(perl_exception);
3086     XSRETURN(1);
3087
3088   PerlException:
3089     InheritPerlException(exception,perl_exception);
3090     exception=DestroyExceptionInfo(exception);
3091     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3092     SvPOK_on(perl_exception);
3093     ST(0)=sv_2mortal(perl_exception);
3094     XSRETURN(1);
3095   }
3096 \f
3097 #
3098 ###############################################################################
3099 #                                                                             #
3100 #                                                                             #
3101 #                                                                             #
3102 #   C L O N E                                                                 #
3103 #                                                                             #
3104 #                                                                             #
3105 #                                                                             #
3106 ###############################################################################
3107 #
3108 #
3109 void
3110 CLONE(ref,...)
3111   SV *ref;
3112   CODE:
3113   {
3114     PERL_UNUSED_VAR(ref);
3115     if (magick_registry != (SplayTreeInfo *) NULL)
3116       {
3117         register Image
3118           *p;
3119
3120         ResetSplayTreeIterator(magick_registry);
3121         p=(Image *) GetNextKeyInSplayTree(magick_registry);
3122         while (p != (Image *) NULL)
3123         {
3124           ReferenceImage(p);
3125           p=(Image *) GetNextKeyInSplayTree(magick_registry);
3126         }
3127       }
3128   }
3129 \f
3130 #
3131 ###############################################################################
3132 #                                                                             #
3133 #                                                                             #
3134 #                                                                             #
3135 #   C o a l e s c e                                                           #
3136 #                                                                             #
3137 #                                                                             #
3138 #                                                                             #
3139 ###############################################################################
3140 #
3141 #
3142 void
3143 Coalesce(ref)
3144   Image::Magick::Q16HDRI ref=NO_INIT
3145   ALIAS:
3146     CoalesceImage   = 1
3147     coalesce        = 2
3148     coalesceimage   = 3
3149   PPCODE:
3150   {
3151     AV
3152       *av;
3153
3154     ExceptionInfo
3155       *exception;
3156
3157     HV
3158       *hv;
3159
3160     Image
3161       *image;
3162
3163     struct PackageInfo
3164       *info;
3165
3166     SV
3167       *av_reference,
3168       *perl_exception,
3169       *reference,
3170       *rv,
3171       *sv;
3172
3173     PERL_UNUSED_VAR(ref);
3174     PERL_UNUSED_VAR(ix);
3175     exception=AcquireExceptionInfo();
3176     perl_exception=newSVpv("",0);
3177     sv=NULL;
3178     if (sv_isobject(ST(0)) == 0)
3179       {
3180         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3181           PackageName);
3182         goto PerlException;
3183       }
3184     reference=SvRV(ST(0));
3185     hv=SvSTASH(reference);
3186     av=newAV();
3187     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3188     SvREFCNT_dec(av);
3189     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3190     if (image == (Image *) NULL)
3191       {
3192         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3193           PackageName);
3194         goto PerlException;
3195       }
3196     image=CoalesceImages(image,exception);
3197     if (image == (Image *) NULL)
3198       goto PerlException;
3199     for ( ; image; image=image->next)
3200     {
3201       AddImageToRegistry(sv,image);
3202       rv=newRV(sv);
3203       av_push(av,sv_bless(rv,hv));
3204       SvREFCNT_dec(sv);
3205     }
3206     exception=DestroyExceptionInfo(exception);
3207     ST(0)=av_reference;
3208     SvREFCNT_dec(perl_exception);
3209     XSRETURN(1);
3210
3211   PerlException:
3212     InheritPerlException(exception,perl_exception);
3213     exception=DestroyExceptionInfo(exception);
3214     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3215     SvPOK_on(perl_exception);
3216     ST(0)=sv_2mortal(perl_exception);
3217     XSRETURN(1);
3218   }
3219 \f
3220 #
3221 ###############################################################################
3222 #                                                                             #
3223 #                                                                             #
3224 #                                                                             #
3225 #   C o m p a r e                                                             #
3226 #                                                                             #
3227 #                                                                             #
3228 #                                                                             #
3229 ###############################################################################
3230 #
3231 #
3232 void
3233 Compare(ref,...)
3234   Image::Magick::Q16HDRI ref=NO_INIT
3235   ALIAS:
3236     CompareImages = 1
3237     compare      = 2
3238     compareimage = 3
3239   PPCODE:
3240   {
3241     AV
3242       *av;
3243
3244     char
3245       *attribute;
3246
3247     double
3248       distortion;
3249
3250     ExceptionInfo
3251       *exception;
3252
3253     HV
3254       *hv;
3255
3256     Image
3257       *difference_image,
3258       *image,
3259       *reconstruct_image;
3260
3261     MetricType
3262       metric;
3263
3264     register ssize_t
3265       i;
3266
3267     ssize_t
3268       option;
3269
3270     struct PackageInfo
3271       *info;
3272
3273     SV
3274       *av_reference,
3275       *perl_exception,
3276       *reference,
3277       *rv,
3278       *sv;
3279
3280     PERL_UNUSED_VAR(ref);
3281     PERL_UNUSED_VAR(ix);
3282     exception=AcquireExceptionInfo();
3283     perl_exception=newSVpv("",0);
3284     sv=NULL;
3285     av=NULL;
3286     attribute=NULL;
3287     if (sv_isobject(ST(0)) == 0)
3288       {
3289         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3290           PackageName);
3291         goto PerlException;
3292       }
3293     reference=SvRV(ST(0));
3294     hv=SvSTASH(reference);
3295     av=newAV();
3296     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3297     SvREFCNT_dec(av);
3298     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3299     if (image == (Image *) NULL)
3300       {
3301         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3302           PackageName);
3303         goto PerlException;
3304       }
3305     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3306     /*
3307       Get attribute.
3308     */
3309     reconstruct_image=image;
3310     metric=RootMeanSquaredErrorMetric;
3311     for (i=2; i < items; i+=2)
3312     {
3313       attribute=(char *) SvPV(ST(i-1),na);
3314       switch (*attribute)
3315       {
3316         case 'C':
3317         case 'c':
3318         {
3319           if (LocaleCompare(attribute,"channel") == 0)
3320             {
3321               ssize_t
3322                 option;
3323
3324               option=ParseChannelOption(SvPV(ST(i),na));
3325               if (option < 0)
3326                 {
3327                   ThrowPerlException(exception,OptionError,
3328                     "UnrecognizedType",SvPV(ST(i),na));
3329                   return;
3330                 }
3331               SetPixelChannelMask(image,(ChannelType) option);
3332               break;
3333             }
3334           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3335             attribute);
3336           break;
3337         }
3338         case 'F':
3339         case 'f':
3340         {
3341           if (LocaleCompare(attribute,"fuzz") == 0)
3342             {
3343               image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3344               break;
3345             }
3346           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3347             attribute);
3348           break;
3349         }
3350         case 'I':
3351         case 'i':
3352         {
3353           if (LocaleCompare(attribute,"image") == 0)
3354             {
3355               reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3356                 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3357               break;
3358             }
3359           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3360             attribute);
3361           break;
3362         }
3363         case 'M':
3364         case 'm':
3365         {
3366           if (LocaleCompare(attribute,"metric") == 0)
3367             {
3368               option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3369                 SvPV(ST(i),na));
3370               if (option < 0)
3371                 {
3372                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
3373                     SvPV(ST(i),na));
3374                   break;
3375                 }
3376               metric=(MetricType) option;
3377               break;
3378             }
3379           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3380             attribute);
3381           break;
3382         }
3383         default:
3384         {
3385           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3386             attribute);
3387           break;
3388         }
3389       }
3390     }
3391     difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3392       exception);
3393     if (difference_image != (Image *) NULL)
3394       {
3395         difference_image->error.mean_error_per_pixel=distortion;
3396         AddImageToRegistry(sv,difference_image);
3397         rv=newRV(sv);
3398         av_push(av,sv_bless(rv,hv));
3399         SvREFCNT_dec(sv);
3400       }
3401     exception=DestroyExceptionInfo(exception);
3402     ST(0)=av_reference;
3403     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
3404     XSRETURN(1);
3405
3406   PerlException:
3407     InheritPerlException(exception,perl_exception);
3408     exception=DestroyExceptionInfo(exception);
3409     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3410     SvPOK_on(perl_exception);
3411     ST(0)=sv_2mortal(perl_exception);
3412     XSRETURN(1);
3413   }
3414 \f
3415 #
3416 ###############################################################################
3417 #                                                                             #
3418 #                                                                             #
3419 #                                                                             #
3420 #   C o m p a r e L a y e r s                                                 #
3421 #                                                                             #
3422 #                                                                             #
3423 #                                                                             #
3424 ###############################################################################
3425 #
3426 #
3427 void
3428 CompareLayers(ref)
3429   Image::Magick::Q16HDRI ref=NO_INIT
3430   ALIAS:
3431     CompareImagesLayers   = 1
3432     comparelayers        = 2
3433     compareimagelayers   = 3
3434   PPCODE:
3435   {
3436     AV
3437       *av;
3438
3439     char
3440       *attribute;
3441
3442     ExceptionInfo
3443       *exception;
3444
3445     HV
3446       *hv;
3447
3448     Image
3449       *image;
3450
3451     LayerMethod
3452       method;
3453
3454     register ssize_t
3455       i;
3456
3457     ssize_t
3458       option;
3459
3460     struct PackageInfo
3461       *info;
3462
3463     SV
3464       *av_reference,
3465       *perl_exception,
3466       *reference,
3467       *rv,
3468       *sv;
3469
3470     PERL_UNUSED_VAR(ref);
3471     PERL_UNUSED_VAR(ix);
3472     exception=AcquireExceptionInfo();
3473     perl_exception=newSVpv("",0);
3474     sv=NULL;
3475     if (sv_isobject(ST(0)) == 0)
3476       {
3477         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3478           PackageName);
3479         goto PerlException;
3480       }
3481     reference=SvRV(ST(0));
3482     hv=SvSTASH(reference);
3483     av=newAV();
3484     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3485     SvREFCNT_dec(av);
3486     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3487     if (image == (Image *) NULL)
3488       {
3489         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3490           PackageName);
3491         goto PerlException;
3492       }
3493     method=CompareAnyLayer;
3494     for (i=2; i < items; i+=2)
3495     {
3496       attribute=(char *) SvPV(ST(i-1),na);
3497       switch (*attribute)
3498       {
3499         case 'M':
3500         case 'm':
3501         {
3502           if (LocaleCompare(attribute,"method") == 0)
3503             {
3504               option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3505                 SvPV(ST(i),na));
3506               if (option < 0)
3507                 {
3508                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
3509                     SvPV(ST(i),na));
3510                   break;
3511                 }
3512                method=(LayerMethod) option;
3513               break;
3514             }
3515           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3516             attribute);
3517           break;
3518         }
3519         default:
3520         {
3521           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3522             attribute);
3523           break;
3524         }
3525       }
3526     }
3527     image=CompareImagesLayers(image,method,exception);
3528     if (image == (Image *) NULL)
3529       goto PerlException;
3530     for ( ; image; image=image->next)
3531     {
3532       AddImageToRegistry(sv,image);
3533       rv=newRV(sv);
3534       av_push(av,sv_bless(rv,hv));
3535       SvREFCNT_dec(sv);
3536     }
3537     exception=DestroyExceptionInfo(exception);
3538     ST(0)=av_reference;
3539     SvREFCNT_dec(perl_exception);
3540     XSRETURN(1);
3541
3542   PerlException:
3543     InheritPerlException(exception,perl_exception);
3544     exception=DestroyExceptionInfo(exception);
3545     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3546     SvPOK_on(perl_exception);
3547     ST(0)=sv_2mortal(perl_exception);
3548     XSRETURN(1);
3549   }
3550 \f
3551 #
3552 ###############################################################################
3553 #                                                                             #
3554 #                                                                             #
3555 #                                                                             #
3556 #   D e s t r o y                                                             #
3557 #                                                                             #
3558 #                                                                             #
3559 #                                                                             #
3560 ###############################################################################
3561 #
3562 #
3563 void
3564 DESTROY(ref)
3565   Image::Magick::Q16HDRI ref=NO_INIT
3566   PPCODE:
3567   {
3568     SV
3569       *reference;
3570
3571     PERL_UNUSED_VAR(ref);
3572     if (sv_isobject(ST(0)) == 0)
3573       croak("ReferenceIsNotMyType");
3574     reference=SvRV(ST(0));
3575     switch (SvTYPE(reference))
3576     {
3577       case SVt_PVAV:
3578       {
3579         char
3580           message[MaxTextExtent];
3581
3582         const SV
3583           *key;
3584
3585         HV
3586           *hv;
3587
3588         GV
3589           **gvp;
3590
3591         struct PackageInfo
3592           *info;
3593
3594         SV
3595           *sv;
3596
3597         /*
3598           Array (AV *) reference
3599         */
3600         (void) FormatLocaleString(message,MaxTextExtent,"package%s%p",
3601           XS_VERSION,reference);
3602         hv=gv_stashpv(PackageName, FALSE);
3603         if (!hv)
3604           break;
3605         gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3606         if (!gvp)
3607           break;
3608         sv=GvSV(*gvp);
3609         if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3610           {
3611             info=INT2PTR(struct PackageInfo *,SvIV(sv));
3612             DestroyPackageInfo(info);
3613           }
3614         key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3615         (void) key;
3616         break;
3617       }
3618       case SVt_PVMG:
3619       {
3620         Image
3621           *image;
3622
3623         /*
3624           Blessed scalar = (Image *) SvIV(reference)
3625         */
3626         image=INT2PTR(Image *,SvIV(reference));
3627         if (image != (Image *) NULL)
3628           DeleteImageFromRegistry(reference,image);
3629         break;
3630       }
3631       default:
3632         break;
3633     }
3634   }
3635 \f
3636 #
3637 ###############################################################################
3638 #                                                                             #
3639 #                                                                             #
3640 #                                                                             #
3641 #   D i s p l a y                                                             #
3642 #                                                                             #
3643 #                                                                             #
3644 #                                                                             #
3645 ###############################################################################
3646 #
3647 #
3648 void
3649 Display(ref,...)
3650   Image::Magick::Q16HDRI ref=NO_INIT
3651   ALIAS:
3652     DisplayImage  = 1
3653     display       = 2
3654     displayimage  = 3
3655   PPCODE:
3656   {
3657     ExceptionInfo
3658       *exception;
3659
3660     Image
3661       *image;
3662
3663     register ssize_t
3664       i;
3665
3666     struct PackageInfo
3667       *info,
3668       *package_info;
3669
3670     SV
3671       *perl_exception,
3672       *reference;
3673
3674     PERL_UNUSED_VAR(ref);
3675     PERL_UNUSED_VAR(ix);
3676     exception=AcquireExceptionInfo();
3677     perl_exception=newSVpv("",0);
3678     package_info=(struct PackageInfo *) NULL;
3679     if (sv_isobject(ST(0)) == 0)
3680       {
3681         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3682           PackageName);
3683         goto PerlException;
3684       }
3685     reference=SvRV(ST(0));
3686     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3687     if (image == (Image *) NULL)
3688       {
3689         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3690           PackageName);
3691         goto PerlException;
3692       }
3693     package_info=ClonePackageInfo(info,exception);
3694     if (items == 2)
3695       SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3696     else
3697       if (items > 2)
3698         for (i=2; i < items; i+=2)
3699           SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3700             exception);
3701     (void) DisplayImages(package_info->image_info,image,exception);
3702     (void) CatchImageException(image);
3703
3704   PerlException:
3705     if (package_info != (struct PackageInfo *) NULL)
3706       DestroyPackageInfo(package_info);
3707     InheritPerlException(exception,perl_exception);
3708     exception=DestroyExceptionInfo(exception);
3709     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3710     SvPOK_on(perl_exception);
3711     ST(0)=sv_2mortal(perl_exception);
3712     XSRETURN(1);
3713   }
3714 \f
3715 #
3716 ###############################################################################
3717 #                                                                             #
3718 #                                                                             #
3719 #                                                                             #
3720 #   E v a l u a t e I m a g e s                                               #
3721 #                                                                             #
3722 #                                                                             #
3723 #                                                                             #
3724 ###############################################################################
3725 #
3726 #
3727 void
3728 EvaluateImages(ref)
3729   Image::Magick::Q16HDRI ref=NO_INIT
3730   ALIAS:
3731     EvaluateImages   = 1
3732     evaluateimages   = 2
3733   PPCODE:
3734   {
3735     AV
3736       *av;
3737
3738     char
3739       *attribute,
3740       *p;
3741
3742     ExceptionInfo
3743       *exception;
3744
3745     HV
3746       *hv;
3747
3748     Image
3749       *image;
3750
3751     MagickEvaluateOperator
3752       op;
3753
3754     register ssize_t
3755       i;
3756
3757     struct PackageInfo
3758       *info;
3759
3760     SV
3761       *perl_exception,
3762       *reference,
3763       *rv,
3764       *sv;
3765
3766     PERL_UNUSED_VAR(ref);
3767     PERL_UNUSED_VAR(ix);
3768     exception=AcquireExceptionInfo();
3769     perl_exception=newSVpv("",0);
3770     sv=NULL;
3771     if (sv_isobject(ST(0)) == 0)
3772       {
3773         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3774           PackageName);
3775         goto PerlException;
3776       }
3777     reference=SvRV(ST(0));
3778     hv=SvSTASH(reference);
3779     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3780     if (image == (Image *) NULL)
3781       {
3782         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3783           PackageName);
3784         goto PerlException;
3785       }
3786     op=MeanEvaluateOperator;
3787     if (items == 2)
3788       {
3789         ssize_t
3790           in;
3791
3792         in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
3793           SvPV(ST(1),na));
3794         if (in < 0)
3795           {
3796             ThrowPerlException(exception,OptionError,"UnrecognizedType",
3797               SvPV(ST(1),na));
3798             return;
3799           }
3800         op=(MagickEvaluateOperator) in;
3801       }
3802     else
3803       for (i=2; i < items; i+=2)
3804       {
3805         attribute=(char *) SvPV(ST(i-1),na);
3806         switch (*attribute)
3807         {
3808           case 'O':
3809           case 'o':
3810           {
3811             if (LocaleCompare(attribute,"operator") == 0)
3812               {
3813                 ssize_t
3814                   in;
3815
3816                 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3817                   MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
3818                 if (in < 0)
3819                   {
3820                     ThrowPerlException(exception,OptionError,"UnrecognizedType",
3821                       SvPV(ST(i),na));
3822                     return;
3823                   }
3824                 op=(MagickEvaluateOperator) in;
3825                 break;
3826               }
3827             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3828               attribute);
3829             break;
3830           }
3831           default:
3832           {
3833             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3834               attribute);
3835             break;
3836           }
3837         }
3838       }
3839     image=EvaluateImages(image,op,exception);
3840     if (image == (Image *) NULL)
3841       goto PerlException;
3842     /*
3843       Create blessed Perl array for the returned image.
3844     */
3845     av=newAV();
3846     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3847     SvREFCNT_dec(av);
3848     AddImageToRegistry(sv,image);
3849     rv=newRV(sv);
3850     av_push(av,sv_bless(rv,hv));
3851     SvREFCNT_dec(sv);
3852     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3853     (void) FormatLocaleString(info->image_info->filename,MaxTextExtent,
3854       "evaluate-%.*s",(int) (MaxTextExtent-9),
3855       ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3856     (void) CopyMagickString(image->filename,info->image_info->filename,
3857       MaxTextExtent);
3858     SetImageInfo(info->image_info,0,exception);
3859     exception=DestroyExceptionInfo(exception);
3860     SvREFCNT_dec(perl_exception);
3861     XSRETURN(1);
3862
3863   PerlException:
3864     InheritPerlException(exception,perl_exception);
3865     exception=DestroyExceptionInfo(exception);
3866     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3867     SvPOK_on(perl_exception);
3868     ST(0)=sv_2mortal(perl_exception);
3869     XSRETURN(1);
3870   }
3871 \f
3872 #
3873 ###############################################################################
3874 #                                                                             #
3875 #                                                                             #
3876 #                                                                             #
3877 #   F e a t u r e s                                                           #
3878 #                                                                             #
3879 #                                                                             #
3880 #                                                                             #
3881 ###############################################################################
3882 #
3883 #
3884 void
3885 Features(ref,...)
3886   Image::Magick::Q16HDRI ref=NO_INIT
3887   ALIAS:
3888     FeaturesImage = 1
3889     features      = 2
3890     featuresimage = 3
3891   PPCODE:
3892   {
3893 #define ChannelFeatures(channel,direction) \
3894 { \
3895   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3896     channel_features[channel].angular_second_moment[direction]); \
3897   PUSHs(sv_2mortal(newSVpv(message,0))); \
3898   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3899     channel_features[channel].contrast[direction]); \
3900   PUSHs(sv_2mortal(newSVpv(message,0))); \
3901   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3902     channel_features[channel].contrast[direction]); \
3903   PUSHs(sv_2mortal(newSVpv(message,0))); \
3904   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3905     channel_features[channel].variance_sum_of_squares[direction]); \
3906   PUSHs(sv_2mortal(newSVpv(message,0))); \
3907   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3908     channel_features[channel].inverse_difference_moment[direction]); \
3909   PUSHs(sv_2mortal(newSVpv(message,0))); \
3910   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3911     channel_features[channel].sum_average[direction]); \
3912   PUSHs(sv_2mortal(newSVpv(message,0))); \
3913   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3914     channel_features[channel].sum_variance[direction]); \
3915   PUSHs(sv_2mortal(newSVpv(message,0))); \
3916   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3917     channel_features[channel].sum_entropy[direction]); \
3918   PUSHs(sv_2mortal(newSVpv(message,0))); \
3919   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3920     channel_features[channel].entropy[direction]); \
3921   PUSHs(sv_2mortal(newSVpv(message,0))); \
3922   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3923     channel_features[channel].difference_variance[direction]); \
3924   PUSHs(sv_2mortal(newSVpv(message,0))); \
3925   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3926     channel_features[channel].difference_entropy[direction]); \
3927   PUSHs(sv_2mortal(newSVpv(message,0))); \
3928   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3929     channel_features[channel].measure_of_correlation_1[direction]); \
3930   PUSHs(sv_2mortal(newSVpv(message,0))); \
3931   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3932     channel_features[channel].measure_of_correlation_2[direction]); \
3933   PUSHs(sv_2mortal(newSVpv(message,0))); \
3934   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
3935     channel_features[channel].maximum_correlation_coefficient[direction]); \
3936   PUSHs(sv_2mortal(newSVpv(message,0))); \
3937 }
3938
3939     AV
3940       *av;
3941
3942     char
3943       *attribute,
3944       message[MaxTextExtent];
3945
3946     ChannelFeatures
3947       *channel_features;
3948
3949     double
3950       distance;
3951
3952     ExceptionInfo
3953       *exception;
3954
3955     Image
3956       *image;
3957
3958     register ssize_t
3959       i;
3960
3961     ssize_t
3962       count;
3963
3964     struct PackageInfo
3965       *info;
3966
3967     SV
3968       *perl_exception,
3969       *reference;
3970
3971     PERL_UNUSED_VAR(ref);
3972     PERL_UNUSED_VAR(ix);
3973     exception=AcquireExceptionInfo();
3974     perl_exception=newSVpv("",0);
3975     av=NULL;
3976     if (sv_isobject(ST(0)) == 0)
3977       {
3978         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3979           PackageName);
3980         goto PerlException;
3981       }
3982     reference=SvRV(ST(0));
3983     av=newAV();
3984     SvREFCNT_dec(av);
3985     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3986     if (image == (Image *) NULL)
3987       {
3988         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3989           PackageName);
3990         goto PerlException;
3991       }
3992     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3993     distance=1;
3994     for (i=2; i < items; i+=2)
3995     {
3996       attribute=(char *) SvPV(ST(i-1),na);
3997       switch (*attribute)
3998       {
3999         case 'D':
4000         case 'd':
4001         {
4002           if (LocaleCompare(attribute,"distance") == 0)
4003             {
4004               distance=StringToLong((char *) SvPV(ST(1),na));
4005               break;
4006             }
4007           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4008             attribute);
4009           break;
4010         }
4011         default:
4012         {
4013           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4014             attribute);
4015           break;
4016         }
4017       }
4018     }
4019     count=0;
4020     for ( ; image; image=image->next)
4021     {
4022       channel_features=GetImageFeatures(image,distance,exception);
4023       if (channel_features == (ChannelFeatures *) NULL)
4024         continue;
4025       count++;
4026       EXTEND(sp,75*count);
4027       for (i=0; i < 4; i++)
4028       {
4029         ChannelFeatures(RedChannel,i);
4030         ChannelFeatures(GreenChannel,i);
4031         ChannelFeatures(BlueChannel,i);
4032         if (image->colorspace == CMYKColorspace)
4033           ChannelFeatures(BlackChannel,i);
4034         if (image->alpha_trait == BlendPixelTrait)
4035           ChannelFeatures(AlphaChannel,i);
4036       }
4037       channel_features=(ChannelFeatures *)
4038         RelinquishMagickMemory(channel_features);
4039     }
4040
4041   PerlException:
4042     InheritPerlException(exception,perl_exception);
4043     exception=DestroyExceptionInfo(exception);
4044     SvREFCNT_dec(perl_exception);
4045   }
4046 \f
4047 #
4048 ###############################################################################
4049 #                                                                             #
4050 #                                                                             #
4051 #                                                                             #
4052 #   F l a t t e n                                                             #
4053 #                                                                             #
4054 #                                                                             #
4055 #                                                                             #
4056 ###############################################################################
4057 #
4058 #
4059 void
4060 Flatten(ref)
4061   Image::Magick::Q16HDRI ref=NO_INIT
4062   ALIAS:
4063     FlattenImage   = 1
4064     flatten        = 2
4065     flattenimage   = 3
4066   PPCODE:
4067   {
4068     AV
4069       *av;
4070
4071     char
4072       *attribute,
4073       *p;
4074
4075     ExceptionInfo
4076       *exception;
4077
4078     HV
4079       *hv;
4080
4081     Image
4082       *image;
4083
4084     PixelInfo
4085       background_color;
4086
4087     register ssize_t
4088       i;
4089
4090     struct PackageInfo
4091       *info;
4092
4093     SV
4094       *perl_exception,
4095       *reference,
4096       *rv,
4097       *sv;
4098
4099     PERL_UNUSED_VAR(ref);
4100     PERL_UNUSED_VAR(ix);
4101     exception=AcquireExceptionInfo();
4102     perl_exception=newSVpv("",0);
4103     sv=NULL;
4104     if (sv_isobject(ST(0)) == 0)
4105       {
4106         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4107           PackageName);
4108         goto PerlException;
4109       }
4110     reference=SvRV(ST(0));
4111     hv=SvSTASH(reference);
4112     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4113     if (image == (Image *) NULL)
4114       {
4115         ThrowPerlException(exception,OptionError,"NoImagesDefined",
4116           PackageName);
4117         goto PerlException;
4118       }
4119     background_color=image->background_color;
4120     if (items == 2)
4121       (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4122         &background_color,exception);
4123     else
4124       for (i=2; i < items; i+=2)
4125       {
4126         attribute=(char *) SvPV(ST(i-1),na);
4127         switch (*attribute)
4128         {
4129           case 'B':
4130           case 'b':
4131           {
4132             if (LocaleCompare(attribute,"background") == 0)
4133               {
4134                 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4135                   AllCompliance,&background_color,exception);
4136                 break;
4137               }
4138             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4139               attribute);
4140             break;
4141           }
4142           default:
4143           {
4144             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4145               attribute);
4146             break;
4147           }
4148         }
4149       }
4150     image->background_color=background_color;
4151     image=MergeImageLayers(image,FlattenLayer,exception);
4152     if (image == (Image *) NULL)
4153       goto PerlException;
4154     /*
4155       Create blessed Perl array for the returned image.
4156     */
4157     av=newAV();
4158     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4159     SvREFCNT_dec(av);
4160     AddImageToRegistry(sv,image);
4161     rv=newRV(sv);
4162     av_push(av,sv_bless(rv,hv));
4163     SvREFCNT_dec(sv);
4164     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4165     (void) FormatLocaleString(info->image_info->filename,MaxTextExtent,
4166       "flatten-%.*s",(int) (MaxTextExtent-9),
4167       ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4168     (void) CopyMagickString(image->filename,info->image_info->filename,
4169       MaxTextExtent);
4170     SetImageInfo(info->image_info,0,exception);
4171     exception=DestroyExceptionInfo(exception);
4172     SvREFCNT_dec(perl_exception);
4173     XSRETURN(1);
4174
4175   PerlException:
4176     InheritPerlException(exception,perl_exception);
4177     exception=DestroyExceptionInfo(exception);
4178     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4179     SvPOK_on(perl_exception);  /* return messages in string context */
4180     ST(0)=sv_2mortal(perl_exception);
4181     XSRETURN(1);
4182   }
4183 \f
4184 #
4185 ###############################################################################
4186 #                                                                             #
4187 #                                                                             #
4188 #                                                                             #
4189 #   F x                                                                       #
4190 #                                                                             #
4191 #                                                                             #
4192 #                                                                             #
4193 ###############################################################################
4194 #
4195 #
4196 void
4197 Fx(ref,...)
4198   Image::Magick::Q16HDRI ref=NO_INIT
4199   ALIAS:
4200     FxImage  = 1
4201     fx       = 2
4202     fximage  = 3
4203   PPCODE:
4204   {
4205     AV
4206       *av;
4207
4208     char
4209       *attribute,
4210       expression[MaxTextExtent];
4211
4212     ChannelType
4213       channel,
4214       channel_mask;
4215
4216     ExceptionInfo
4217       *exception;
4218
4219     HV
4220       *hv;
4221
4222     Image
4223       *image;
4224
4225     register ssize_t
4226       i;
4227
4228     struct PackageInfo
4229       *info;
4230
4231     SV
4232       *av_reference,
4233       *perl_exception,
4234       *reference,
4235       *rv,
4236       *sv;
4237
4238     PERL_UNUSED_VAR(ref);
4239     PERL_UNUSED_VAR(ix);
4240     exception=AcquireExceptionInfo();
4241     perl_exception=newSVpv("",0);
4242     sv=NULL;
4243     attribute=NULL;
4244     av=NULL;
4245     if (sv_isobject(ST(0)) == 0)
4246       {
4247         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4248           PackageName);
4249         goto PerlException;
4250       }
4251     reference=SvRV(ST(0));
4252     hv=SvSTASH(reference);
4253     av=newAV();
4254     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4255     SvREFCNT_dec(av);
4256     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4257     if (image == (Image *) NULL)
4258       {
4259         ThrowPerlException(exception,OptionError,"NoImagesDefined",
4260           PackageName);
4261         goto PerlException;
4262       }
4263     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4264     /*
4265       Get options.
4266     */
4267     channel=DefaultChannels;
4268     (void) CopyMagickString(expression,"u",MaxTextExtent);
4269     if (items == 2)
4270       (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MaxTextExtent);
4271     else
4272       for (i=2; i < items; i+=2)
4273       {
4274         attribute=(char *) SvPV(ST(i-1),na);
4275         switch (*attribute)
4276         {
4277           case 'C':
4278           case 'c':
4279           {
4280             if (LocaleCompare(attribute,"channel") == 0)
4281               {
4282                 ssize_t
4283                   option;
4284
4285                 option=ParseChannelOption(SvPV(ST(i),na));
4286                 if (option < 0)
4287                   {
4288                     ThrowPerlException(exception,OptionError,
4289                       "UnrecognizedType",SvPV(ST(i),na));
4290                     return;
4291                   }
4292                 channel=(ChannelType) option;
4293                 break;
4294               }
4295             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4296               attribute);
4297             break;
4298           }
4299           case 'E':
4300           case 'e':
4301           {
4302             if (LocaleCompare(attribute,"expression") == 0)
4303               {
4304                 (void) CopyMagickString(expression,SvPV(ST(i),na),
4305                   MaxTextExtent);
4306                 break;
4307               }
4308             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4309               attribute);
4310             break;
4311           }
4312           default:
4313           {
4314             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4315               attribute);
4316             break;
4317           }
4318         }
4319       }
4320     channel_mask=SetImageChannelMask(image,channel);
4321     image=FxImage(image,expression,exception);
4322     if (image != (Image *) NULL)
4323       (void) SetImageChannelMask(image,channel_mask);
4324     if (image == (Image *) NULL)
4325       goto PerlException;
4326     for ( ; image; image=image->next)
4327     {
4328       AddImageToRegistry(sv,image);
4329       rv=newRV(sv);
4330       av_push(av,sv_bless(rv,hv));
4331       SvREFCNT_dec(sv);
4332     }
4333     exception=DestroyExceptionInfo(exception);
4334     ST(0)=av_reference;
4335     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
4336     XSRETURN(1);
4337
4338   PerlException:
4339     InheritPerlException(exception,perl_exception);
4340     exception=DestroyExceptionInfo(exception);
4341     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4342     SvPOK_on(perl_exception);
4343     ST(0)=sv_2mortal(perl_exception);
4344     XSRETURN(1);
4345   }
4346 \f
4347 #
4348 ###############################################################################
4349 #                                                                             #
4350 #                                                                             #
4351 #                                                                             #
4352 #   G e t                                                                     #
4353 #                                                                             #
4354 #                                                                             #
4355 #                                                                             #
4356 ###############################################################################
4357 #
4358 #
4359 void
4360 Get(ref,...)
4361   Image::Magick::Q16HDRI ref=NO_INIT
4362   ALIAS:
4363     GetAttributes = 1
4364     GetAttribute  = 2
4365     get           = 3
4366     getattributes = 4
4367     getattribute  = 5
4368   PPCODE:
4369   {
4370     char
4371       *attribute,
4372       color[MaxTextExtent];
4373
4374     const char
4375       *value;
4376
4377     ExceptionInfo
4378       *exception;
4379
4380     Image
4381       *image;
4382
4383     long
4384       j;
4385
4386     register ssize_t
4387       i;
4388
4389     struct PackageInfo
4390       *info;
4391
4392     SV
4393       *perl_exception,
4394       *reference,
4395       *s;
4396
4397     PERL_UNUSED_VAR(ref);
4398     PERL_UNUSED_VAR(ix);
4399     exception=AcquireExceptionInfo();
4400     perl_exception=newSVpv("",0);
4401     if (sv_isobject(ST(0)) == 0)
4402       {
4403         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4404           PackageName);
4405         XSRETURN_EMPTY;
4406       }
4407     reference=SvRV(ST(0));
4408     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4409     if (image == (Image *) NULL && !info)
4410       XSRETURN_EMPTY;
4411     EXTEND(sp,items);
4412     for (i=1; i < items; i++)
4413     {
4414       attribute=(char *) SvPV(ST(i),na);
4415       s=NULL;
4416       switch (*attribute)
4417       {
4418         case 'A':
4419         case 'a':
4420         {
4421           if (LocaleCompare(attribute,"adjoin") == 0)
4422             {
4423               if (info)
4424                 s=newSViv((ssize_t) info->image_info->adjoin);
4425               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4426               continue;
4427             }
4428           if (LocaleCompare(attribute,"antialias") == 0)
4429             {
4430               if (info)
4431                 s=newSViv((ssize_t) info->image_info->antialias);
4432               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4433               continue;
4434             }
4435           if (LocaleCompare(attribute,"area") == 0)
4436             {
4437               s=newSViv(GetMagickResource(AreaResource));
4438               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4439               continue;
4440             }
4441           if (LocaleCompare(attribute,"attenuate") == 0)
4442             {
4443               const char
4444                 *value;
4445
4446               value=GetImageProperty(image,attribute,exception);
4447               if (value != (const char *) NULL)
4448                 s=newSVpv(value,0);
4449               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4450               continue;
4451             }
4452           if (LocaleCompare(attribute,"authenticate") == 0)
4453             {
4454               if (info)
4455                 {
4456                   const char
4457                     *option;
4458
4459                   option=GetImageOption(info->image_info,attribute);
4460                   if (option != (const char *) NULL)
4461                     s=newSVpv(option,0);
4462                 }
4463               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4464               continue;
4465             }
4466           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4467             attribute);
4468           break;
4469         }
4470         case 'B':
4471         case 'b':
4472         {
4473           if (LocaleCompare(attribute,"background") == 0)
4474             {
4475               if (image == (Image *) NULL)
4476                 break;
4477               (void) FormatLocaleString(color,MaxTextExtent,
4478                 "%.20g,%.20g,%.20g,%.20g",image->background_color.red,
4479                 image->background_color.green,image->background_color.blue,
4480                 image->background_color.alpha);
4481               s=newSVpv(color,0);
4482               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4483               continue;
4484             }
4485           if (LocaleCompare(attribute,"base-columns") == 0)
4486             {
4487               if (image != (Image *) NULL)
4488                 s=newSViv((ssize_t) image->magick_columns);
4489               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4490               continue;
4491             }
4492           if (LocaleCompare(attribute,"base-filename") == 0)
4493             {
4494               if (image != (Image *) NULL)
4495                 s=newSVpv(image->magick_filename,0);
4496               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4497               continue;
4498             }
4499           if (LocaleCompare(attribute,"base-height") == 0)
4500             {
4501               if (image != (Image *) NULL)
4502                 s=newSViv((ssize_t) image->magick_rows);
4503               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4504               continue;
4505             }
4506           if (LocaleCompare(attribute,"base-rows") == 0)
4507             {
4508               if (image != (Image *) NULL)
4509                 s=newSViv((ssize_t) image->magick_rows);
4510               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4511               continue;
4512             }
4513           if (LocaleCompare(attribute,"base-width") == 0)
4514             {
4515               if (image != (Image *) NULL)
4516                 s=newSViv((ssize_t) image->magick_columns);
4517               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4518               continue;
4519             }
4520           if (LocaleCompare(attribute,"blue-primary") == 0)
4521             {
4522               if (image == (Image *) NULL)
4523                 break;
4524               (void) FormatLocaleString(color,MaxTextExtent,"%.15g,%.15g",
4525                 image->chromaticity.blue_primary.x,
4526                 image->chromaticity.blue_primary.y);
4527               s=newSVpv(color,0);
4528               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4529               continue;
4530             }
4531           if (LocaleCompare(attribute,"bordercolor") == 0)
4532             {
4533               if (image == (Image *) NULL)
4534                 break;
4535               (void) FormatLocaleString(color,MaxTextExtent,
4536                 "%.20g,%.20g,%.20g,%.20g",image->border_color.red,
4537                 image->border_color.green,image->border_color.blue,
4538                 image->border_color.alpha);
4539               s=newSVpv(color,0);
4540               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4541               continue;
4542             }
4543           if (LocaleCompare(attribute,"bounding-box") == 0)
4544             {
4545               char
4546                 geometry[MaxTextExtent];
4547
4548               RectangleInfo
4549                 page;
4550
4551               if (image == (Image *) NULL)
4552                 break;
4553               page=GetImageBoundingBox(image,exception);
4554               (void) FormatLocaleString(geometry,MaxTextExtent,
4555                 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4556                 page.height,(double) page.x,(double) page.y);
4557               s=newSVpv(geometry,0);
4558               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4559               continue;
4560             }
4561           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4562             attribute);
4563           break;
4564         }
4565         case 'C':
4566         case 'c':
4567         {
4568           if (LocaleCompare(attribute,"class") == 0)
4569             {
4570               if (image == (Image *) NULL)
4571                 break;
4572               s=newSViv(image->storage_class);
4573               (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4574                 image->storage_class));
4575               SvIOK_on(s);
4576               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4577               continue;
4578             }
4579           if (LocaleCompare(attribute,"clip-mask") == 0)
4580             {
4581               if (image != (Image *) NULL)
4582                 {
4583                   Image
4584                     *mask_image;
4585
4586                   SV
4587                     *sv;
4588
4589                   sv=NULL;
4590                   if (image->mask == MagickFalse)
4591                     ClipImage(image,exception);
4592                   mask_image=GetImageMask(image,exception);
4593                   if (mask_image != (Image *) NULL)
4594                     {
4595                       AddImageToRegistry(sv,mask_image);
4596                       s=sv_bless(newRV(sv),SvSTASH(reference));
4597                     }
4598                 }
4599               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4600               continue;
4601             }
4602           if (LocaleCompare(attribute,"clip-path") == 0)
4603             {
4604               if (image != (Image *) NULL)
4605                 {
4606                   Image
4607                     *mask_image;
4608
4609                   SV
4610                     *sv;
4611
4612                   sv=NULL;
4613                   if (image->mask != MagickFalse)
4614                     ClipImage(image,exception);
4615                   mask_image=GetImageMask(image,exception);
4616                   if (mask_image != (Image *) NULL)
4617                     {
4618                       AddImageToRegistry(sv,mask_image);
4619                       s=sv_bless(newRV(sv),SvSTASH(reference));
4620                     }
4621                 }
4622               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4623               continue;
4624             }
4625           if (LocaleCompare(attribute,"compression") == 0)
4626             {
4627               j=info ? info->image_info->compression : image ?
4628                 image->compression : UndefinedCompression;
4629               if (info)
4630                 if (info->image_info->compression == UndefinedCompression)
4631                   j=image->compression;
4632               s=newSViv(j);
4633               (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4634                 j));
4635               SvIOK_on(s);
4636               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4637               continue;
4638             }
4639           if (LocaleCompare(attribute,"colorspace") == 0)
4640             {
4641               j=image ? image->colorspace : RGBColorspace;
4642               s=newSViv(j);
4643               (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4644                 j));
4645               SvIOK_on(s);
4646               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4647               continue;
4648             }
4649           if (LocaleCompare(attribute,"colors") == 0)
4650             {
4651               if (image != (Image *) NULL)
4652                 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4653                   exception));
4654               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4655               continue;
4656             }
4657           if (LocaleNCompare(attribute,"colormap",8) == 0)
4658             {
4659               int
4660                 items;
4661
4662               if (image == (Image *) NULL || !image->colormap)
4663                 break;
4664               j=0;
4665               items=sscanf(attribute,"%*[^[][%ld",&j);
4666               (void) items;
4667               if (j > (ssize_t) image->colors)
4668                 j%=image->colors;
4669               (void) FormatLocaleString(color,MaxTextExtent,
4670                 "%.20g,%.20g,%.20g,%.20g",image->colormap[j].red,
4671                 image->colormap[j].green,image->colormap[j].blue,
4672                 image->colormap[j].alpha);
4673               s=newSVpv(color,0);
4674               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4675               continue;
4676             }
4677           if (LocaleCompare(attribute,"columns") == 0)
4678             {
4679               if (image != (Image *) NULL)
4680                 s=newSViv((ssize_t) image->columns);
4681               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4682               continue;
4683             }
4684           if (LocaleCompare(attribute,"comment") == 0)
4685             {
4686               const char
4687                 *value;
4688
4689               value=GetImageProperty(image,attribute,exception);
4690               if (value != (const char *) NULL)
4691                 s=newSVpv(value,0);
4692               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4693               continue;
4694             }
4695           if (LocaleCompare(attribute,"copyright") == 0)
4696             {
4697               s=newSVpv(GetMagickCopyright(),0);
4698               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4699               continue;
4700             }
4701           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4702             attribute);
4703           break;
4704         }
4705         case 'D':
4706         case 'd':
4707         {
4708           if (LocaleCompare(attribute,"density") == 0)
4709             {
4710               char
4711                 geometry[MaxTextExtent];
4712
4713               if (image == (Image *) NULL)
4714                 break;
4715               (void) FormatLocaleString(geometry,MaxTextExtent,"%.15gx%.15g",
4716                 image->resolution.x,image->resolution.y);
4717               s=newSVpv(geometry,0);
4718               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4719               continue;
4720             }
4721           if (LocaleCompare(attribute,"delay") == 0)
4722             {
4723               if (image != (Image *) NULL)
4724                 s=newSViv((ssize_t) image->delay);
4725               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4726               continue;
4727             }
4728           if (LocaleCompare(attribute,"depth") == 0)
4729             {
4730               s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4731               if (image != (Image *) NULL)
4732                 s=newSViv((ssize_t) GetImageDepth(image,exception));
4733               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4734               continue;
4735             }
4736           if (LocaleCompare(attribute,"directory") == 0)
4737             {
4738               if (image && image->directory)
4739                 s=newSVpv(image->directory,0);
4740               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4741               continue;
4742             }
4743           if (LocaleCompare(attribute,"dispose") == 0)
4744             {
4745               if (image == (Image *) NULL)
4746                 break;
4747
4748               s=newSViv(image->dispose);
4749               (void) sv_setpv(s,
4750                 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
4751               SvIOK_on(s);
4752               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4753               continue;
4754             }
4755           if (LocaleCompare(attribute,"disk") == 0)
4756             {
4757               s=newSViv(GetMagickResource(DiskResource));
4758               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4759               continue;
4760             }
4761           if (LocaleCompare(attribute,"dither") == 0)
4762             {
4763               if (info)
4764                 s=newSViv((ssize_t) info->image_info->dither);
4765               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4766               continue;
4767             }
4768           if (LocaleCompare(attribute,"display") == 0)  /* same as server */
4769             {
4770               if (info && info->image_info->server_name)
4771                 s=newSVpv(info->image_info->server_name,0);
4772               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4773               continue;
4774             }
4775           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4776             attribute);
4777           break;
4778         }
4779         case 'E':
4780         case 'e':
4781         {
4782           if (LocaleCompare(attribute,"elapsed-time") == 0)
4783             {
4784               if (image != (Image *) NULL)
4785                 s=newSVnv(GetElapsedTime(&image->timer));
4786               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4787               continue;
4788             }
4789           if (LocaleCompare(attribute,"endian") == 0)
4790             {
4791               j=info ? info->image_info->endian : image ? image->endian :
4792                 UndefinedEndian;
4793               s=newSViv(j);
4794               (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
4795               SvIOK_on(s);
4796               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4797               continue;
4798             }
4799           if (LocaleCompare(attribute,"error") == 0)
4800             {
4801               if (image != (Image *) NULL)
4802                 s=newSVnv(image->error.mean_error_per_pixel);
4803               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4804               continue;
4805             }
4806           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4807             attribute);
4808           break;
4809         }
4810         case 'F':
4811         case 'f':
4812         {
4813           if (LocaleCompare(attribute,"filesize") == 0)
4814             {
4815               if (image != (Image *) NULL)
4816                 s=newSViv((ssize_t) GetBlobSize(image));
4817               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4818               continue;
4819             }
4820           if (LocaleCompare(attribute,"filename") == 0)
4821             {
4822               if (info && info->image_info->filename &&
4823                   *info->image_info->filename)
4824                 s=newSVpv(info->image_info->filename,0);
4825               if (image != (Image *) NULL)
4826                 s=newSVpv(image->filename,0);
4827               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4828               continue;
4829             }
4830           if (LocaleCompare(attribute,"filter") == 0)
4831             {
4832               s=image ? newSViv(image->filter) : newSViv(0);
4833               (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
4834                 image->filter));
4835               SvIOK_on(s);
4836               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4837               continue;
4838             }
4839           if (LocaleCompare(attribute,"font") == 0)
4840             {
4841               if (info && info->image_info->font)
4842                 s=newSVpv(info->image_info->font,0);
4843               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4844               continue;
4845             }
4846           if (LocaleCompare(attribute,"foreground") == 0)
4847             continue;
4848           if (LocaleCompare(attribute,"format") == 0)
4849             {
4850               const MagickInfo
4851                 *magick_info;
4852
4853               magick_info=(const MagickInfo *) NULL;
4854               if (info && (*info->image_info->magick != '\0'))
4855                 magick_info=GetMagickInfo(info->image_info->magick,exception);
4856               if (image != (Image *) NULL)
4857                 magick_info=GetMagickInfo(image->magick,exception);
4858               if ((magick_info != (const MagickInfo *) NULL) &&
4859                   (*magick_info->description != '\0'))
4860                 s=newSVpv((char *) magick_info->description,0);
4861               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4862               continue;
4863             }
4864           if (LocaleCompare(attribute,"fuzz") == 0)
4865             {
4866               if (info)
4867                 s=newSVnv(info->image_info->fuzz);
4868               if (image != (Image *) NULL)
4869                 s=newSVnv(image->fuzz);
4870               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4871               continue;
4872             }
4873           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4874             attribute);
4875           break;
4876         }
4877         case 'G':
4878         case 'g':
4879         {
4880           if (LocaleCompare(attribute,"gamma") == 0)
4881             {
4882               if (image != (Image *) NULL)
4883                 s=newSVnv(image->gamma);
4884               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4885               continue;
4886             }
4887           if (LocaleCompare(attribute,"geometry") == 0)
4888             {
4889               if (image && image->geometry)
4890                 s=newSVpv(image->geometry,0);
4891               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4892               continue;
4893             }
4894           if (LocaleCompare(attribute,"gravity") == 0)
4895             {
4896               s=image ? newSViv(image->gravity) : newSViv(0);
4897               (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
4898                 image->gravity));
4899               SvIOK_on(s);
4900               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4901               continue;
4902             }
4903           if (LocaleCompare(attribute,"green-primary") == 0)
4904             {
4905               if (image == (Image *) NULL)
4906                 break;
4907               (void) FormatLocaleString(color,MaxTextExtent,"%.15g,%.15g",
4908                 image->chromaticity.green_primary.x,
4909                 image->chromaticity.green_primary.y);
4910               s=newSVpv(color,0);
4911               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4912               continue;
4913             }
4914           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4915             attribute);
4916           break;
4917         }
4918         case 'H':
4919         case 'h':
4920         {
4921           if (LocaleCompare(attribute,"height") == 0)
4922             {
4923               if (image != (Image *) NULL)
4924                 s=newSViv((ssize_t) image->rows);
4925               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4926               continue;
4927             }
4928           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4929             attribute);
4930           break;
4931         }
4932         case 'I':
4933         case 'i':
4934         {
4935           if (LocaleCompare(attribute,"icc") == 0)
4936             {
4937               if (image != (Image *) NULL)
4938                 {
4939                   const StringInfo
4940                     *profile;
4941
4942                   profile=GetImageProfile(image,"icc");
4943                   if (profile != (StringInfo *) NULL)
4944                     s=newSVpv((const char *) GetStringInfoDatum(profile),
4945                       GetStringInfoLength(profile));
4946                 }
4947               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4948               continue;
4949             }
4950           if (LocaleCompare(attribute,"icm") == 0)
4951             {
4952               if (image != (Image *) NULL)
4953                 {
4954                   const StringInfo
4955                     *profile;
4956
4957                   profile=GetImageProfile(image,"icm");
4958                   if (profile != (const StringInfo *) NULL)
4959                     s=newSVpv((const char *) GetStringInfoDatum(profile),
4960                       GetStringInfoLength(profile));
4961                 }
4962               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4963               continue;
4964             }
4965           if (LocaleCompare(attribute,"id") == 0)
4966             {
4967               if (image != (Image *) NULL)
4968                 {
4969                   char
4970                     key[MaxTextExtent];
4971
4972                   MagickBooleanType
4973                     status;
4974
4975                   static ssize_t
4976                     id = 0;
4977
4978                   (void) FormatLocaleString(key,MaxTextExtent,"%.20g\n",(double)
4979                     id);
4980                   status=SetImageRegistry(ImageRegistryType,key,image,
4981                     exception);
4982                   (void) status;
4983                   s=newSViv(id++);
4984                 }
4985               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4986               continue;
4987             }
4988           if (LocaleNCompare(attribute,"index",5) == 0)
4989             {
4990               char
4991                 name[MaxTextExtent];
4992
4993               int
4994                 items;
4995
4996               long
4997                 x,
4998                 y;
4999
5000               register const Quantum
5001                 *p;
5002
5003               CacheView
5004                 *image_view;
5005
5006               if (image == (Image *) NULL)
5007                 break;
5008               if (image->storage_class != PseudoClass)
5009                 break;
5010               x=0;
5011               y=0;
5012               items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5013               (void) items;
5014               image_view=AcquireVirtualCacheView(image,exception);
5015               p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5016               if (p != (const Quantum *) NULL)
5017                 {
5018                   (void) FormatLocaleString(name,MaxTextExtent,QuantumFormat,
5019                     GetPixelIndex(image,p));
5020                   s=newSVpv(name,0);
5021                   PUSHs(s ? sv_2mortal(s) : &sv_undef);
5022                 }
5023               image_view=DestroyCacheView(image_view);
5024               continue;
5025             }
5026           if (LocaleCompare(attribute,"iptc") == 0)
5027             {
5028               if (image != (Image *) NULL)
5029                 {
5030                   const StringInfo
5031                     *profile;
5032
5033                   profile=GetImageProfile(image,"iptc");
5034                   if (profile != (const StringInfo *) NULL)
5035                     s=newSVpv((const char *) GetStringInfoDatum(profile),
5036                       GetStringInfoLength(profile));
5037                 }
5038               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5039               continue;
5040             }
5041           if (LocaleCompare(attribute,"iterations") == 0)  /* same as loop */
5042             {
5043               if (image != (Image *) NULL)
5044                 s=newSViv((ssize_t) image->iterations);
5045               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5046               continue;
5047             }
5048           if (LocaleCompare(attribute,"interlace") == 0)
5049             {
5050               j=info ? info->image_info->interlace : image ? image->interlace :
5051                 UndefinedInterlace;
5052               s=newSViv(j);
5053               (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5054                 j));
5055               SvIOK_on(s);
5056               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5057               continue;
5058             }
5059           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5060             attribute);
5061           break;
5062         }
5063         case 'L':
5064         case 'l':
5065         {
5066           if (LocaleCompare(attribute,"label") == 0)
5067             {
5068               const char
5069                 *value;
5070
5071               if (image == (Image *) NULL)
5072                 break;
5073               value=GetImageProperty(image,"Label",exception);
5074               if (value != (const char *) NULL)
5075                 s=newSVpv(value,0);
5076               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5077               continue;
5078             }
5079           if (LocaleCompare(attribute,"loop") == 0)  /* same as iterations */
5080             {
5081               if (image != (Image *) NULL)
5082                 s=newSViv((ssize_t) image->iterations);
5083               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5084               continue;
5085             }
5086           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5087             attribute);
5088           break;
5089         }
5090         case 'M':
5091         case 'm':
5092         {
5093           if (LocaleCompare(attribute,"magick") == 0)
5094             {
5095               if (info && *info->image_info->magick)
5096                 s=newSVpv(info->image_info->magick,0);
5097               if (image != (Image *) NULL)
5098                 s=newSVpv(image->magick,0);
5099               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5100               continue;
5101             }
5102           if (LocaleCompare(attribute,"map") == 0)
5103             {
5104               s=newSViv(GetMagickResource(MapResource));
5105               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5106               continue;
5107             }
5108           if (LocaleCompare(attribute,"maximum-error") == 0)
5109             {
5110               if (image != (Image *) NULL)
5111                 s=newSVnv(image->error.normalized_maximum_error);
5112               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5113               continue;
5114             }
5115           if (LocaleCompare(attribute,"memory") == 0)
5116             {
5117               s=newSViv(GetMagickResource(MemoryResource));
5118               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5119               continue;
5120             }
5121           if (LocaleCompare(attribute,"mean-error") == 0)
5122             {
5123               if (image != (Image *) NULL)
5124                 s=newSVnv(image->error.normalized_mean_error);
5125               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5126               continue;
5127             }
5128           if (LocaleCompare(attribute,"mime") == 0)
5129             {
5130               if (info && *info->image_info->magick)
5131                 s=newSVpv(MagickToMime(info->image_info->magick),0);
5132               if (image != (Image *) NULL)
5133                 s=newSVpv(MagickToMime(image->magick),0);
5134               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5135               continue;
5136             }
5137           if (LocaleCompare(attribute,"mattecolor") == 0)
5138             {
5139               if (image == (Image *) NULL)
5140                 break;
5141               (void) FormatLocaleString(color,MaxTextExtent,
5142                 "%.20g,%.20g,%.20g,%.20g",image->matte_color.red,
5143                 image->matte_color.green,image->matte_color.blue,
5144                 image->matte_color.alpha);
5145               s=newSVpv(color,0);
5146               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5147               continue;
5148             }
5149           if (LocaleCompare(attribute,"matte") == 0)
5150             {
5151               if (image != (Image *) NULL)
5152                 s=newSViv((ssize_t) image->alpha_trait == BlendPixelTrait ?
5153                   1 : 0);
5154               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5155               continue;
5156             }
5157           if (LocaleCompare(attribute,"mime") == 0)
5158             {
5159               const char
5160                 *magick;
5161
5162               magick=NULL;
5163               if (info && *info->image_info->magick)
5164                 magick=info->image_info->magick;
5165               if (image != (Image *) NULL)
5166                 magick=image->magick;
5167               if (magick)
5168                 {
5169                   char
5170                     *mime;
5171
5172                   mime=MagickToMime(magick);
5173                   s=newSVpv(mime,0);
5174                   mime=(char *) RelinquishMagickMemory(mime);
5175                 }
5176               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5177               continue;
5178             }
5179           if (LocaleCompare(attribute,"monochrome") == 0)
5180             {
5181               if (image == (Image *) NULL)
5182                 continue;
5183               j=info ? info->image_info->monochrome :
5184                 IsImageMonochrome(image,exception);
5185               s=newSViv(j);
5186               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5187               continue;
5188             }
5189           if (LocaleCompare(attribute,"montage") == 0)
5190             {
5191               if (image && image->montage)
5192                 s=newSVpv(image->montage,0);
5193               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5194               continue;
5195             }
5196           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5197             attribute);
5198           break;
5199         }
5200         case 'O':
5201         case 'o':
5202         {
5203           if (LocaleCompare(attribute,"orientation") == 0)
5204             {
5205               j=info ? info->image_info->orientation : image ?
5206                 image->orientation : UndefinedOrientation;
5207               s=newSViv(j);
5208               (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5209                 j));
5210               SvIOK_on(s);
5211               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5212               continue;
5213             }
5214           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5215             attribute);
5216           break;
5217         }
5218         case 'P':
5219         case 'p':
5220         {
5221           if (LocaleCompare(attribute,"page") == 0)
5222             {
5223               if (info && info->image_info->page)
5224                 s=newSVpv(info->image_info->page,0);
5225               if (image != (Image *) NULL)
5226                 {
5227                   char
5228                     geometry[MaxTextExtent];
5229
5230                   (void) FormatLocaleString(geometry,MaxTextExtent,
5231                     "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5232                     (double) image->page.height,(double) image->page.x,(double)
5233                     image->page.y);
5234                   s=newSVpv(geometry,0);
5235                 }
5236               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5237               continue;
5238             }
5239           if (LocaleCompare(attribute,"page.x") == 0)
5240             {
5241               if (image != (Image *) NULL)
5242                 s=newSViv((ssize_t) image->page.x);
5243               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5244               continue;
5245             }
5246           if (LocaleCompare(attribute,"page.y") == 0)
5247             {
5248               if (image != (Image *) NULL)
5249                 s=newSViv((ssize_t) image->page.y);
5250               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5251               continue;
5252             }
5253           if (LocaleNCompare(attribute,"pixel",5) == 0)
5254             {
5255               char
5256                 tuple[MaxTextExtent];
5257
5258               int
5259                 items;
5260
5261               long
5262                 x,
5263                 y;
5264
5265               register const Quantum
5266                 *p;
5267
5268               if (image == (Image *) NULL)
5269                 break;
5270               x=0;
5271               y=0;
5272               items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5273               (void) items;
5274               p=GetVirtualPixels(image,x,y,1,1,exception);
5275               if (image->colorspace != CMYKColorspace)
5276                 (void) FormatLocaleString(tuple,MaxTextExtent,QuantumFormat ","
5277                   QuantumFormat "," QuantumFormat "," QuantumFormat,
5278                   GetPixelRed(image,p),GetPixelGreen(image,p),
5279                   GetPixelBlue(image,p),GetPixelAlpha(image,p));
5280               else
5281                 (void) FormatLocaleString(tuple,MaxTextExtent,QuantumFormat ","
5282                   QuantumFormat "," QuantumFormat "," QuantumFormat ","
5283                   QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5284                   GetPixelBlue(image,p),GetPixelBlack(image,p),
5285                   GetPixelAlpha(image,p));
5286               s=newSVpv(tuple,0);
5287               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5288               continue;
5289             }
5290           if (LocaleCompare(attribute,"pointsize") == 0)
5291             {
5292               if (info)
5293                 s=newSViv((ssize_t) info->image_info->pointsize);
5294               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5295               continue;
5296             }
5297           if (LocaleCompare(attribute,"preview") == 0)
5298             {
5299               s=newSViv(info->image_info->preview_type);
5300               (void) sv_setpv(s,CommandOptionToMnemonic(MagickPreviewOptions,
5301                 info->image_info->preview_type));
5302               SvIOK_on(s);
5303               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5304               continue;
5305             }
5306           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5307             attribute);
5308           break;
5309         }
5310         case 'Q':
5311         case 'q':
5312         {
5313           if (LocaleCompare(attribute,"quality") == 0)
5314             {
5315               if (info)
5316                 s=newSViv((ssize_t) info->image_info->quality);
5317               if (image != (Image *) NULL)
5318                 s=newSViv((ssize_t) image->quality);
5319               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5320               continue;
5321             }
5322           if (LocaleCompare(attribute,"quantum") == 0)
5323             {
5324               if (info)
5325                 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5326               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5327               continue;
5328             }
5329           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5330             attribute);
5331           break;
5332         }
5333         case 'R':
5334         case 'r':
5335         {
5336           if (LocaleCompare(attribute,"rendering-intent") == 0)
5337             {
5338               s=newSViv(image->rendering_intent);
5339               (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5340                 image->rendering_intent));
5341               SvIOK_on(s);
5342               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5343               continue;
5344             }
5345           if (LocaleCompare(attribute,"red-primary") == 0)
5346             {
5347               if (image == (Image *) NULL)
5348                 break;
5349               (void) FormatLocaleString(color,MaxTextExtent,"%.15g,%.15g",
5350                 image->chromaticity.red_primary.x,
5351                 image->chromaticity.red_primary.y);
5352               s=newSVpv(color,0);
5353               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5354               continue;
5355             }
5356           if (LocaleCompare(attribute,"rows") == 0)
5357             {
5358               if (image != (Image *) NULL)
5359                 s=newSViv((ssize_t) image->rows);
5360               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5361               continue;
5362             }
5363           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5364             attribute);
5365           break;
5366         }
5367         case 'S':
5368         case 's':
5369         {
5370           if (LocaleCompare(attribute,"sampling-factor") == 0)
5371             {
5372               if (info && info->image_info->sampling_factor)
5373                 s=newSVpv(info->image_info->sampling_factor,0);
5374               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5375               continue;
5376             }
5377           if (LocaleCompare(attribute,"server") == 0)  /* same as display */
5378             {
5379               if (info && info->image_info->server_name)
5380                 s=newSVpv(info->image_info->server_name,0);
5381               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5382               continue;
5383             }
5384           if (LocaleCompare(attribute,"size") == 0)
5385             {
5386               if (info && info->image_info->size)
5387                 s=newSVpv(info->image_info->size,0);
5388               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5389               continue;
5390             }
5391           if (LocaleCompare(attribute,"scene") == 0)
5392             {
5393               if (image != (Image *) NULL)
5394                 s=newSViv((ssize_t) image->scene);
5395               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5396               continue;
5397             }
5398           if (LocaleCompare(attribute,"scenes") == 0)
5399             {
5400               if (image != (Image *) NULL)
5401                 s=newSViv((ssize_t) info->image_info->number_scenes);
5402               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5403               continue;
5404             }
5405           if (LocaleCompare(attribute,"signature") == 0)
5406             {
5407               const char
5408                 *value;
5409
5410               if (image == (Image *) NULL)
5411                 break;
5412               (void) SignatureImage(image,exception);
5413               value=GetImageProperty(image,"Signature",exception);
5414               if (value != (const char *) NULL)
5415                 s=newSVpv(value,0);
5416               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5417               continue;
5418             }
5419           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5420             attribute);
5421           break;
5422         }
5423         case 'T':
5424         case 't':
5425         {
5426           if (LocaleCompare(attribute,"taint") == 0)
5427             {
5428               if (image != (Image *) NULL)
5429                 s=newSViv((ssize_t) IsTaintImage(image));
5430               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5431               continue;
5432             }
5433           if (LocaleCompare(attribute,"texture") == 0)
5434             {
5435               if (info && info->image_info->texture)
5436                 s=newSVpv(info->image_info->texture,0);
5437               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5438               continue;
5439             }
5440           if (LocaleCompare(attribute,"total-ink-density") == 0)
5441             {
5442               s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5443               if (image != (Image *) NULL)
5444                 s=newSVnv(GetImageTotalInkDensity(image,exception));
5445               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5446               continue;
5447             }
5448           if (LocaleCompare(attribute,"transparent-color") == 0)
5449             {
5450               if (image == (Image *) NULL)
5451                 break;
5452               (void) FormatLocaleString(color,MaxTextExtent,
5453                 "%.20g,%.20g,%.20g,%.20g",image->transparent_color.red,
5454                 image->transparent_color.green,image->transparent_color.blue,
5455                 image->transparent_color.alpha);
5456               s=newSVpv(color,0);
5457               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5458               continue;
5459             }
5460           if (LocaleCompare(attribute,"type") == 0)
5461             {
5462               if (image == (Image *) NULL)
5463                 break;
5464               j=(ssize_t) GetImageType(image,exception);
5465               s=newSViv(j);
5466               (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5467               SvIOK_on(s);
5468               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5469               continue;
5470             }
5471           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5472             attribute);
5473           break;
5474         }
5475         case 'U':
5476         case 'u':
5477         {
5478           if (LocaleCompare(attribute,"units") == 0)
5479             {
5480               j=info ? info->image_info->units : image ? image->units :
5481                 UndefinedResolution;
5482               if (info && (info->image_info->units == UndefinedResolution))
5483                 if (image)
5484                   j=image->units;
5485               if (j == UndefinedResolution)
5486                 s=newSVpv("undefined units",0);
5487               else
5488                 if (j == PixelsPerInchResolution)
5489                   s=newSVpv("pixels / inch",0);
5490                 else
5491                   s=newSVpv("pixels / centimeter",0);
5492               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5493               continue;
5494             }
5495           if (LocaleCompare(attribute,"user-time") == 0)
5496             {
5497               if (image != (Image *) NULL)
5498                 s=newSVnv(GetUserTime(&image->timer));
5499               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5500               continue;
5501             }
5502           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5503             attribute);
5504           break;
5505         }
5506         case 'V':
5507         case 'v':
5508         {
5509           if (LocaleCompare(attribute,"verbose") == 0)
5510             {
5511               if (info)
5512                 s=newSViv((ssize_t) info->image_info->verbose);
5513               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5514               continue;
5515             }
5516           if (LocaleCompare(attribute,"version") == 0)
5517             {
5518               s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5519               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5520               continue;
5521             }
5522           if (LocaleCompare(attribute,"view") == 0)
5523             {
5524               if (info && info->image_info->view)
5525                 s=newSVpv(info->image_info->view,0);
5526               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5527               continue;
5528             }
5529           if (LocaleCompare(attribute,"virtual-pixel") == 0)
5530             {
5531               if (image == (Image *) NULL)
5532                 break;
5533               j=(ssize_t) GetImageVirtualPixelMethod(image);
5534               s=newSViv(j);
5535               (void) sv_setpv(s,CommandOptionToMnemonic(
5536                 MagickVirtualPixelOptions,j));
5537               SvIOK_on(s);
5538               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5539               continue;
5540             }
5541           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5542             attribute);
5543           break;
5544         }
5545         case 'W':
5546         case 'w':
5547         {
5548           if (LocaleCompare(attribute,"white-point") == 0)
5549             {
5550               if (image == (Image *) NULL)
5551                 break;
5552               (void) FormatLocaleString(color,MaxTextExtent,"%.15g,%.15g",
5553                 image->chromaticity.white_point.x,
5554                 image->chromaticity.white_point.y);
5555               s=newSVpv(color,0);
5556               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5557               continue;
5558             }
5559           if (LocaleCompare(attribute,"width") == 0)
5560             {
5561               if (image != (Image *) NULL)
5562                 s=newSViv((ssize_t) image->columns);
5563               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5564               continue;
5565             }
5566           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5567              attribute);
5568           break;
5569         }
5570         case 'X':
5571         case 'x':
5572         {
5573           if (LocaleCompare(attribute,"x-resolution") == 0)
5574             {
5575               if (image != (Image *) NULL)
5576                 s=newSVnv(image->resolution.x);
5577               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5578               continue;
5579             }
5580           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5581             attribute);
5582           break;
5583         }
5584         case 'Y':
5585         case 'y':
5586         {
5587           if (LocaleCompare(attribute,"y-resolution") == 0)
5588             {
5589               if (image != (Image *) NULL)
5590                 s=newSVnv(image->resolution.y);
5591               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5592               continue;
5593             }
5594           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5595             attribute);
5596           break;
5597         }
5598         default:
5599           break;
5600       }
5601       if (image == (Image *) NULL)
5602         ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5603           attribute)
5604       else
5605         {
5606           value=GetImageProperty(image,attribute,exception);
5607           if (value != (const char *) NULL)
5608             {
5609               s=newSVpv(value,0);
5610               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5611             }
5612           else
5613             if (*attribute != '%')
5614               ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5615                 attribute)
5616             else
5617               {
5618                  char
5619                    *meta;
5620
5621                  meta=InterpretImageProperties(info ? info->image_info :
5622                    (ImageInfo *) NULL,image,attribute,exception);
5623                  s=newSVpv(meta,0);
5624                  PUSHs(s ? sv_2mortal(s) : &sv_undef);
5625                  meta=(char *) RelinquishMagickMemory(meta);
5626               }
5627         }
5628     }
5629     exception=DestroyExceptionInfo(exception);
5630     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
5631   }
5632 \f
5633 #
5634 ###############################################################################
5635 #                                                                             #
5636 #                                                                             #
5637 #                                                                             #
5638 #   G e t A u t h e n t i c P i x e l s                                       #
5639 #                                                                             #
5640 #                                                                             #
5641 #                                                                             #
5642 ###############################################################################
5643 #
5644 #
5645 void *
5646 GetAuthenticPixels(ref,...)
5647   Image::Magick::Q16HDRI ref = NO_INIT
5648   ALIAS:
5649     getauthenticpixels = 1
5650     GetImagePixels = 2
5651     getimagepixels = 3
5652   CODE:
5653   {
5654     char
5655       *attribute;
5656
5657     ExceptionInfo
5658       *exception;
5659
5660     Image
5661       *image;
5662
5663     RectangleInfo
5664       region;
5665
5666     ssize_t
5667       i;
5668
5669     struct PackageInfo
5670       *info;
5671
5672     SV
5673       *perl_exception,
5674       *reference;
5675
5676     void
5677       *blob = NULL;
5678
5679     PERL_UNUSED_VAR(ref);
5680     PERL_UNUSED_VAR(ix);
5681     exception=AcquireExceptionInfo();
5682     perl_exception=newSVpv("",0);
5683     if (sv_isobject(ST(0)) == 0)
5684       {
5685         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5686           PackageName);
5687         goto PerlException;
5688       }
5689     reference=SvRV(ST(0));
5690
5691     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5692     if (image == (Image *) NULL)
5693       {
5694         ThrowPerlException(exception,OptionError,"NoImagesDefined",
5695           PackageName);
5696         goto PerlException;
5697       }
5698
5699     region.x=0;
5700     region.y=0;
5701     region.width=image->columns;
5702     region.height=1;
5703     if (items == 1)
5704       (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5705     for (i=2; i < items; i+=2)
5706     {
5707       attribute=(char *) SvPV(ST(i-1),na);
5708       switch (*attribute)
5709       {
5710         case 'g':
5711         case 'G':
5712         {
5713           if (LocaleCompare(attribute,"geometry") == 0)
5714             {
5715               (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5716               break;
5717             }
5718           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5719             attribute);
5720           break;
5721         }
5722         case 'H':
5723         case 'h':
5724         {
5725           if (LocaleCompare(attribute,"height") == 0)
5726             {
5727               region.height=SvIV(ST(i));
5728               continue;
5729             }
5730           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5731             attribute);
5732           break;
5733         }
5734         case 'X':
5735         case 'x':
5736         {
5737           if (LocaleCompare(attribute,"x") == 0)
5738             {
5739               region.x=SvIV(ST(i));
5740               continue;
5741             }
5742           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5743             attribute);
5744           break;
5745         }
5746         case 'Y':
5747         case 'y':
5748         {
5749           if (LocaleCompare(attribute,"y") == 0)
5750             {
5751               region.y=SvIV(ST(i));
5752               continue;
5753             }
5754           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5755             attribute);
5756           break;
5757         }
5758         case 'W':
5759         case 'w':
5760         {
5761           if (LocaleCompare(attribute,"width") == 0)
5762             {
5763               region.width=SvIV(ST(i));
5764               continue;
5765             }
5766           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5767             attribute);
5768           break;
5769         }
5770       }
5771     }
5772     blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
5773       region.height,exception);
5774     if (blob != (void *) NULL)
5775       goto PerlEnd;
5776
5777   PerlException:
5778     InheritPerlException(exception,perl_exception);
5779     exception=DestroyExceptionInfo(exception);
5780     SvREFCNT_dec(perl_exception);  /* throw away all errors */
5781
5782   PerlEnd:
5783     RETVAL = blob;
5784   }
5785   OUTPUT:
5786     RETVAL
5787 \f
5788 #
5789 ###############################################################################
5790 #                                                                             #
5791 #                                                                             #
5792 #                                                                             #
5793 #   G e t V i r t u a l P i x e l s                                           #
5794 #                                                                             #
5795 #                                                                             #
5796 #                                                                             #
5797 ###############################################################################
5798 #
5799 #
5800 void *
5801 GetVirtualPixels(ref,...)
5802   Image::Magick::Q16HDRI ref = NO_INIT
5803   ALIAS:
5804     getvirtualpixels = 1
5805     AcquireImagePixels = 2
5806     acquireimagepixels = 3
5807   CODE:
5808   {
5809     char
5810       *attribute;
5811
5812     const void
5813       *blob = NULL;
5814
5815     ExceptionInfo
5816       *exception;
5817
5818     Image
5819       *image;
5820
5821     RectangleInfo
5822       region;
5823
5824     ssize_t
5825       i;
5826
5827     struct PackageInfo
5828       *info;
5829
5830     SV
5831       *perl_exception,
5832       *reference;
5833
5834     PERL_UNUSED_VAR(ref);
5835     PERL_UNUSED_VAR(ix);
5836     exception=AcquireExceptionInfo();
5837     perl_exception=newSVpv("",0);
5838     if (sv_isobject(ST(0)) == 0)
5839       {
5840         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5841           PackageName);
5842         goto PerlException;
5843       }
5844     reference=SvRV(ST(0));
5845
5846     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5847     if (image == (Image *) NULL)
5848       {
5849         ThrowPerlException(exception,OptionError,"NoImagesDefined",
5850           PackageName);
5851         goto PerlException;
5852       }
5853
5854     region.x=0;
5855     region.y=0;
5856     region.width=image->columns;
5857     region.height=1;
5858     if (items == 1)
5859       (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5860     for (i=2; i < items; i+=2)
5861     {
5862       attribute=(char *) SvPV(ST(i-1),na);
5863       switch (*attribute)
5864       {
5865         case 'g':
5866         case 'G':
5867         {
5868           if (LocaleCompare(attribute,"geometry") == 0)
5869             {
5870               (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5871               break;
5872             }
5873           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5874             attribute);
5875           break;
5876         }
5877         case 'H':
5878         case 'h':
5879         {
5880           if (LocaleCompare(attribute,"height") == 0)
5881             {
5882               region.height=SvIV(ST(i));
5883               continue;
5884             }
5885           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5886             attribute);
5887           break;
5888         }
5889         case 'X':
5890         case 'x':
5891         {
5892           if (LocaleCompare(attribute,"x") == 0)
5893             {
5894               region.x=SvIV(ST(i));
5895               continue;
5896             }
5897           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5898             attribute);
5899           break;
5900         }
5901         case 'Y':
5902         case 'y':
5903         {
5904           if (LocaleCompare(attribute,"y") == 0)
5905             {
5906               region.y=SvIV(ST(i));
5907               continue;
5908             }
5909           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5910             attribute);
5911           break;
5912         }
5913         case 'W':
5914         case 'w':
5915         {
5916           if (LocaleCompare(attribute,"width") == 0)
5917             {
5918               region.width=SvIV(ST(i));
5919               continue;
5920             }
5921           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5922             attribute);
5923           break;
5924         }
5925       }
5926     }
5927     blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
5928       region.height,exception);
5929     if (blob != (void *) NULL)
5930       goto PerlEnd;
5931
5932   PerlException:
5933     InheritPerlException(exception,perl_exception);
5934     exception=DestroyExceptionInfo(exception);
5935     SvREFCNT_dec(perl_exception);  /* throw away all errors */
5936
5937   PerlEnd:
5938     RETVAL = (void *) blob;
5939   }
5940   OUTPUT:
5941     RETVAL
5942 \f
5943 #
5944 ###############################################################################
5945 #                                                                             #
5946 #                                                                             #
5947 #                                                                             #
5948 #   G e t A u t h e n t i c M e t a c o n t e n t                             #
5949 #                                                                             #
5950 #                                                                             #
5951 #                                                                             #
5952 ###############################################################################
5953 #
5954 #
5955 void *
5956 GetAuthenticMetacontent(ref,...)
5957   Image::Magick::Q16HDRI ref = NO_INIT
5958   ALIAS:
5959     getauthenticmetacontent = 1
5960     GetMetacontent = 2
5961     getmetacontent = 3
5962   CODE:
5963   {
5964     ExceptionInfo
5965       *exception;
5966
5967     Image
5968       *image;
5969
5970     struct PackageInfo
5971       *info;
5972
5973     SV
5974       *perl_exception,
5975       *reference;
5976
5977     void
5978       *blob = NULL;
5979
5980     PERL_UNUSED_VAR(ref);
5981     PERL_UNUSED_VAR(ix);
5982     exception=AcquireExceptionInfo();
5983     perl_exception=newSVpv("",0);
5984     if (sv_isobject(ST(0)) == 0)
5985       {
5986         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5987           PackageName);
5988         goto PerlException;
5989       }
5990     reference=SvRV(ST(0));
5991
5992     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5993     if (image == (Image *) NULL)
5994       {
5995         ThrowPerlException(exception,OptionError,"NoImagesDefined",
5996           PackageName);
5997         goto PerlException;
5998       }
5999
6000     blob=(void *) GetAuthenticMetacontent(image);
6001     if (blob != (void *) NULL)
6002       goto PerlEnd;
6003
6004   PerlException:
6005     InheritPerlException(exception,perl_exception);
6006     exception=DestroyExceptionInfo(exception);
6007     SvREFCNT_dec(perl_exception);  /* throw away all errors */
6008
6009   PerlEnd:
6010     RETVAL = blob;
6011   }
6012   OUTPUT:
6013     RETVAL
6014 \f
6015 #
6016 ###############################################################################
6017 #                                                                             #
6018 #                                                                             #
6019 #                                                                             #
6020 #   G e t V i r t u a l M e t a c o n t e n t                                 #
6021 #                                                                             #
6022 #                                                                             #
6023 #                                                                             #
6024 ###############################################################################
6025 #
6026 #
6027 void *
6028 GetVirtualMetacontent(ref,...)
6029   Image::Magick::Q16HDRI ref = NO_INIT
6030   ALIAS:
6031     getvirtualmetacontent = 1
6032   CODE:
6033   {
6034     ExceptionInfo
6035       *exception;
6036
6037     Image
6038       *image;
6039
6040     struct PackageInfo
6041       *info;
6042
6043     SV
6044       *perl_exception,
6045       *reference;
6046
6047     void
6048       *blob = NULL;
6049
6050     PERL_UNUSED_VAR(ref);
6051     PERL_UNUSED_VAR(ix);
6052     exception=AcquireExceptionInfo();
6053     perl_exception=newSVpv("",0);
6054     if (sv_isobject(ST(0)) == 0)
6055       {
6056         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6057           PackageName);
6058         goto PerlException;
6059       }
6060     reference=SvRV(ST(0));
6061
6062     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6063     if (image == (Image *) NULL)
6064       {
6065         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6066           PackageName);
6067         goto PerlException;
6068       }
6069
6070     blob=(void *) GetVirtualMetacontent(image);
6071     if (blob != (void *) NULL)
6072       goto PerlEnd;
6073
6074   PerlException:
6075     InheritPerlException(exception,perl_exception);
6076     exception=DestroyExceptionInfo(exception);
6077     SvREFCNT_dec(perl_exception);  /* throw away all errors */
6078
6079   PerlEnd:
6080     RETVAL = blob;
6081   }
6082   OUTPUT:
6083     RETVAL
6084 \f
6085 #
6086 ###############################################################################
6087 #                                                                             #
6088 #                                                                             #
6089 #                                                                             #
6090 #   H i s t o g r a m                                                         #
6091 #                                                                             #
6092 #                                                                             #
6093 #                                                                             #
6094 ###############################################################################
6095 #
6096 #
6097 void
6098 Histogram(ref,...)
6099   Image::Magick::Q16HDRI ref=NO_INIT
6100   ALIAS:
6101     HistogramImage = 1
6102     histogram      = 2
6103     histogramimage = 3
6104   PPCODE:
6105   {
6106     AV
6107       *av;
6108
6109     char
6110       message[MaxTextExtent];
6111
6112     PixelInfo
6113       *histogram;
6114
6115     ExceptionInfo
6116       *exception;
6117
6118     Image
6119       *image;
6120
6121     register ssize_t
6122       i;
6123
6124     ssize_t
6125       count;
6126
6127     struct PackageInfo
6128       *info;
6129
6130     SV
6131       *perl_exception,
6132       *reference;
6133
6134     size_t
6135       number_colors;
6136
6137     PERL_UNUSED_VAR(ref);
6138     PERL_UNUSED_VAR(ix);
6139     exception=AcquireExceptionInfo();
6140     perl_exception=newSVpv("",0);
6141     av=NULL;
6142     if (sv_isobject(ST(0)) == 0)
6143       {
6144         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6145           PackageName);
6146         goto PerlException;
6147       }
6148     reference=SvRV(ST(0));
6149     av=newAV();
6150     SvREFCNT_dec(av);
6151     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6152     if (image == (Image *) NULL)
6153       {
6154         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6155           PackageName);
6156         goto PerlException;
6157       }
6158     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
6159     count=0;
6160     for ( ; image; image=image->next)
6161     {
6162       histogram=GetImageHistogram(image,&number_colors,exception);
6163       if (histogram == (PixelInfo *) NULL)
6164         continue;
6165       count+=(ssize_t) number_colors;
6166       EXTEND(sp,6*count);
6167       for (i=0; i < (ssize_t) number_colors; i++)
6168       {
6169         (void) FormatLocaleString(message,MaxTextExtent,"%.20g",
6170           histogram[i].red);
6171         PUSHs(sv_2mortal(newSVpv(message,0)));
6172         (void) FormatLocaleString(message,MaxTextExtent,"%.20g",
6173           histogram[i].green);
6174         PUSHs(sv_2mortal(newSVpv(message,0)));
6175         (void) FormatLocaleString(message,MaxTextExtent,"%.20g",
6176           histogram[i].blue);
6177         PUSHs(sv_2mortal(newSVpv(message,0)));
6178         if (image->colorspace == CMYKColorspace)
6179           {
6180             (void) FormatLocaleString(message,MaxTextExtent,"%.20g",
6181               histogram[i].black);
6182             PUSHs(sv_2mortal(newSVpv(message,0)));
6183           }
6184         (void) FormatLocaleString(message,MaxTextExtent,"%.20g",
6185           histogram[i].alpha);
6186         PUSHs(sv_2mortal(newSVpv(message,0)));
6187         (void) FormatLocaleString(message,MaxTextExtent,"%.20g",(double)
6188           histogram[i].count);
6189         PUSHs(sv_2mortal(newSVpv(message,0)));
6190       }
6191       histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6192     }
6193
6194   PerlException:
6195     InheritPerlException(exception,perl_exception);
6196     exception=DestroyExceptionInfo(exception);
6197     SvREFCNT_dec(perl_exception);
6198   }
6199 \f
6200 #
6201 ###############################################################################
6202 #                                                                             #
6203 #                                                                             #
6204 #                                                                             #
6205 #   G e t P i x e l                                                           #
6206 #                                                                             #
6207 #                                                                             #
6208 #                                                                             #
6209 ###############################################################################
6210 #
6211 #
6212 void
6213 GetPixel(ref,...)
6214   Image::Magick::Q16HDRI ref=NO_INIT
6215   ALIAS:
6216     getpixel = 1
6217     getPixel = 2
6218   PPCODE:
6219   {
6220     AV
6221       *av;
6222
6223     char
6224       *attribute;
6225
6226     ExceptionInfo
6227       *exception;
6228
6229     Image
6230       *image;
6231
6232     MagickBooleanType
6233       normalize;
6234
6235     RectangleInfo
6236       region;
6237
6238     register const Quantum
6239       *p;
6240
6241     register ssize_t
6242       i;
6243
6244     ssize_t
6245       option;
6246
6247     struct PackageInfo
6248       *info;
6249
6250     SV
6251       *perl_exception,
6252       *reference;  /* reference is the SV* of ref=SvIV(reference) */
6253
6254     PERL_UNUSED_VAR(ref);
6255     PERL_UNUSED_VAR(ix);
6256     exception=AcquireExceptionInfo();
6257     perl_exception=newSVpv("",0);
6258     reference=SvRV(ST(0));
6259     av=(AV *) reference;
6260     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6261       exception);
6262     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6263     if (image == (Image *) NULL)
6264       {
6265         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6266           PackageName);
6267         goto PerlException;
6268       }
6269     normalize=MagickTrue;
6270     region.x=0;
6271     region.y=0;
6272     region.width=image->columns;
6273     region.height=1;
6274     if (items == 1)
6275       (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6276     for (i=2; i < items; i+=2)
6277     {
6278       attribute=(char *) SvPV(ST(i-1),na);
6279       switch (*attribute)
6280       {
6281         case 'C':
6282         case 'c':
6283         {
6284           if (LocaleCompare(attribute,"channel") == 0)
6285             {
6286               ssize_t
6287                 option;
6288
6289               option=ParseChannelOption(SvPV(ST(i),na));
6290               if (option < 0)
6291                 {
6292                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
6293                     SvPV(ST(i),na));
6294                   return;
6295                 }
6296               SetPixelChannelMask(image,(ChannelType) option);
6297               break;
6298             }
6299           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6300             attribute);
6301           break;
6302         }
6303         case 'g':
6304         case 'G':
6305         {
6306           if (LocaleCompare(attribute,"geometry") == 0)
6307             {
6308               (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6309               break;
6310             }
6311           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6312             attribute);
6313           break;
6314         }
6315         case 'N':
6316         case 'n':
6317         {
6318           if (LocaleCompare(attribute,"normalize") == 0)
6319             {
6320               option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6321                 SvPV(ST(i),na));
6322               if (option < 0)
6323                 {
6324                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
6325                     SvPV(ST(i),na));
6326                   break;
6327                 }
6328              normalize=option != 0 ? MagickTrue : MagickFalse;
6329              break;
6330             }
6331           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6332             attribute);
6333           break;
6334         }
6335         case 'x':
6336         case 'X':
6337         {
6338           if (LocaleCompare(attribute,"x") == 0)
6339             {
6340               region.x=SvIV(ST(i));
6341               break;
6342             }
6343           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6344             attribute);
6345           break;
6346         }
6347         case 'y':
6348         case 'Y':
6349         {
6350           if (LocaleCompare(attribute,"y") == 0)
6351             {
6352               region.y=SvIV(ST(i));
6353               break;
6354             }
6355           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6356             attribute);
6357           break;
6358         }
6359         default:
6360         {
6361           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6362             attribute);
6363           break;
6364         }
6365       }
6366     }
6367     p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6368     if (p == (const Quantum *) NULL)
6369       PUSHs(&sv_undef);
6370     else
6371       {
6372         double
6373           scale;
6374
6375         scale=1.0;
6376         if (normalize != MagickFalse)
6377           scale=1.0/QuantumRange;
6378         if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6379           PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6380         if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6381           PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6382         if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6383           PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6384         if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6385             (image->colorspace == CMYKColorspace))
6386           PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6387         if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6388           PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6389       }
6390
6391   PerlException:
6392     InheritPerlException(exception,perl_exception);
6393     exception=DestroyExceptionInfo(exception);
6394     SvREFCNT_dec(perl_exception);
6395   }
6396 \f
6397 #
6398 ###############################################################################
6399 #                                                                             #
6400 #                                                                             #
6401 #                                                                             #
6402 #   G e t P i x e l s                                                         #
6403 #                                                                             #
6404 #                                                                             #
6405 #                                                                             #
6406 ###############################################################################
6407 #
6408 #
6409 void
6410 GetPixels(ref,...)
6411   Image::Magick::Q16HDRI ref=NO_INIT
6412   ALIAS:
6413     getpixels = 1
6414     getPixels = 2
6415   PPCODE:
6416   {
6417     AV
6418       *av;
6419
6420     char
6421       *attribute;
6422
6423     const char
6424       *map;
6425
6426     ExceptionInfo
6427       *exception;
6428
6429     Image
6430       *image;
6431
6432     MagickBooleanType
6433       normalize,
6434       status;
6435
6436     RectangleInfo
6437       region;
6438
6439     register ssize_t
6440       i;
6441
6442     ssize_t
6443       option;
6444
6445     struct PackageInfo
6446       *info;
6447
6448     SV
6449       *perl_exception,
6450       *reference;  /* reference is the SV* of ref=SvIV(reference) */
6451
6452     PERL_UNUSED_VAR(ref);
6453     PERL_UNUSED_VAR(ix);
6454     exception=AcquireExceptionInfo();
6455     perl_exception=newSVpv("",0);
6456     reference=SvRV(ST(0));
6457     av=(AV *) reference;
6458     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6459       exception);
6460     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6461     if (image == (Image *) NULL)
6462       {
6463         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6464           PackageName);
6465         goto PerlException;
6466       }
6467     map="RGB";
6468     if (image->alpha_trait == BlendPixelTrait)
6469       map="RGBA";
6470     if (image->colorspace == CMYKColorspace)
6471       {
6472         map="CMYK";
6473         if (image->alpha_trait == BlendPixelTrait)
6474           map="CMYKA";
6475       }
6476     normalize=MagickFalse;
6477     region.x=0;
6478     region.y=0;
6479     region.width=image->columns;
6480     region.height=1;
6481     if (items == 1)
6482       (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6483     for (i=2; i < items; i+=2)
6484     {
6485       attribute=(char *) SvPV(ST(i-1),na);
6486       switch (*attribute)
6487       {
6488         case 'g':
6489         case 'G':
6490         {
6491           if (LocaleCompare(attribute,"geometry") == 0)
6492             {
6493               (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6494               break;
6495             }
6496           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6497             attribute);
6498           break;
6499         }
6500         case 'H':
6501         case 'h':
6502         {
6503           if (LocaleCompare(attribute,"height") == 0)
6504             {
6505               region.height=SvIV(ST(i));
6506               break;
6507             }
6508           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6509             attribute);
6510           break;
6511         }
6512         case 'M':
6513         case 'm':
6514         {
6515           if (LocaleCompare(attribute,"map") == 0)
6516             {
6517               map=SvPV(ST(i),na);
6518               break;
6519             }
6520           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6521             attribute);
6522           break;
6523         }
6524         case 'N':
6525         case 'n':
6526         {
6527           if (LocaleCompare(attribute,"normalize") == 0)
6528             {
6529               option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6530                 SvPV(ST(i),na));
6531               if (option < 0)
6532                 {
6533                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
6534                     SvPV(ST(i),na));
6535                   break;
6536                 }
6537              normalize=option != 0 ? MagickTrue : MagickFalse;
6538              break;
6539             }
6540           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6541             attribute);
6542           break;
6543         }
6544         case 'W':
6545         case 'w':
6546         {
6547           if (LocaleCompare(attribute,"width") == 0)
6548             {
6549               region.width=SvIV(ST(i));
6550               break;
6551             }
6552           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6553             attribute);
6554           break;
6555         }
6556         case 'x':
6557         case 'X':
6558         {
6559           if (LocaleCompare(attribute,"x") == 0)
6560             {
6561               region.x=SvIV(ST(i));
6562               break;
6563             }
6564           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6565             attribute);
6566           break;
6567         }
6568         case 'y':
6569         case 'Y':
6570         {
6571           if (LocaleCompare(attribute,"y") == 0)
6572             {
6573               region.y=SvIV(ST(i));
6574               break;
6575             }
6576           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6577             attribute);
6578           break;
6579         }
6580         default:
6581         {
6582           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6583             attribute);
6584           break;
6585         }
6586       }
6587     }
6588     if (normalize != MagickFalse)
6589       {
6590         float
6591           *pixels;
6592
6593         pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6594           region.height*sizeof(*pixels));
6595         if (pixels == (float *) NULL)
6596           {
6597             ThrowPerlException(exception,ResourceLimitError,
6598               "MemoryAllocationFailed",PackageName);
6599             goto PerlException;
6600           }
6601         status=ExportImagePixels(image,region.x,region.y,region.width,
6602           region.height,map,FloatPixel,pixels,exception);
6603         if (status == MagickFalse)
6604           PUSHs(&sv_undef);
6605         else
6606           {
6607             EXTEND(sp,strlen(map)*region.width*region.height);
6608             for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6609               PUSHs(sv_2mortal(newSVnv(pixels[i])));
6610           }
6611         pixels=(float *) RelinquishMagickMemory(pixels);
6612       }
6613     else
6614       {
6615         Quantum
6616           *pixels;
6617
6618         pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6619           region.height*sizeof(*pixels));
6620         if (pixels == (Quantum *) NULL)
6621           {
6622             ThrowPerlException(exception,ResourceLimitError,
6623               "MemoryAllocationFailed",PackageName);
6624             goto PerlException;
6625           }
6626         status=ExportImagePixels(image,region.x,region.y,region.width,
6627           region.height,map,QuantumPixel,pixels,exception);
6628         if (status == MagickFalse)
6629           PUSHs(&sv_undef);
6630         else
6631           {
6632             EXTEND(sp,strlen(map)*region.width*region.height);
6633             for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6634               PUSHs(sv_2mortal(newSViv(pixels[i])));
6635           }
6636         pixels=(Quantum *) RelinquishMagickMemory(pixels);
6637       }
6638
6639   PerlException:
6640     InheritPerlException(exception,perl_exception);
6641     exception=DestroyExceptionInfo(exception);
6642     SvREFCNT_dec(perl_exception);
6643   }
6644 \f
6645 #
6646 ###############################################################################
6647 #                                                                             #
6648 #                                                                             #
6649 #                                                                             #
6650 #   I m a g e T o B l o b                                                     #
6651 #                                                                             #
6652 #                                                                             #
6653 #                                                                             #
6654 ###############################################################################
6655 #
6656 #
6657 void
6658 ImageToBlob(ref,...)
6659   Image::Magick::Q16HDRI ref=NO_INIT
6660   ALIAS:
6661     ImageToBlob  = 1
6662     imagetoblob  = 2
6663     toblob       = 3
6664     blob         = 4
6665   PPCODE:
6666   {
6667     char
6668       filename[MaxTextExtent];
6669
6670     ExceptionInfo
6671       *exception;
6672
6673     Image
6674       *image,
6675       *next;
6676
6677     register ssize_t
6678       i;
6679
6680     struct PackageInfo
6681       *info,
6682       *package_info;
6683
6684     size_t
6685       length;
6686
6687     ssize_t
6688       scene;
6689
6690     SV
6691       *perl_exception,
6692       *reference;
6693
6694     void
6695       *blob;
6696
6697     PERL_UNUSED_VAR(ref);
6698     PERL_UNUSED_VAR(ix);
6699     exception=AcquireExceptionInfo();
6700     perl_exception=newSVpv("",0);
6701     package_info=(struct PackageInfo *) NULL;
6702     if (sv_isobject(ST(0)) == 0)
6703       {
6704         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6705           PackageName);
6706         goto PerlException;
6707       }
6708     reference=SvRV(ST(0));
6709     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6710     if (image == (Image *) NULL)
6711       {
6712         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6713           PackageName);
6714         goto PerlException;
6715       }
6716     package_info=ClonePackageInfo(info,exception);
6717     for (i=2; i < items; i+=2)
6718       SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6719     (void) CopyMagickString(filename,package_info->image_info->filename,
6720       MaxTextExtent);
6721     scene=0;
6722     for (next=image; next; next=next->next)
6723     {
6724       (void) CopyMagickString(next->filename,filename,MaxTextExtent);
6725       next->scene=scene++;
6726     }
6727     SetImageInfo(package_info->image_info,(unsigned int)
6728       GetImageListLength(image),exception);
6729     EXTEND(sp,(ssize_t) GetImageListLength(image));
6730     for ( ; image; image=image->next)
6731     {
6732       length=0;
6733       blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6734       if (blob != (char *) NULL)
6735         {
6736           PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6737           blob=(unsigned char *) RelinquishMagickMemory(blob);
6738         }
6739       if (package_info->image_info->adjoin)
6740         break;
6741     }
6742
6743   PerlException:
6744     if (package_info != (struct PackageInfo *) NULL)
6745       DestroyPackageInfo(package_info);
6746     InheritPerlException(exception,perl_exception);
6747     exception=DestroyExceptionInfo(exception);
6748     SvREFCNT_dec(perl_exception);  /* throw away all errors */
6749   }
6750 \f
6751 #
6752 ###############################################################################
6753 #                                                                             #
6754 #                                                                             #
6755 #                                                                             #
6756 #   L a y e r s                                                               #
6757 #                                                                             #
6758 #                                                                             #
6759 #                                                                             #
6760 ###############################################################################
6761 #
6762 #
6763 void
6764 Layers(ref,...)
6765   Image::Magick::Q16HDRI ref=NO_INIT
6766   ALIAS:
6767     Layers                = 1
6768     layers           = 2
6769     OptimizeImageLayers   = 3
6770     optimizelayers        = 4
6771     optimizeimagelayers   = 5
6772   PPCODE:
6773   {
6774     AV
6775       *av;
6776
6777     char
6778       *attribute;
6779
6780     CompositeOperator
6781       compose;
6782
6783     ExceptionInfo
6784       *exception;
6785
6786     HV
6787       *hv;
6788
6789     Image
6790       *image,
6791       *layers;
6792
6793     LayerMethod
6794       method;
6795
6796     register ssize_t
6797       i;
6798
6799     ssize_t
6800       option,
6801       sp;
6802
6803     struct PackageInfo
6804       *info;
6805
6806     SV
6807       *av_reference,
6808       *perl_exception,
6809       *reference,
6810       *rv,
6811       *sv;
6812
6813     PERL_UNUSED_VAR(ref);
6814     PERL_UNUSED_VAR(ix);
6815     exception=AcquireExceptionInfo();
6816     perl_exception=newSVpv("",0);
6817     sv=NULL;
6818     if (sv_isobject(ST(0)) == 0)
6819       {
6820         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6821           PackageName);
6822         goto PerlException;
6823       }
6824     reference=SvRV(ST(0));
6825     hv=SvSTASH(reference);
6826     av=newAV();
6827     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
6828     SvREFCNT_dec(av);
6829     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6830     if (image == (Image *) NULL)
6831       {
6832         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6833           PackageName);
6834         goto PerlException;
6835       }
6836     compose=image->compose;
6837     method=OptimizeLayer;
6838     for (i=2; i < items; i+=2)
6839     {
6840       attribute=(char *) SvPV(ST(i-1),na);
6841       switch (*attribute)
6842       {
6843         case 'C':
6844         case 'c':
6845         {
6846           if (LocaleCompare(attribute,"compose") == 0)
6847             {
6848               sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
6849                 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
6850               if (sp < 0)
6851                 {
6852                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
6853                     SvPV(ST(i),na));
6854                   break;
6855                 }
6856               compose=(CompositeOperator) sp;
6857               break;
6858             }
6859           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6860             attribute);
6861           break;
6862         }
6863         case 'M':
6864         case 'm':
6865         {
6866           if (LocaleCompare(attribute,"method") == 0)
6867             {
6868               option=ParseCommandOption(MagickLayerOptions,MagickFalse,
6869                 SvPV(ST(i),na));
6870               if (option < 0)
6871                 {
6872                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
6873                     SvPV(ST(i),na));
6874                   break;
6875                 }
6876               method=(LayerMethod) option;
6877               break;
6878             }
6879           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6880             attribute);
6881           break;
6882         }
6883         default:
6884         {
6885           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6886             attribute);
6887           break;
6888         }
6889       }
6890     }
6891     layers=(Image *) NULL;
6892     switch (method)
6893     {
6894       case CompareAnyLayer:
6895       case CompareClearLayer:
6896       case CompareOverlayLayer:
6897       default:
6898       {
6899         layers=CompareImagesLayers(image,method,exception);
6900         break;
6901       }
6902       case MergeLayer:
6903       case FlattenLayer:
6904       case MosaicLayer:
6905       {
6906         layers=MergeImageLayers(image,method,exception);
6907         break;
6908       }
6909       case DisposeLayer:
6910       {
6911         layers=DisposeImages(image,exception);
6912         break;
6913       }
6914       case OptimizeImageLayer:
6915       {
6916         layers=OptimizeImageLayers(image,exception);
6917         break;
6918       }
6919       case OptimizePlusLayer:
6920       {
6921         layers=OptimizePlusImageLayers(image,exception);
6922         break;
6923       }
6924       case OptimizeTransLayer:
6925       {
6926         OptimizeImageTransparency(image,exception);
6927         break;
6928       }
6929       case RemoveDupsLayer:
6930       {
6931         RemoveDuplicateLayers(&image,exception);
6932         break;
6933       }
6934       case RemoveZeroLayer:
6935       {
6936         RemoveZeroDelayLayers(&image,exception);
6937         break;
6938       }
6939       case OptimizeLayer:
6940       {
6941         QuantizeInfo
6942           *quantize_info;
6943
6944         /*
6945           General Purpose, GIF Animation Optimizer.
6946         */
6947         layers=CoalesceImages(image,exception);
6948         if (layers == (Image *) NULL)
6949           break;
6950         image=layers;
6951         layers=OptimizeImageLayers(image,exception);
6952         if (layers == (Image *) NULL)
6953           break;
6954         image=DestroyImageList(image);
6955         image=layers;
6956         layers=(Image *) NULL;
6957         OptimizeImageTransparency(image,exception);
6958         quantize_info=AcquireQuantizeInfo(info->image_info);
6959         (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
6960         quantize_info=DestroyQuantizeInfo(quantize_info);
6961         break;
6962       }
6963       case CompositeLayer:
6964       {
6965         Image
6966           *source;
6967
6968         RectangleInfo
6969           geometry;
6970
6971         /*
6972           Split image sequence at the first 'NULL:' image.
6973         */
6974         source=image;
6975         while (source != (Image *) NULL)
6976         {
6977           source=GetNextImageInList(source);
6978           if ((source != (Image *) NULL) &&
6979               (LocaleCompare(source->magick,"NULL") == 0))
6980             break;
6981         }
6982         if (source != (Image *) NULL)
6983           {
6984             if ((GetPreviousImageInList(source) == (Image *) NULL) ||
6985                 (GetNextImageInList(source) == (Image *) NULL))
6986               source=(Image *) NULL;
6987             else
6988               {
6989                 /*
6990                   Separate the two lists, junk the null: image.
6991                 */
6992                 source=SplitImageList(source->previous);
6993                 DeleteImageFromList(&source);
6994               }
6995           }
6996         if (source == (Image *) NULL)
6997           {
6998             (void) ThrowMagickException(exception,GetMagickModule(),
6999               OptionError,"MissingNullSeparator","layers Composite");
7000             break;
7001           }
7002         /*
7003           Adjust offset with gravity and virtual canvas.
7004         */
7005         SetGeometry(image,&geometry);
7006         (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7007         geometry.width=source->page.width != 0 ? source->page.width :
7008           source->columns;
7009         geometry.height=source->page.height != 0 ? source->page.height :
7010           source->rows;
7011         GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7012           image->columns,image->page.height != 0 ? image->page.height :
7013           image->rows,image->gravity,&geometry);
7014         CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7015         source=DestroyImageList(source);
7016         break;
7017       }
7018     }
7019     if (layers != (Image *) NULL)
7020       image=layers;
7021     if (image == (Image *) NULL)
7022       goto PerlException;
7023     for ( ; image; image=image->next)
7024     {
7025       AddImageToRegistry(sv,image);
7026       rv=newRV(sv);
7027       av_push(av,sv_bless(rv,hv));
7028       SvREFCNT_dec(sv);
7029     }
7030     exception=DestroyExceptionInfo(exception);
7031     ST(0)=av_reference;
7032     SvREFCNT_dec(perl_exception);
7033     XSRETURN(1);
7034
7035   PerlException:
7036     InheritPerlException(exception,perl_exception);
7037     exception=DestroyExceptionInfo(exception);
7038     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7039     SvPOK_on(perl_exception);
7040     ST(0)=sv_2mortal(perl_exception);
7041     XSRETURN(1);
7042   }
7043 \f
7044 #
7045 ###############################################################################
7046 #                                                                             #
7047 #                                                                             #
7048 #                                                                             #
7049 #   M a g i c k T o M i m e                                                   #
7050 #                                                                             #
7051 #                                                                             #
7052 #                                                                             #
7053 ###############################################################################
7054 #
7055 #
7056 SV *
7057 MagickToMime(ref,name)
7058   Image::Magick::Q16HDRI ref=NO_INIT
7059   char *name
7060   ALIAS:
7061     magicktomime = 1
7062   CODE:
7063   {
7064     char
7065       *mime;
7066
7067     PERL_UNUSED_VAR(ref);
7068     PERL_UNUSED_VAR(ix);
7069     mime=MagickToMime(name);
7070     RETVAL=newSVpv(mime,0);
7071     mime=(char *) RelinquishMagickMemory(mime);
7072   }
7073   OUTPUT:
7074     RETVAL
7075 \f
7076 #
7077 ###############################################################################
7078 #                                                                             #
7079 #                                                                             #
7080 #                                                                             #
7081 #   M o g r i f y                                                             #
7082 #                                                                             #
7083 #                                                                             #
7084 #                                                                             #
7085 ###############################################################################
7086 #
7087 #
7088 void
7089 Mogrify(ref,...)
7090   Image::Magick::Q16HDRI ref=NO_INIT
7091   ALIAS:
7092     Comment            =   1
7093     CommentImage       =   2
7094     Label              =   3
7095     LabelImage         =   4
7096     AddNoise           =   5
7097     AddNoiseImage      =   6
7098     Colorize           =   7
7099     ColorizeImage      =   8
7100     Border             =   9
7101     BorderImage        =  10
7102     Blur               =  11
7103     BlurImage          =  12
7104     Chop               =  13
7105     ChopImage          =  14
7106     Crop               =  15
7107     CropImage          =  16
7108     Despeckle          =  17
7109     DespeckleImage     =  18
7110     Edge               =  19
7111     EdgeImage          =  20
7112     Emboss             =  21
7113     EmbossImage        =  22
7114     Enhance            =  23
7115     EnhanceImage       =  24
7116     Flip               =  25
7117     FlipImage          =  26
7118     Flop               =  27
7119     FlopImage          =  28
7120     Frame              =  29
7121     FrameImage         =  30
7122     Implode            =  31
7123     ImplodeImage       =  32
7124     Magnify            =  33
7125     MagnifyImage       =  34
7126     MedianFilter       =  35
7127     MedianConvolveImage  =  36
7128     Minify             =  37
7129     MinifyImage        =  38
7130     OilPaint           =  39
7131     OilPaintImage      =  40
7132     ReduceNoise        =  41
7133     ReduceNoiseImage   =  42
7134     Roll               =  43
7135     RollImage          =  44
7136     Rotate             =  45
7137     RotateImage        =  46
7138     Sample             =  47
7139     SampleImage        =  48
7140     Scale              =  49
7141     ScaleImage         =  50
7142     Shade              =  51
7143     ShadeImage         =  52
7144     Sharpen            =  53
7145     SharpenImage       =  54
7146     Shear              =  55
7147     ShearImage         =  56
7148     Spread             =  57
7149     SpreadImage        =  58
7150     Swirl              =  59
7151     SwirlImage         =  60
7152     Resize             =  61
7153     ResizeImage        =  62
7154     Zoom               =  63
7155     ZoomImage          =  64
7156     Annotate           =  65
7157     AnnotateImage      =  66
7158     ColorFloodfill     =  67
7159     ColorFloodfillImage=  68
7160     Composite          =  69
7161     CompositeImage     =  70
7162     Contrast           =  71
7163     ContrastImage      =  72
7164     CycleColormap      =  73
7165     CycleColormapImage =  74
7166     Draw               =  75
7167     DrawImage          =  76
7168     Equalize           =  77
7169     EqualizeImage      =  78
7170     Gamma              =  79
7171     GammaImage         =  80
7172     Map                =  81
7173     MapImage           =  82
7174     MatteFloodfill     =  83
7175     MatteFloodfillImage=  84
7176     Modulate           =  85
7177     ModulateImage      =  86
7178     Negate             =  87
7179     NegateImage        =  88
7180     Normalize          =  89
7181     NormalizeImage     =  90
7182     NumberColors       =  91
7183     NumberColorsImage  =  92
7184     Opaque             =  93
7185     OpaqueImage        =  94
7186     Quantize           =  95
7187     QuantizeImage      =  96
7188     Raise              =  97
7189     RaiseImage         =  98
7190     Segment            =  99
7191     SegmentImage       = 100
7192     Signature          = 101
7193     SignatureImage     = 102
7194     Solarize           = 103
7195     SolarizeImage      = 104
7196     Sync               = 105
7197     SyncImage          = 106
7198     Texture            = 107
7199     TextureImage       = 108
7200     Evaluate           = 109
7201     EvaluateImage      = 110
7202     Transparent        = 111
7203     TransparentImage   = 112
7204     Threshold          = 113
7205     ThresholdImage     = 114
7206     Charcoal           = 115
7207     CharcoalImage      = 116
7208     Trim               = 117
7209     TrimImage          = 118
7210     Wave               = 119
7211     WaveImage          = 120
7212     Separate           = 121
7213     SeparateImage      = 122
7214     Stereo             = 125
7215     StereoImage        = 126
7216     Stegano            = 127
7217     SteganoImage       = 128
7218     Deconstruct        = 129
7219     DeconstructImage   = 130
7220     GaussianBlur       = 131
7221     GaussianBlurImage  = 132
7222     Convolve           = 133
7223     ConvolveImage      = 134
7224     Profile            = 135
7225     ProfileImage       = 136
7226     UnsharpMask        = 137
7227     UnsharpMaskImage   = 138
7228     MotionBlur         = 139
7229     MotionBlurImage    = 140
7230     OrderedDither      = 141
7231     OrderedDitherImage = 142
7232     Shave              = 143
7233     ShaveImage         = 144
7234     Level              = 145
7235     LevelImage         = 146
7236     Clip               = 147
7237     ClipImage          = 148
7238     AffineTransform    = 149
7239     AffineTransformImage = 150
7240     Difference         = 151
7241     DifferenceImage    = 152
7242     AdaptiveThreshold  = 153
7243     AdaptiveThresholdImage = 154
7244     Resample           = 155
7245     ResampleImage      = 156
7246     Describe           = 157
7247     DescribeImage      = 158
7248     BlackThreshold     = 159
7249     BlackThresholdImage= 160
7250     WhiteThreshold     = 161
7251     WhiteThresholdImage= 162
7252     RadialBlur         = 163
7253     RadialBlurImage    = 164
7254     Thumbnail          = 165
7255     ThumbnailImage     = 166
7256     Strip              = 167
7257     StripImage         = 168
7258     Tint               = 169
7259     TintImage          = 170
7260     Channel            = 171
7261     ChannelImage       = 172
7262     Splice             = 173
7263     SpliceImage        = 174
7264     Posterize          = 175
7265     PosterizeImage     = 176
7266     Shadow             = 177
7267     ShadowImage        = 178
7268     Identify           = 179
7269     IdentifyImage      = 180
7270     SepiaTone          = 181
7271     SepiaToneImage     = 182
7272     SigmoidalContrast  = 183
7273     SigmoidalContrastImage = 184
7274     Extent             = 185
7275     ExtentImage        = 186
7276     Vignette           = 187
7277     VignetteImage      = 188
7278     ContrastStretch    = 189
7279     ContrastStretchImage = 190
7280     Sans0              = 191
7281     Sans0Image         = 192
7282     Sans1              = 193
7283     Sans1Image         = 194
7284     AdaptiveSharpen    = 195
7285     AdaptiveSharpenImage = 196
7286     Transpose          = 197
7287     TransposeImage     = 198
7288     Transverse         = 199
7289     TransverseImage    = 200
7290     AutoOrient         = 201
7291     AutoOrientImage    = 202
7292     AdaptiveBlur       = 203
7293     AdaptiveBlurImage  = 204
7294     Sketch             = 205
7295     SketchImage        = 206
7296     UniqueColors       = 207
7297     UniqueColorsImage  = 208
7298     AdaptiveResize     = 209
7299     AdaptiveResizeImage= 210
7300     ClipMask           = 211
7301     ClipMaskImage      = 212
7302     LinearStretch      = 213
7303     LinearStretchImage = 214
7304     ColorMatrix        = 215
7305     ColorMatrixImage   = 216
7306     Mask               = 217
7307     MaskImage          = 218
7308     Polaroid           = 219
7309     PolaroidImage      = 220
7310     FloodfillPaint     = 221
7311     FloodfillPaintImage= 222
7312     Distort            = 223
7313     DistortImage       = 224
7314     Clut               = 225
7315     ClutImage          = 226
7316     LiquidRescale      = 227
7317     LiquidRescaleImage = 228
7318     Encipher           = 229
7319     EncipherImage      = 230
7320     Decipher           = 231
7321     DecipherImage      = 232
7322     Deskew             = 233
7323     DeskewImage        = 234
7324     Remap              = 235
7325     RemapImage         = 236
7326     SparseColor        = 237
7327     SparseColorImage   = 238
7328     Function           = 239
7329     FunctionImage      = 240
7330     SelectiveBlur      = 241
7331     SelectiveBlurImage = 242
7332     HaldClut           = 243
7333     HaldClutImage      = 244
7334     BlueShift          = 245
7335     BlueShiftImage     = 246
7336     ForwardFourierTransform  = 247
7337     ForwardFourierTransformImage = 248
7338     InverseFourierTransform = 249
7339     InverseFourierTransformImage = 250
7340     ColorDecisionList  = 251
7341     ColorDecisionListImage = 252
7342     AutoGamma          = 253
7343     AutoGammaImage     = 254
7344     AutoLevel          = 255
7345     AutoLevelImage     = 256
7346     LevelColors        = 257
7347     LevelImageColors   = 258
7348     Clamp              = 259
7349     ClampImage         = 260
7350     BrightnessContrast = 261
7351     BrightnessContrastImage = 262
7352     Morphology         = 263
7353     MorphologyImage    = 264
7354     Color              = 265
7355     ColorImage         = 266
7356     Mode               = 267
7357     ModeImage          = 268
7358     Statistic          = 269
7359     StatisticImage     = 270
7360     Perceptible        = 271
7361     PerceptibleImage   = 272
7362     Poly               = 273
7363     PolyImage          = 274
7364     MogrifyRegion      = 666
7365   PPCODE:
7366   {
7367     AffineMatrix
7368       affine,
7369       current;
7370
7371     char
7372       attribute_flag[MaxArguments],
7373       message[MaxTextExtent];
7374
7375     ChannelType
7376       channel,
7377       channel_mask;
7378
7379     CompositeOperator
7380       compose;
7381
7382     const char
7383       *attribute,
7384       *value;
7385
7386     double
7387       angle;
7388
7389     ExceptionInfo
7390       *exception;
7391
7392     GeometryInfo
7393       geometry_info;
7394
7395     Image
7396       *image,
7397       *next,
7398       *region_image;
7399
7400     MagickBooleanType
7401       status;
7402
7403     MagickStatusType
7404       flags;
7405
7406     PixelInfo
7407       fill_color;
7408
7409     RectangleInfo
7410       geometry,
7411       region_info;
7412
7413     register ssize_t
7414       i;
7415
7416     ssize_t
7417       base,
7418       j,
7419       number_images;
7420
7421     struct Methods
7422       *rp;
7423
7424     struct PackageInfo
7425       *info;
7426
7427     SV
7428       *perl_exception,
7429       **pv,
7430       *reference,
7431       **reference_vector;
7432
7433     struct ArgumentList
7434       argument_list[MaxArguments];
7435
7436     PERL_UNUSED_VAR(ref);
7437     PERL_UNUSED_VAR(ix);
7438     exception=AcquireExceptionInfo();
7439     perl_exception=newSVpv("",0);
7440     reference_vector=NULL;
7441     region_image=NULL;
7442     number_images=0;
7443     base=2;
7444     if (sv_isobject(ST(0)) == 0)
7445       {
7446         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7447           PackageName);
7448         goto PerlException;
7449       }
7450     reference=SvRV(ST(0));
7451     region_info.width=0;
7452     region_info.height=0;
7453     region_info.x=0;
7454     region_info.y=0;
7455     region_image=(Image *) NULL;
7456     image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7457     if (ix && (ix != 666))
7458       {
7459         /*
7460           Called as Method(...)
7461         */
7462         ix=(ix+1)/2;
7463         rp=(&Methods[ix-1]);
7464         attribute=rp->name;
7465       }
7466     else
7467       {
7468         /*
7469           Called as Mogrify("Method",...)
7470         */
7471         attribute=(char *) SvPV(ST(1),na);
7472         if (ix)
7473           {
7474             flags=ParseGravityGeometry(image,attribute,&region_info,exception);
7475             attribute=(char *) SvPV(ST(2),na);
7476             base++;
7477           }
7478         for (rp=Methods; ; rp++)
7479         {
7480           if (rp >= EndOf(Methods))
7481             {
7482               ThrowPerlException(exception,OptionError,
7483                 "UnrecognizedPerlMagickMethod",attribute);
7484               goto PerlException;
7485             }
7486           if (strEQcase(attribute,rp->name))
7487             break;
7488         }
7489         ix=rp-Methods+1;
7490         base++;
7491       }
7492     if (image == (Image *) NULL)
7493       {
7494         ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7495         goto PerlException;
7496       }
7497     Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7498     Zero(&attribute_flag,NumberOf(attribute_flag),char);
7499     for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7500     {
7501       Arguments
7502         *pp,
7503         *qq;
7504
7505       ssize_t
7506         ssize_test;
7507
7508       struct ArgumentList
7509         *al;
7510
7511       SV
7512         *sv;
7513
7514       sv=NULL;
7515       ssize_test=0;
7516       pp=(Arguments *) NULL;
7517       qq=rp->arguments;
7518       if (i == items)
7519         {
7520           pp=rp->arguments,
7521           sv=ST(i-1);
7522         }
7523       else
7524         for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7525         {
7526           if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7527             break;
7528           if (strEQcase(attribute,qq->method) > ssize_test)
7529             {
7530               pp=qq;
7531               ssize_test=strEQcase(attribute,qq->method);
7532             }
7533         }
7534       if (pp == (Arguments *) NULL)
7535         {
7536           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7537             attribute);
7538           goto continue_outer_loop;
7539         }
7540       al=(&argument_list[pp-rp->arguments]);
7541       switch (pp->type)
7542       {
7543         case ArrayReference:
7544         {
7545           if (SvTYPE(sv) != SVt_RV)
7546             {
7547               (void) FormatLocaleString(message,MaxTextExtent,
7548                 "invalid %.60s value",pp->method);
7549               ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7550               goto continue_outer_loop;
7551             }
7552           al->array_reference=SvRV(sv);
7553           break;
7554         }
7555         case RealReference:
7556         {
7557           al->real_reference=SvNV(sv);
7558           break;
7559         }
7560         case FileReference:
7561         {
7562           al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7563           break;
7564         }
7565         case ImageReference:
7566         {
7567           if (!sv_isobject(sv) ||
7568               !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7569                 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7570             {
7571               ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7572                 PackageName);
7573               goto PerlException;
7574             }
7575           break;
7576         }
7577         case IntegerReference:
7578         {
7579           al->integer_reference=SvIV(sv);
7580           break;
7581         }
7582         case StringReference:
7583         {
7584           al->string_reference=(char *) SvPV(sv,al->length);
7585           if (sv_isobject(sv))
7586             al->image_reference=SetupList(aTHX_ SvRV(sv),
7587               (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7588           break;
7589         }
7590         default:
7591         {
7592           /*
7593             Is a string; look up name.
7594           */
7595           if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7596             {
7597               al->string_reference=(char *) SvPV(sv,al->length);
7598               al->integer_reference=(-1);
7599               break;
7600             }
7601           al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7602             MagickFalse,SvPV(sv,na));
7603           if (pp->type == MagickChannelOptions)
7604             al->integer_reference=ParseChannelOption(SvPV(sv,na));
7605           if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7606             {
7607               (void) FormatLocaleString(message,MaxTextExtent,
7608                 "invalid %.60s value",pp->method);
7609               ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7610               goto continue_outer_loop;
7611             }
7612           break;
7613         }
7614       }
7615       attribute_flag[pp-rp->arguments]++;
7616       continue_outer_loop: ;
7617     }
7618     (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7619     pv=reference_vector;
7620     SetGeometryInfo(&geometry_info);
7621     channel=DefaultChannels;
7622     for (next=image; next; next=next->next)
7623     {
7624       image=next;
7625       SetGeometry(image,&geometry);
7626       if ((region_info.width*region_info.height) != 0)
7627         {
7628           region_image=image;
7629           image=CropImage(image,&region_info,exception);
7630         }
7631       switch (ix)
7632       {
7633         default:
7634         {
7635           (void) FormatLocaleString(message,MaxTextExtent,"%.20g",(double) ix);
7636           ThrowPerlException(exception,OptionError,
7637             "UnrecognizedPerlMagickMethod",message);
7638           goto PerlException;
7639         }
7640         case 1:  /* Comment */
7641         {
7642           if (attribute_flag[0] == 0)
7643             argument_list[0].string_reference=(char *) NULL;
7644           (void) SetImageProperty(image,"comment",InterpretImageProperties(
7645             info ? info->image_info : (ImageInfo *) NULL,image,
7646             argument_list[0].string_reference,exception),exception);
7647           break;
7648         }
7649         case 2:  /* Label */
7650         {
7651           if (attribute_flag[0] == 0)
7652             argument_list[0].string_reference=(char *) NULL;
7653           (void) SetImageProperty(image,"label",InterpretImageProperties(
7654             info ? info->image_info : (ImageInfo *) NULL,image,
7655             argument_list[0].string_reference,exception),exception);
7656           break;
7657         }
7658         case 3:  /* AddNoise */
7659         {
7660           double
7661             attenuate;
7662
7663           if (attribute_flag[0] == 0)
7664             argument_list[0].integer_reference=UniformNoise;
7665           attenuate=1.0;
7666           if (attribute_flag[1] != 0)
7667             attenuate=argument_list[1].real_reference;
7668           if (attribute_flag[2] != 0)
7669             channel=(ChannelType) argument_list[2].integer_reference;
7670           channel_mask=SetImageChannelMask(image,channel);
7671           image=AddNoiseImage(image,(NoiseType)
7672             argument_list[0].integer_reference,attenuate,exception);
7673           if (image != (Image *) NULL)
7674             (void) SetImageChannelMask(image,channel_mask);
7675           break;
7676         }
7677         case 4:  /* Colorize */
7678         {
7679           PixelInfo
7680             target;
7681
7682           (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7683             0,0,&target,exception);
7684           if (attribute_flag[0] != 0)
7685             (void) QueryColorCompliance(argument_list[0].string_reference,
7686               AllCompliance,&target,exception);
7687           if (attribute_flag[1] == 0)
7688             argument_list[1].string_reference="100%";
7689           image=ColorizeImage(image,argument_list[1].string_reference,&target,
7690             exception);
7691           break;
7692         }
7693         case 5:  /* Border */
7694         {
7695           CompositeOperator
7696             compose;
7697
7698           geometry.width=0;
7699           geometry.height=0;
7700           if (attribute_flag[0] != 0)
7701             flags=ParsePageGeometry(image,argument_list[0].string_reference,
7702               &geometry,exception);
7703           if (attribute_flag[1] != 0)
7704             geometry.width=argument_list[1].integer_reference;
7705           if (attribute_flag[2] != 0)
7706             geometry.height=argument_list[2].integer_reference;
7707           if (attribute_flag[3] != 0)
7708             QueryColorCompliance(argument_list[3].string_reference,
7709               AllCompliance,&image->border_color,exception);
7710           if (attribute_flag[4] != 0)
7711             QueryColorCompliance(argument_list[4].string_reference,
7712               AllCompliance,&image->border_color,exception);
7713           if (attribute_flag[5] != 0)
7714             QueryColorCompliance(argument_list[5].string_reference,
7715               AllCompliance,&image->border_color,exception);
7716           compose=image->compose;
7717           if (attribute_flag[6] != 0)
7718             compose=(CompositeOperator) argument_list[6].integer_reference;
7719           image=BorderImage(image,&geometry,compose,exception);
7720           break;
7721         }
7722         case 6:  /* Blur */
7723         {
7724           if (attribute_flag[0] != 0)
7725             {
7726               flags=ParseGeometry(argument_list[0].string_reference,
7727                 &geometry_info);
7728               if ((flags & SigmaValue) == 0)
7729                 geometry_info.sigma=1.0;
7730             }
7731           if (attribute_flag[1] != 0)
7732             geometry_info.rho=argument_list[1].real_reference;
7733           if (attribute_flag[2] != 0)
7734             geometry_info.sigma=argument_list[2].real_reference;
7735           if (attribute_flag[3] != 0)
7736             channel=(ChannelType) argument_list[3].integer_reference;
7737           channel_mask=SetImageChannelMask(image,channel);
7738           image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
7739             exception);
7740           if (image != (Image *) NULL)
7741             (void) SetImageChannelMask(image,channel_mask);
7742           break;
7743         }
7744         case 7:  /* Chop */
7745         {
7746           if (attribute_flag[0] != 0)
7747             flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7748               &geometry,exception);
7749           if (attribute_flag[1] != 0)
7750             geometry.width=argument_list[1].integer_reference;
7751           if (attribute_flag[2] != 0)
7752             geometry.height=argument_list[2].integer_reference;
7753           if (attribute_flag[3] != 0)
7754             geometry.x=argument_list[3].integer_reference;
7755           if (attribute_flag[4] != 0)
7756             geometry.y=argument_list[4].integer_reference;
7757           image=ChopImage(image,&geometry,exception);
7758           break;
7759         }
7760         case 8:  /* Crop */
7761         {
7762           if (attribute_flag[6] != 0)
7763             image->gravity=(GravityType) argument_list[6].integer_reference;
7764           if (attribute_flag[0] != 0)
7765             flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7766               &geometry,exception);
7767           if (attribute_flag[1] != 0)
7768             geometry.width=argument_list[1].integer_reference;
7769           if (attribute_flag[2] != 0)
7770             geometry.height=argument_list[2].integer_reference;
7771           if (attribute_flag[3] != 0)
7772             geometry.x=argument_list[3].integer_reference;
7773           if (attribute_flag[4] != 0)
7774             geometry.y=argument_list[4].integer_reference;
7775           if (attribute_flag[5] != 0)
7776             image->fuzz=StringToDoubleInterval(
7777               argument_list[5].string_reference,(double) QuantumRange+1.0);
7778           image=CropImage(image,&geometry,exception);
7779           break;
7780         }
7781         case 9:  /* Despeckle */
7782         {
7783           image=DespeckleImage(image,exception);
7784           break;
7785         }
7786         case 10:  /* Edge */
7787         {
7788           if (attribute_flag[0] != 0)
7789             geometry_info.rho=argument_list[0].real_reference;
7790           image=EdgeImage(image,geometry_info.rho,exception);
7791           break;
7792         }
7793         case 11:  /* Emboss */
7794         {
7795           if (attribute_flag[0] != 0)
7796             {
7797               flags=ParseGeometry(argument_list[0].string_reference,
7798                 &geometry_info);
7799               if ((flags & SigmaValue) == 0)
7800                 geometry_info.sigma=1.0;
7801             }
7802           if (attribute_flag[1] != 0)
7803             geometry_info.rho=argument_list[1].real_reference;
7804           if (attribute_flag[2] != 0)
7805             geometry_info.sigma=argument_list[2].real_reference;
7806           image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
7807             exception);
7808           break;
7809         }
7810         case 12:  /* Enhance */
7811         {
7812           image=EnhanceImage(image,exception);
7813           break;
7814         }
7815         case 13:  /* Flip */
7816         {
7817           image=FlipImage(image,exception);
7818           break;
7819         }
7820         case 14:  /* Flop */
7821         {
7822           image=FlopImage(image,exception);
7823           break;
7824         }
7825         case 15:  /* Frame */
7826         {
7827           CompositeOperator
7828             compose;
7829
7830           FrameInfo
7831             frame_info;
7832
7833           if (attribute_flag[0] != 0)
7834             {
7835               flags=ParsePageGeometry(image,argument_list[0].string_reference,
7836                 &geometry,exception);
7837               frame_info.width=geometry.width;
7838               frame_info.height=geometry.height;
7839               frame_info.outer_bevel=geometry.x;
7840               frame_info.inner_bevel=geometry.y;
7841             }
7842           if (attribute_flag[1] != 0)
7843             frame_info.width=argument_list[1].integer_reference;
7844           if (attribute_flag[2] != 0)
7845             frame_info.height=argument_list[2].integer_reference;
7846           if (attribute_flag[3] != 0)
7847             frame_info.inner_bevel=argument_list[3].integer_reference;
7848           if (attribute_flag[4] != 0)
7849             frame_info.outer_bevel=argument_list[4].integer_reference;
7850           if (attribute_flag[5] != 0)
7851             QueryColorCompliance(argument_list[5].string_reference,
7852               AllCompliance,&fill_color,exception);
7853           if (attribute_flag[6] != 0)
7854             QueryColorCompliance(argument_list[6].string_reference,
7855               AllCompliance,&fill_color,exception);
7856           frame_info.x=(ssize_t) frame_info.width;
7857           frame_info.y=(ssize_t) frame_info.height;
7858           frame_info.width=image->columns+2*frame_info.x;
7859           frame_info.height=image->rows+2*frame_info.y;
7860           if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
7861             image->matte_color=fill_color;
7862           compose=image->compose;
7863           if (attribute_flag[7] != 0)
7864             compose=(CompositeOperator) argument_list[7].integer_reference;
7865           image=FrameImage(image,&frame_info,compose,exception);
7866           break;
7867         }
7868         case 16:  /* Implode */
7869         {
7870           PixelInterpolateMethod
7871             method;
7872
7873           if (attribute_flag[0] == 0)
7874             argument_list[0].real_reference=0.5;
7875           method=UndefinedInterpolatePixel;
7876           if (attribute_flag[1] != 0)
7877             method=(PixelInterpolateMethod) argument_list[1].integer_reference;
7878           image=ImplodeImage(image,argument_list[0].real_reference,
7879             method,exception);
7880           break;
7881         }
7882         case 17:  /* Magnify */
7883         {
7884           image=MagnifyImage(image,exception);
7885           break;
7886         }
7887         case 18:  /* MedianFilter */
7888         {
7889           if (attribute_flag[0] != 0)
7890             {
7891               flags=ParseGeometry(argument_list[0].string_reference,
7892                 &geometry_info);
7893               if ((flags & SigmaValue) == 0)
7894                 geometry_info.sigma=geometry_info.rho;
7895             }
7896           if (attribute_flag[1] != 0)
7897             geometry_info.rho=argument_list[1].real_reference;
7898           if (attribute_flag[2] != 0)
7899             geometry_info.sigma=argument_list[2].real_reference;
7900           if (attribute_flag[3] != 0)
7901             channel=(ChannelType) argument_list[3].integer_reference;
7902           channel_mask=SetImageChannelMask(image,channel);
7903           image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
7904             (size_t) geometry_info.sigma,exception);
7905           if (image != (Image *) NULL)
7906             (void) SetImageChannelMask(image,channel_mask);
7907           break;
7908         }
7909         case 19:  /* Minify */
7910         {
7911           image=MinifyImage(image,exception);
7912           break;
7913         }
7914         case 20:  /* OilPaint */
7915         {
7916           if (attribute_flag[0] == 0)
7917             argument_list[0].real_reference=0.0;
7918           if (attribute_flag[1] == 0)
7919             argument_list[1].real_reference=1.0;
7920           image=OilPaintImage(image,argument_list[0].real_reference,
7921             argument_list[1].real_reference,exception);
7922           break;
7923         }
7924         case 21:  /* ReduceNoise */
7925         {
7926           if (attribute_flag[0] != 0)
7927             {
7928               flags=ParseGeometry(argument_list[0].string_reference,
7929                 &geometry_info);
7930               if ((flags & SigmaValue) == 0)
7931                 geometry_info.sigma=1.0;
7932             }
7933           if (attribute_flag[1] != 0)
7934             geometry_info.rho=argument_list[1].real_reference;
7935           if (attribute_flag[2] != 0)
7936             geometry_info.sigma=argument_list[2].real_reference;
7937           if (attribute_flag[3] != 0)
7938             channel=(ChannelType) argument_list[3].integer_reference;
7939           channel_mask=SetImageChannelMask(image,channel);
7940           image=StatisticImage(image,NonpeakStatistic,(size_t)
7941             geometry_info.rho,(size_t) geometry_info.sigma,exception);
7942           if (image != (Image *) NULL)
7943             (void) SetImageChannelMask(image,channel_mask);
7944           break;
7945         }
7946         case 22:  /* Roll */
7947         {
7948           if (attribute_flag[0] != 0)
7949             flags=ParsePageGeometry(image,argument_list[0].string_reference,
7950               &geometry,exception);
7951           if (attribute_flag[1] != 0)
7952             geometry.x=argument_list[1].integer_reference;
7953           if (attribute_flag[2] != 0)
7954             geometry.y=argument_list[2].integer_reference;
7955           image=RollImage(image,geometry.x,geometry.y,exception);
7956           break;
7957         }
7958         case 23:  /* Rotate */
7959         {
7960           if (attribute_flag[0] == 0)
7961             argument_list[0].real_reference=90.0;
7962           if (attribute_flag[1] != 0)
7963             {
7964               QueryColorCompliance(argument_list[1].string_reference,
7965                 AllCompliance,&image->background_color,exception);
7966               if ((image->background_color.alpha_trait == BlendPixelTrait) &&
7967                   (image->alpha_trait != BlendPixelTrait))
7968                 (void) SetImageAlpha(image,OpaqueAlpha,exception);
7969             }
7970           image=RotateImage(image,argument_list[0].real_reference,exception);
7971           break;
7972         }
7973         case 24:  /* Sample */
7974         {
7975           if (attribute_flag[0] != 0)
7976             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
7977               &geometry,exception);
7978           if (attribute_flag[1] != 0)
7979             geometry.width=argument_list[1].integer_reference;
7980           if (attribute_flag[2] != 0)
7981             geometry.height=argument_list[2].integer_reference;
7982           image=SampleImage(image,geometry.width,geometry.height,exception);
7983           break;
7984         }
7985         case 25:  /* Scale */
7986         {
7987           if (attribute_flag[0] != 0)
7988             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
7989               &geometry,exception);
7990           if (attribute_flag[1] != 0)
7991             geometry.width=argument_list[1].integer_reference;
7992           if (attribute_flag[2] != 0)
7993             geometry.height=argument_list[2].integer_reference;
7994           image=ScaleImage(image,geometry.width,geometry.height,exception);
7995           break;
7996         }
7997         case 26:  /* Shade */
7998         {
7999           if (attribute_flag[0] != 0)
8000             {
8001               flags=ParseGeometry(argument_list[0].string_reference,
8002                 &geometry_info);
8003               if ((flags & SigmaValue) == 0)
8004                 geometry_info.sigma=0.0;
8005             }
8006           if (attribute_flag[1] != 0)
8007             geometry_info.rho=argument_list[1].real_reference;
8008           if (attribute_flag[2] != 0)
8009             geometry_info.sigma=argument_list[2].real_reference;
8010           image=ShadeImage(image,
8011             argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8012             geometry_info.rho,geometry_info.sigma,exception);
8013           break;
8014         }
8015         case 27:  /* Sharpen */
8016         {
8017           if (attribute_flag[0] != 0)
8018             {
8019               flags=ParseGeometry(argument_list[0].string_reference,
8020                 &geometry_info);
8021               if ((flags & SigmaValue) == 0)
8022                 geometry_info.sigma=1.0;
8023             }
8024           if (attribute_flag[1] != 0)
8025             geometry_info.rho=argument_list[1].real_reference;
8026           if (attribute_flag[2] != 0)
8027             geometry_info.sigma=argument_list[2].real_reference;
8028           if (attribute_flag[3] != 0)
8029             channel=(ChannelType) argument_list[3].integer_reference;
8030           channel_mask=SetImageChannelMask(image,channel);
8031           image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8032             exception);
8033           if (image != (Image *) NULL)
8034             (void) SetImageChannelMask(image,channel_mask);
8035           break;
8036         }
8037         case 28:  /* Shear */
8038         {
8039           if (attribute_flag[0] != 0)
8040             {
8041               flags=ParseGeometry(argument_list[0].string_reference,
8042                 &geometry_info);
8043               if ((flags & SigmaValue) == 0)
8044                 geometry_info.sigma=geometry_info.rho;
8045             }
8046           if (attribute_flag[1] != 0)
8047             geometry_info.rho=argument_list[1].real_reference;
8048           if (attribute_flag[2] != 0)
8049             geometry_info.sigma=argument_list[2].real_reference;
8050           if (attribute_flag[3] != 0)
8051             QueryColorCompliance(argument_list[3].string_reference,
8052               AllCompliance,&image->background_color,exception);
8053           if (attribute_flag[4] != 0)
8054             QueryColorCompliance(argument_list[4].string_reference,
8055               AllCompliance,&image->background_color,exception);
8056           image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8057             exception);
8058           break;
8059         }
8060         case 29:  /* Spread */
8061         {
8062           PixelInterpolateMethod
8063             method;
8064
8065           if (attribute_flag[0] == 0)
8066             argument_list[0].real_reference=1.0;
8067           method=UndefinedInterpolatePixel;
8068           if (attribute_flag[1] != 0)
8069             method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8070           image=SpreadImage(image,argument_list[0].real_reference,method,
8071             exception);
8072           break;
8073         }
8074         case 30:  /* Swirl */
8075         {
8076           PixelInterpolateMethod
8077             method;
8078
8079           if (attribute_flag[0] == 0)
8080             argument_list[0].real_reference=50.0;
8081           method=UndefinedInterpolatePixel;
8082           if (attribute_flag[1] != 0)
8083             method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8084           image=SwirlImage(image,argument_list[0].real_reference,
8085             method,exception);
8086           break;
8087         }
8088         case 31:  /* Resize */
8089         case 32:  /* Zoom */
8090         {
8091           if (attribute_flag[0] != 0)
8092             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8093               &geometry,exception);
8094           if (attribute_flag[1] != 0)
8095             geometry.width=argument_list[1].integer_reference;
8096           if (attribute_flag[2] != 0)
8097             geometry.height=argument_list[2].integer_reference;
8098           if (attribute_flag[3] == 0)
8099             argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8100           if (attribute_flag[4] != 0)
8101             SetImageArtifact(image,"filter:support",
8102               argument_list[4].string_reference);
8103           image=ResizeImage(image,geometry.width,geometry.height,
8104             (FilterTypes) argument_list[3].integer_reference,
8105             exception);
8106           break;
8107         }
8108         case 33:  /* Annotate */
8109         {
8110           DrawInfo
8111             *draw_info;
8112
8113           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8114             (DrawInfo *) NULL);
8115           if (attribute_flag[0] != 0)
8116             {
8117               char
8118                 *text;
8119
8120               text=InterpretImageProperties(info ? info->image_info :
8121                 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8122                 exception);
8123               (void) CloneString(&draw_info->text,text);
8124               text=DestroyString(text);
8125             }
8126           if (attribute_flag[1] != 0)
8127             (void) CloneString(&draw_info->font,
8128               argument_list[1].string_reference);
8129           if (attribute_flag[2] != 0)
8130             draw_info->pointsize=argument_list[2].real_reference;
8131           if (attribute_flag[3] != 0)
8132             (void) CloneString(&draw_info->density,
8133               argument_list[3].string_reference);
8134           if (attribute_flag[4] != 0)
8135             (void) QueryColorCompliance(argument_list[4].string_reference,
8136               AllCompliance,&draw_info->undercolor,exception);
8137           if (attribute_flag[5] != 0)
8138             {
8139               (void) QueryColorCompliance(argument_list[5].string_reference,
8140                 AllCompliance,&draw_info->stroke,exception);
8141               if (argument_list[5].image_reference != (Image *) NULL)
8142                 draw_info->stroke_pattern=CloneImage(
8143                   argument_list[5].image_reference,0,0,MagickTrue,exception);
8144             }
8145           if (attribute_flag[6] != 0)
8146             {
8147               (void) QueryColorCompliance(argument_list[6].string_reference,
8148                 AllCompliance,&draw_info->fill,exception);
8149               if (argument_list[6].image_reference != (Image *) NULL)
8150                 draw_info->fill_pattern=CloneImage(
8151                   argument_list[6].image_reference,0,0,MagickTrue,exception);
8152             }
8153           if (attribute_flag[7] != 0)
8154             {
8155               (void) CloneString(&draw_info->geometry,
8156                 argument_list[7].string_reference);
8157               flags=ParsePageGeometry(image,argument_list[7].string_reference,
8158                 &geometry,exception);
8159               if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8160                 geometry_info.sigma=geometry_info.xi;
8161             }
8162           if (attribute_flag[8] != 0)
8163             (void) QueryColorCompliance(argument_list[8].string_reference,
8164               AllCompliance,&draw_info->fill,exception);
8165           if (attribute_flag[11] != 0)
8166             draw_info->gravity=(GravityType)
8167               argument_list[11].integer_reference;
8168           if (attribute_flag[25] != 0)
8169             {
8170               AV
8171                 *av;
8172
8173               av=(AV *) argument_list[25].array_reference;
8174               if ((av_len(av) != 3) && (av_len(av) != 5))
8175                 {
8176                   ThrowPerlException(exception,OptionError,
8177                     "affine matrix must have 4 or 6 elements",PackageName);
8178                   goto PerlException;
8179                 }
8180               draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8181               draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8182               draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8183               draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8184               if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8185                   draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8186                 {
8187                   ThrowPerlException(exception,OptionError,
8188                     "affine matrix is singular",PackageName);
8189                    goto PerlException;
8190                 }
8191               if (av_len(av) == 5)
8192                 {
8193                   draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8194                   draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8195                 }
8196             }
8197           for (j=12; j < 17; j++)
8198           {
8199             if (attribute_flag[j] == 0)
8200               continue;
8201             value=argument_list[j].string_reference;
8202             angle=argument_list[j].real_reference;
8203             current=draw_info->affine;
8204             GetAffineMatrix(&affine);
8205             switch (j)
8206             {
8207               case 12:
8208               {
8209                 /*
8210                   Translate.
8211                 */
8212                 flags=ParseGeometry(value,&geometry_info);
8213                 affine.tx=geometry_info.xi;
8214                 affine.ty=geometry_info.psi;
8215                 if ((flags & PsiValue) == 0)
8216                   affine.ty=affine.tx;
8217                 break;
8218               }
8219               case 13:
8220               {
8221                 /*
8222                   Scale.
8223                 */
8224                 flags=ParseGeometry(value,&geometry_info);
8225                 affine.sx=geometry_info.rho;
8226                 affine.sy=geometry_info.sigma;
8227                 if ((flags & SigmaValue) == 0)
8228                   affine.sy=affine.sx;
8229                 break;
8230               }
8231               case 14:
8232               {
8233                 /*
8234                   Rotate.
8235                 */
8236                 if (angle == 0.0)
8237                   break;
8238                 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8239                 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8240                 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8241                 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8242                 break;
8243               }
8244               case 15:
8245               {
8246                 /*
8247                   SkewX.
8248                 */
8249                 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8250                 break;
8251               }
8252               case 16:
8253               {
8254                 /*
8255                   SkewY.
8256                 */
8257                 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8258                 break;
8259               }
8260             }
8261             draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8262             draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8263             draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8264             draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8265             draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8266               current.tx;
8267             draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8268               current.ty;
8269           }
8270           if (attribute_flag[9] == 0)
8271             argument_list[9].real_reference=0.0;
8272           if (attribute_flag[10] == 0)
8273             argument_list[10].real_reference=0.0;
8274           if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8275             {
8276               char
8277                 geometry[MaxTextExtent];
8278
8279               (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
8280                 (double) argument_list[9].real_reference+draw_info->affine.tx,
8281                 (double) argument_list[10].real_reference+draw_info->affine.ty);
8282               (void) CloneString(&draw_info->geometry,geometry);
8283             }
8284           if (attribute_flag[17] != 0)
8285             draw_info->stroke_width=argument_list[17].real_reference;
8286           if (attribute_flag[18] != 0)
8287             {
8288               draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8289                 MagickTrue : MagickFalse;
8290               draw_info->stroke_antialias=draw_info->text_antialias;
8291             }
8292           if (attribute_flag[19] != 0)
8293             (void) CloneString(&draw_info->family,
8294               argument_list[19].string_reference);
8295           if (attribute_flag[20] != 0)
8296             draw_info->style=(StyleType) argument_list[20].integer_reference;
8297           if (attribute_flag[21] != 0)
8298             draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8299           if (attribute_flag[22] != 0)
8300             draw_info->weight=argument_list[22].integer_reference;
8301           if (attribute_flag[23] != 0)
8302             draw_info->align=(AlignType) argument_list[23].integer_reference;
8303           if (attribute_flag[24] != 0)
8304             (void) CloneString(&draw_info->encoding,
8305               argument_list[24].string_reference);
8306           if (attribute_flag[25] != 0)
8307             draw_info->fill_pattern=CloneImage(
8308               argument_list[25].image_reference,0,0,MagickTrue,exception);
8309           if (attribute_flag[26] != 0)
8310             draw_info->fill_pattern=CloneImage(
8311               argument_list[26].image_reference,0,0,MagickTrue,exception);
8312           if (attribute_flag[27] != 0)
8313             draw_info->stroke_pattern=CloneImage(
8314               argument_list[27].image_reference,0,0,MagickTrue,exception);
8315           if (attribute_flag[29] != 0)
8316             draw_info->kerning=argument_list[29].real_reference;
8317           if (attribute_flag[30] != 0)
8318             draw_info->interline_spacing=argument_list[30].real_reference;
8319           if (attribute_flag[31] != 0)
8320             draw_info->interword_spacing=argument_list[31].real_reference;
8321           if (attribute_flag[32] != 0)
8322             draw_info->direction=(DirectionType)
8323               argument_list[32].integer_reference;
8324           (void) AnnotateImage(image,draw_info,exception);
8325           draw_info=DestroyDrawInfo(draw_info);
8326           break;
8327         }
8328         case 34:  /* ColorFloodfill */
8329         {
8330           DrawInfo
8331             *draw_info;
8332
8333           MagickBooleanType
8334             invert;
8335
8336           PixelInfo
8337             target;
8338
8339           draw_info=CloneDrawInfo(info ? info->image_info :
8340             (ImageInfo *) NULL,(DrawInfo *) NULL);
8341           if (attribute_flag[0] != 0)
8342             flags=ParsePageGeometry(image,argument_list[0].string_reference,
8343               &geometry,exception);
8344           if (attribute_flag[1] != 0)
8345             geometry.x=argument_list[1].integer_reference;
8346           if (attribute_flag[2] != 0)
8347             geometry.y=argument_list[2].integer_reference;
8348           if (attribute_flag[3] != 0)
8349             (void) QueryColorCompliance(argument_list[3].string_reference,
8350               AllCompliance,&draw_info->fill,exception);
8351           (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8352             geometry.x,geometry.y,&target,exception);
8353           invert=MagickFalse;
8354           if (attribute_flag[4] != 0)
8355             {
8356               QueryColorCompliance(argument_list[4].string_reference,
8357                 AllCompliance,&target,exception);
8358               invert=MagickTrue;
8359             }
8360           if (attribute_flag[5] != 0)
8361             image->fuzz=StringToDoubleInterval(
8362               argument_list[5].string_reference,(double) QuantumRange+1.0);
8363           if (attribute_flag[6] != 0)
8364             invert=(MagickBooleanType) argument_list[6].integer_reference;
8365           (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8366             geometry.y,invert,exception);
8367           draw_info=DestroyDrawInfo(draw_info);
8368           break;
8369         }
8370         case 35:  /* Composite */
8371         {
8372           char
8373             composite_geometry[MaxTextExtent];
8374
8375           Image
8376             *composite_image,
8377             *rotate_image;
8378
8379           MagickBooleanType
8380             clip_to_self;
8381
8382           compose=OverCompositeOp;
8383           if (attribute_flag[0] != 0)
8384             composite_image=argument_list[0].image_reference;
8385           else
8386             {
8387               ThrowPerlException(exception,OptionError,
8388                 "CompositeImageRequired",PackageName);
8389               goto PerlException;
8390             }
8391           /*
8392             Parameter Handling used for BOTH normal and tiled composition.
8393           */
8394           if (attribute_flag[1] != 0) /* compose */
8395             compose=(CompositeOperator) argument_list[1].integer_reference;
8396           if (attribute_flag[6] != 0) /* opacity  */
8397             {
8398               if (compose != DissolveCompositeOp)
8399                 (void) SetImageAlpha(composite_image,(Quantum)
8400                   StringToDoubleInterval(argument_list[6].string_reference,
8401                   (double) QuantumRange+1.0),exception);
8402               else
8403                 {
8404                   CacheView
8405                     *composite_view;
8406
8407                   double
8408                     opacity;
8409
8410                   MagickBooleanType
8411                     sync;
8412
8413                   register ssize_t
8414                     x;
8415
8416                   register Quantum
8417                     *q;
8418
8419                   ssize_t
8420                     y;
8421
8422                   /*
8423                     Handle dissolve composite operator (patch by
8424                     Kevin A. McGrail).
8425                   */
8426                   (void) CloneString(&image->geometry,
8427                     argument_list[6].string_reference);
8428                   opacity=(Quantum) StringToDoubleInterval(
8429                     argument_list[6].string_reference,(double) QuantumRange+
8430                     1.0);
8431                   if (composite_image->alpha_trait == BlendPixelTrait)
8432                     (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8433                   composite_view=AcquireAuthenticCacheView(composite_image,exception);
8434                   for (y=0; y < (ssize_t) composite_image->rows ; y++)
8435                   {
8436                     q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8437                       composite_image->columns,1,exception);
8438                     for (x=0; x < (ssize_t) composite_image->columns; x++)
8439                     {
8440                       if (GetPixelAlpha(image,q) == OpaqueAlpha)
8441                         SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8442                           q);
8443                       q+=GetPixelChannels(composite_image);
8444                     }
8445                     sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8446                     if (sync == MagickFalse)
8447                       break;
8448                   }
8449                   composite_view=DestroyCacheView(composite_view);
8450                 }
8451             }
8452           if (attribute_flag[9] != 0)    /* "color=>" */
8453             QueryColorCompliance(argument_list[9].string_reference,
8454               AllCompliance,&composite_image->background_color,exception);
8455           if (attribute_flag[12] != 0) /* "interpolate=>" */
8456             image->interpolate=(PixelInterpolateMethod)
8457               argument_list[12].integer_reference;
8458           if (attribute_flag[13] != 0)   /* "args=>" */
8459             (void) SetImageArtifact(composite_image,"compose:args",
8460               argument_list[13].string_reference);
8461           if (attribute_flag[14] != 0)   /* "blend=>"  depreciated */
8462             (void) SetImageArtifact(composite_image,"compose:args",
8463               argument_list[14].string_reference);
8464           clip_to_self=MagickTrue;
8465           if (attribute_flag[15] != 0)
8466             clip_to_self=(MagickBooleanType)
8467               argument_list[15].integer_reference;
8468           /*
8469             Tiling Composition (with orthogonal rotate).
8470           */
8471           rotate_image=(Image *) NULL;
8472           if (attribute_flag[8] != 0)   /* "rotate=>" */
8473             {
8474                /*
8475                  Rotate image.
8476                */
8477                rotate_image=RotateImage(composite_image,
8478                  argument_list[8].real_reference,exception);
8479                if (rotate_image == (Image *) NULL)
8480                  break;
8481             }
8482           if ((attribute_flag[7] != 0) &&
8483               (argument_list[7].integer_reference != 0)) /* tile */
8484             {
8485               ssize_t
8486                 x,
8487                 y;
8488
8489               /*
8490                 Tile the composite image.
8491               */
8492              if (attribute_flag[8] != 0)   /* "tile=>" */
8493                (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
8494                  "false");
8495              else
8496                (void) SetImageArtifact(composite_image,
8497                  "compose:outside-overlay","false");
8498              for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8499                 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8500                 {
8501                   if (attribute_flag[8] != 0) /* rotate */
8502                     (void) CompositeImage(image,rotate_image,compose,
8503                       MagickTrue,x,y,exception);
8504                   else
8505                     (void) CompositeImage(image,composite_image,compose,
8506                       MagickTrue,x,y,exception);
8507                 }
8508               if (attribute_flag[8] != 0) /* rotate */
8509                 rotate_image=DestroyImage(rotate_image);
8510               break;
8511             }
8512           /*
8513             Parameter Handling used used ONLY for normal composition.
8514           */
8515           if (attribute_flag[5] != 0) /* gravity */
8516             image->gravity=(GravityType) argument_list[5].integer_reference;
8517           if (attribute_flag[2] != 0) /* geometry offset */
8518             {
8519               SetGeometry(image,&geometry);
8520               (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8521                 &geometry);
8522               GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8523                 &geometry);
8524             }
8525           if (attribute_flag[3] != 0) /* x offset */
8526             geometry.x=argument_list[3].integer_reference;
8527           if (attribute_flag[4] != 0) /* y offset */
8528             geometry.y=argument_list[4].integer_reference;
8529           if (attribute_flag[10] != 0) /* mask */
8530             {
8531               if ((image->compose == DisplaceCompositeOp) ||
8532                   (image->compose == DistortCompositeOp))
8533                 {
8534                   /*
8535                     Merge Y displacement into X displacement image.
8536                   */
8537                   composite_image=CloneImage(composite_image,0,0,MagickTrue,
8538                     exception);
8539                   (void) CompositeImage(composite_image,
8540                     argument_list[10].image_reference,CopyGreenCompositeOp,
8541                     MagickTrue,0,0,exception);
8542                 }
8543               else
8544                 {
8545                   Image
8546                     *mask_image;
8547
8548                   /*
8549                     Set a blending mask for the composition.
8550                   */
8551                   mask_image=CloneImage(argument_list[10].image_reference,0,0,
8552                     MagickTrue,exception);
8553                   (void) NegateImage(mask_image,MagickFalse,exception);
8554                   (void) SetImageMask(composite_image,mask_image,exception);
8555                   mask_image=DestroyImage(mask_image);
8556                 }
8557             }
8558           if (attribute_flag[11] != 0) /* channel */
8559             channel=(ChannelType) argument_list[11].integer_reference;
8560           /*
8561             Composite two images (normal composition).
8562           */
8563           (void) FormatLocaleString(composite_geometry,MaxTextExtent,
8564             "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8565             (double) composite_image->rows,(double) geometry.x,(double)
8566             geometry.y);
8567           flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8568             exception);
8569           channel_mask=SetImageChannelMask(image,channel);
8570           if (attribute_flag[8] == 0) /* no rotate */
8571             CompositeImage(image,composite_image,compose,clip_to_self,
8572               geometry.x,geometry.y,exception);
8573           else
8574             {
8575               /*
8576                 Position adjust rotated image then composite.
8577               */
8578               geometry.x-=(ssize_t) (rotate_image->columns-
8579                 composite_image->columns)/2;
8580               geometry.y-=(ssize_t) (rotate_image->rows-
8581                 composite_image->rows)/2;
8582               CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8583                 geometry.y,exception);
8584               rotate_image=DestroyImage(rotate_image);
8585             }
8586           if (attribute_flag[10] != 0) /* mask */
8587             {
8588               if ((image->compose == DisplaceCompositeOp) ||
8589                   (image->compose == DistortCompositeOp))
8590                 composite_image=DestroyImage(composite_image);
8591               else
8592                 (void) SetImageMask(image,(Image *) NULL,exception);
8593             }
8594           (void) SetImageChannelMask(image,channel_mask);
8595           break;
8596         }
8597         case 36:  /* Contrast */
8598         {
8599           if (attribute_flag[0] == 0)
8600             argument_list[0].integer_reference=0;
8601           (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8602             MagickTrue : MagickFalse,exception);
8603           break;
8604         }
8605         case 37:  /* CycleColormap */
8606         {
8607           if (attribute_flag[0] == 0)
8608             argument_list[0].integer_reference=6;
8609           (void) CycleColormapImage(image,argument_list[0].integer_reference,
8610             exception);
8611           break;
8612         }
8613         case 38:  /* Draw */
8614         {
8615           DrawInfo
8616             *draw_info;
8617
8618           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8619             (DrawInfo *) NULL);
8620           (void) CloneString(&draw_info->primitive,"point");
8621           if (attribute_flag[0] != 0)
8622             {
8623               if (argument_list[0].integer_reference < 0)
8624                 (void) CloneString(&draw_info->primitive,
8625                   argument_list[0].string_reference);
8626               else
8627                 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8628                   MagickPrimitiveOptions,argument_list[0].integer_reference));
8629             }
8630           if (attribute_flag[1] != 0)
8631             {
8632               if (LocaleCompare(draw_info->primitive,"path") == 0)
8633                 {
8634                   (void) ConcatenateString(&draw_info->primitive," '");
8635                   ConcatenateString(&draw_info->primitive,
8636                     argument_list[1].string_reference);
8637                   (void) ConcatenateString(&draw_info->primitive,"'");
8638                 }
8639               else
8640                 {
8641                   (void) ConcatenateString(&draw_info->primitive," ");
8642                   ConcatenateString(&draw_info->primitive,
8643                     argument_list[1].string_reference);
8644                 }
8645             }
8646           if (attribute_flag[2] != 0)
8647             {
8648               (void) ConcatenateString(&draw_info->primitive," ");
8649               (void) ConcatenateString(&draw_info->primitive,
8650                 CommandOptionToMnemonic(MagickMethodOptions,
8651                 argument_list[2].integer_reference));
8652             }
8653           if (attribute_flag[3] != 0)
8654             {
8655               (void) QueryColorCompliance(argument_list[3].string_reference,
8656                 AllCompliance,&draw_info->stroke,exception);
8657               if (argument_list[3].image_reference != (Image *) NULL)
8658                 draw_info->stroke_pattern=CloneImage(
8659                   argument_list[3].image_reference,0,0,MagickTrue,exception);
8660             }
8661           if (attribute_flag[4] != 0)
8662             {
8663               (void) QueryColorCompliance(argument_list[4].string_reference,
8664                 AllCompliance,&draw_info->fill,exception);
8665               if (argument_list[4].image_reference != (Image *) NULL)
8666                 draw_info->fill_pattern=CloneImage(
8667                   argument_list[4].image_reference,0,0,MagickTrue,exception);
8668             }
8669           if (attribute_flag[5] != 0)
8670             draw_info->stroke_width=argument_list[5].real_reference;
8671           if (attribute_flag[6] != 0)
8672             (void) CloneString(&draw_info->font,
8673               argument_list[6].string_reference);
8674           if (attribute_flag[7] != 0)
8675             (void) QueryColorCompliance(argument_list[7].string_reference,
8676               AllCompliance,&draw_info->border_color,exception);
8677           if (attribute_flag[8] != 0)
8678             draw_info->affine.tx=argument_list[8].real_reference;
8679           if (attribute_flag[9] != 0)
8680             draw_info->affine.ty=argument_list[9].real_reference;
8681           if (attribute_flag[20] != 0)
8682             {
8683               AV
8684                 *av;
8685
8686               av=(AV *) argument_list[20].array_reference;
8687               if ((av_len(av) != 3) && (av_len(av) != 5))
8688                 {
8689                   ThrowPerlException(exception,OptionError,
8690                     "affine matrix must have 4 or 6 elements",PackageName);
8691                   goto PerlException;
8692                 }
8693               draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8694               draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8695               draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8696               draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8697               if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8698                   draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8699                 {
8700                   ThrowPerlException(exception,OptionError,
8701                     "affine matrix is singular",PackageName);
8702                    goto PerlException;
8703                 }
8704               if (av_len(av) == 5)
8705                 {
8706                   draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8707                   draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8708                 }
8709             }
8710           for (j=10; j < 15; j++)
8711           {
8712             if (attribute_flag[j] == 0)
8713               continue;
8714             value=argument_list[j].string_reference;
8715             angle=argument_list[j].real_reference;
8716             current=draw_info->affine;
8717             GetAffineMatrix(&affine);
8718             switch (j)
8719             {
8720               case 10:
8721               {
8722                 /*
8723                   Translate.
8724                 */
8725                 flags=ParseGeometry(value,&geometry_info);
8726                 affine.tx=geometry_info.xi;
8727                 affine.ty=geometry_info.psi;
8728                 if ((flags & PsiValue) == 0)
8729                   affine.ty=affine.tx;
8730                 break;
8731               }
8732               case 11:
8733               {
8734                 /*
8735                   Scale.
8736                 */
8737                 flags=ParseGeometry(value,&geometry_info);
8738                 affine.sx=geometry_info.rho;
8739                 affine.sy=geometry_info.sigma;
8740                 if ((flags & SigmaValue) == 0)
8741                   affine.sy=affine.sx;
8742                 break;
8743               }
8744               case 12:
8745               {
8746                 /*
8747                   Rotate.
8748                 */
8749                 if (angle == 0.0)
8750                   break;
8751                 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8752                 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8753                 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8754                 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8755                 break;
8756               }
8757               case 13:
8758               {
8759                 /*
8760                   SkewX.
8761                 */
8762                 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8763                 break;
8764               }
8765               case 14:
8766               {
8767                 /*
8768                   SkewY.
8769                 */
8770                 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8771                 break;
8772               }
8773             }
8774             draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8775             draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8776             draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8777             draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8778             draw_info->affine.tx=
8779               current.sx*affine.tx+current.ry*affine.ty+current.tx;
8780             draw_info->affine.ty=
8781               current.rx*affine.tx+current.sy*affine.ty+current.ty;
8782           }
8783           if (attribute_flag[15] != 0)
8784             draw_info->fill_pattern=CloneImage(
8785               argument_list[15].image_reference,0,0,MagickTrue,exception);
8786           if (attribute_flag[16] != 0)
8787             draw_info->pointsize=argument_list[16].real_reference;
8788           if (attribute_flag[17] != 0)
8789             {
8790               draw_info->stroke_antialias=argument_list[17].integer_reference != 0
8791                 ? MagickTrue : MagickFalse;
8792               draw_info->text_antialias=draw_info->stroke_antialias;
8793             }
8794           if (attribute_flag[18] != 0)
8795             (void) CloneString(&draw_info->density,
8796               argument_list[18].string_reference);
8797           if (attribute_flag[19] != 0)
8798             draw_info->stroke_width=argument_list[19].real_reference;
8799           if (attribute_flag[21] != 0)
8800             draw_info->dash_offset=argument_list[21].real_reference;
8801           if (attribute_flag[22] != 0)
8802             {
8803               AV
8804                 *av;
8805
8806               av=(AV *) argument_list[22].array_reference;
8807               draw_info->dash_pattern=(double *) AcquireQuantumMemory(
8808                 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
8809               if (draw_info->dash_pattern != (double *) NULL)
8810                 {
8811                   for (i=0; i <= av_len(av); i++)
8812                     draw_info->dash_pattern[i]=(double)
8813                       SvNV(*(av_fetch(av,i,0)));
8814                   draw_info->dash_pattern[i]=0.0;
8815                 }
8816             }
8817           if (attribute_flag[23] != 0)
8818             image->interpolate=(PixelInterpolateMethod)
8819               argument_list[23].integer_reference;
8820           if ((attribute_flag[24] != 0) &&
8821               (draw_info->fill_pattern != (Image *) NULL))
8822             flags=ParsePageGeometry(draw_info->fill_pattern,
8823               argument_list[24].string_reference,
8824               &draw_info->fill_pattern->tile_offset,exception);
8825           if (attribute_flag[25] != 0)
8826             {
8827               (void) ConcatenateString(&draw_info->primitive," '");
8828               (void) ConcatenateString(&draw_info->primitive,
8829                 argument_list[25].string_reference);
8830               (void) ConcatenateString(&draw_info->primitive,"'");
8831             }
8832           if (attribute_flag[26] != 0)
8833             draw_info->fill_pattern=CloneImage(
8834               argument_list[26].image_reference,0,0,MagickTrue,exception);
8835           if (attribute_flag[27] != 0)
8836             draw_info->stroke_pattern=CloneImage(
8837               argument_list[27].image_reference,0,0,MagickTrue,exception);
8838           if (attribute_flag[28] != 0)
8839             (void) CloneString(&draw_info->primitive,
8840               argument_list[28].string_reference);
8841           if (attribute_flag[29] != 0)
8842             draw_info->kerning=argument_list[29].real_reference;
8843           if (attribute_flag[30] != 0)
8844             draw_info->interline_spacing=argument_list[30].real_reference;
8845           if (attribute_flag[31] != 0)
8846             draw_info->interword_spacing=argument_list[31].real_reference;
8847           if (attribute_flag[32] != 0)
8848             draw_info->direction=(DirectionType)
8849               argument_list[32].integer_reference;
8850           DrawImage(image,draw_info,exception);
8851           draw_info=DestroyDrawInfo(draw_info);
8852           break;
8853         }
8854         case 39:  /* Equalize */
8855         {
8856           if (attribute_flag[0] != 0)
8857             channel=(ChannelType) argument_list[0].integer_reference;
8858           channel_mask=SetImageChannelMask(image,channel);
8859           EqualizeImage(image,exception);
8860           (void) SetImageChannelMask(image,channel_mask);
8861           break;
8862         }
8863         case 40:  /* Gamma */
8864         {
8865           if (attribute_flag[1] != 0)
8866             channel=(ChannelType) argument_list[1].integer_reference;
8867           if (attribute_flag[2] == 0)
8868             argument_list[2].real_reference=1.0;
8869           if (attribute_flag[3] == 0)
8870             argument_list[3].real_reference=1.0;
8871           if (attribute_flag[4] == 0)
8872             argument_list[4].real_reference=1.0;
8873           if (attribute_flag[0] == 0)
8874             {
8875               (void) FormatLocaleString(message,MaxTextExtent,
8876                 "%.15g,%.15g,%.15g",(double) argument_list[2].real_reference,
8877                 (double) argument_list[3].real_reference,
8878                 (double) argument_list[4].real_reference);
8879               argument_list[0].string_reference=message;
8880             }
8881           (void) GammaImage(image,StringToDouble(
8882             argument_list[0].string_reference,(char **) NULL),exception);
8883           break;
8884         }
8885         case 41:  /* Map */
8886         {
8887           QuantizeInfo
8888             *quantize_info;
8889
8890           if (attribute_flag[0] == 0)
8891             {
8892               ThrowPerlException(exception,OptionError,"MapImageRequired",
8893                 PackageName);
8894               goto PerlException;
8895             }
8896           quantize_info=AcquireQuantizeInfo(info->image_info);
8897           if (attribute_flag[1] != 0)
8898             quantize_info->dither_method=(DitherMethod)
8899               argument_list[1].integer_reference;
8900           (void) RemapImages(quantize_info,image,
8901             argument_list[0].image_reference,exception);
8902           quantize_info=DestroyQuantizeInfo(quantize_info);
8903           break;
8904         }
8905         case 42:  /* MatteFloodfill */
8906         {
8907           DrawInfo
8908             *draw_info;
8909
8910           MagickBooleanType
8911             invert;
8912
8913           PixelInfo
8914             target;
8915
8916           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8917             (DrawInfo *) NULL);
8918           if (attribute_flag[0] != 0)
8919             flags=ParsePageGeometry(image,argument_list[0].string_reference,
8920               &geometry,exception);
8921           if (attribute_flag[1] != 0)
8922             geometry.x=argument_list[1].integer_reference;
8923           if (attribute_flag[2] != 0)
8924             geometry.y=argument_list[2].integer_reference;
8925           if (image->alpha_trait != BlendPixelTrait)
8926             (void) SetImageAlpha(image,OpaqueAlpha,exception);
8927           (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8928             geometry.x,geometry.y,&target,exception);
8929           if (attribute_flag[4] != 0)
8930             QueryColorCompliance(argument_list[4].string_reference,
8931               AllCompliance,&target,exception);
8932           if (attribute_flag[3] != 0)
8933             target.alpha=StringToDoubleInterval(
8934               argument_list[3].string_reference,(double) (double) QuantumRange+
8935               1.0);
8936           if (attribute_flag[5] != 0)
8937             image->fuzz=StringToDoubleInterval(
8938               argument_list[5].string_reference,(double) QuantumRange+1.0);
8939           invert=MagickFalse;
8940           if (attribute_flag[6] != 0)
8941             invert=(MagickBooleanType) argument_list[6].integer_reference;
8942           channel_mask=SetImageChannelMask(image,AlphaChannel);
8943           (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8944             geometry.y,invert,exception);
8945           (void) SetImageChannelMask(image,channel_mask);
8946           draw_info=DestroyDrawInfo(draw_info);
8947           break;
8948         }
8949         case 43:  /* Modulate */
8950         {
8951           char
8952             modulate[MaxTextExtent];
8953
8954           geometry_info.rho=100.0;
8955           geometry_info.sigma=100.0;
8956           geometry_info.xi=100.0;
8957           if (attribute_flag[0] != 0)
8958             (void)ParseGeometry(argument_list[0].string_reference,
8959               &geometry_info);
8960           if (attribute_flag[1] != 0)
8961             geometry_info.xi=argument_list[1].real_reference;
8962           if (attribute_flag[2] != 0)
8963             geometry_info.sigma=argument_list[2].real_reference;
8964           if (attribute_flag[3] != 0)
8965             {
8966               geometry_info.sigma=argument_list[3].real_reference;
8967               SetImageArtifact(image,"modulate:colorspace","HWB");
8968             }
8969           if (attribute_flag[4] != 0)
8970             {
8971               geometry_info.rho=argument_list[4].real_reference;
8972               SetImageArtifact(image,"modulate:colorspace","HSB");
8973             }
8974           if (attribute_flag[5] != 0)
8975             {
8976               geometry_info.sigma=argument_list[5].real_reference;
8977               SetImageArtifact(image,"modulate:colorspace","HSL");
8978             }
8979           if (attribute_flag[6] != 0)
8980             {
8981               geometry_info.rho=argument_list[6].real_reference;
8982               SetImageArtifact(image,"modulate:colorspace","HWB");
8983             }
8984           (void) FormatLocaleString(modulate,MaxTextExtent,"%.15g,%.15g,%.15g",
8985             geometry_info.rho,geometry_info.sigma,geometry_info.xi);
8986           (void) ModulateImage(image,modulate,exception);
8987           break;
8988         }
8989         case 44:  /* Negate */
8990         {
8991           if (attribute_flag[0] == 0)
8992             argument_list[0].integer_reference=0;
8993           if (attribute_flag[1] != 0)
8994             channel=(ChannelType) argument_list[1].integer_reference;
8995           channel_mask=SetImageChannelMask(image,channel);
8996           (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
8997             MagickTrue : MagickFalse,exception);
8998           (void) SetImageChannelMask(image,channel_mask);
8999           break;
9000         }
9001         case 45:  /* Normalize */
9002         {
9003           if (attribute_flag[0] != 0)
9004             channel=(ChannelType) argument_list[0].integer_reference;
9005           channel_mask=SetImageChannelMask(image,channel);
9006           NormalizeImage(image,exception);
9007           (void) SetImageChannelMask(image,channel_mask);
9008           break;
9009         }
9010         case 46:  /* NumberColors */
9011           break;
9012         case 47:  /* Opaque */
9013         {
9014           MagickBooleanType
9015             invert;
9016
9017           PixelInfo
9018             fill_color,
9019             target;
9020
9021           (void) QueryColorCompliance("none",AllCompliance,&target,
9022              exception);
9023           (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9024             exception);
9025           if (attribute_flag[0] != 0)
9026             (void) QueryColorCompliance(argument_list[0].string_reference,
9027               AllCompliance,&target,exception);
9028           if (attribute_flag[1] != 0)
9029             (void) QueryColorCompliance(argument_list[1].string_reference,
9030               AllCompliance,&fill_color,exception);
9031           if (attribute_flag[2] != 0)
9032             image->fuzz=StringToDoubleInterval(
9033               argument_list[2].string_reference,(double) QuantumRange+1.0);
9034           if (attribute_flag[3] != 0)
9035             channel=(ChannelType) argument_list[3].integer_reference;
9036           invert=MagickFalse;
9037           if (attribute_flag[4] != 0)
9038             invert=(MagickBooleanType) argument_list[4].integer_reference;
9039           channel_mask=SetImageChannelMask(image,channel);
9040           (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9041           (void) SetImageChannelMask(image,channel_mask);
9042           break;
9043         }
9044         case 48:  /* Quantize */
9045         {
9046           QuantizeInfo
9047             *quantize_info;
9048
9049           quantize_info=AcquireQuantizeInfo(info->image_info);
9050           if (attribute_flag[0] != 0)
9051             quantize_info->number_colors=(size_t)
9052               argument_list[0].integer_reference;
9053           if (attribute_flag[1] != 0)
9054             quantize_info->tree_depth=(size_t)
9055               argument_list[1].integer_reference;
9056           if (attribute_flag[2] != 0)
9057             quantize_info->colorspace=(ColorspaceType)
9058               argument_list[2].integer_reference;
9059           if (attribute_flag[3] != 0)
9060             quantize_info->dither_method=(DitherMethod)
9061               argument_list[3].integer_reference;
9062           if (attribute_flag[4] != 0)
9063             quantize_info->measure_error=argument_list[4].integer_reference !=
9064               0 ? MagickTrue : MagickFalse;
9065           if (attribute_flag[5] != 0)
9066             (void) QueryColorCompliance(argument_list[5].string_reference,
9067               AllCompliance,&image->transparent_color,exception);
9068           if (attribute_flag[5] && argument_list[5].integer_reference)
9069             {
9070               (void) QuantizeImages(quantize_info,image,exception);
9071               goto PerlException;
9072             }
9073           if (attribute_flag[6] != 0)
9074             quantize_info->dither_method=(DitherMethod)
9075               argument_list[6].integer_reference;
9076           if ((image->storage_class == DirectClass) ||
9077               (image->colors > quantize_info->number_colors) ||
9078               (quantize_info->colorspace == GRAYColorspace))
9079             (void) QuantizeImage(quantize_info,image,exception);
9080           else
9081             CompressImageColormap(image,exception);
9082           quantize_info=DestroyQuantizeInfo(quantize_info);
9083           break;
9084         }
9085         case 49:  /* Raise */
9086         {
9087           if (attribute_flag[0] != 0)
9088             flags=ParsePageGeometry(image,argument_list[0].string_reference,
9089               &geometry,exception);
9090           if (attribute_flag[1] != 0)
9091             geometry.width=argument_list[1].integer_reference;
9092           if (attribute_flag[2] != 0)
9093             geometry.height=argument_list[2].integer_reference;
9094           if (attribute_flag[3] == 0)
9095             argument_list[3].integer_reference=1;
9096           (void) RaiseImage(image,&geometry,
9097             argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9098             exception);
9099           break;
9100         }
9101         case 50:  /* Segment */
9102         {
9103           ColorspaceType
9104             colorspace;
9105
9106           double
9107             cluster_threshold,
9108             smoothing_threshold;
9109
9110           MagickBooleanType
9111             verbose;
9112
9113           cluster_threshold=1.0;
9114           smoothing_threshold=1.5;
9115           colorspace=sRGBColorspace;
9116           verbose=MagickFalse;
9117           if (attribute_flag[0] != 0)
9118             {
9119               flags=ParseGeometry(argument_list[0].string_reference,
9120                 &geometry_info);
9121               cluster_threshold=geometry_info.rho;
9122               if (flags & SigmaValue)
9123                 smoothing_threshold=geometry_info.sigma;
9124             }
9125           if (attribute_flag[1] != 0)
9126             cluster_threshold=argument_list[1].real_reference;
9127           if (attribute_flag[2] != 0)
9128             smoothing_threshold=argument_list[2].real_reference;
9129           if (attribute_flag[3] != 0)
9130             colorspace=(ColorspaceType) argument_list[3].integer_reference;
9131           if (attribute_flag[4] != 0)
9132             verbose=argument_list[4].integer_reference != 0 ?
9133               MagickTrue : MagickFalse;
9134           (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9135             smoothing_threshold,exception);
9136           break;
9137         }
9138         case 51:  /* Signature */
9139         {
9140           (void) SignatureImage(image,exception);
9141           break;
9142         }
9143         case 52:  /* Solarize */
9144         {
9145           geometry_info.rho=QuantumRange/2.0;
9146           if (attribute_flag[0] != 0)
9147             flags=ParseGeometry(argument_list[0].string_reference,
9148               &geometry_info);
9149           if (attribute_flag[1] != 0)
9150             geometry_info.rho=StringToDoubleInterval(
9151               argument_list[1].string_reference,(double) QuantumRange+1.0);
9152           (void) SolarizeImage(image,geometry_info.rho,exception);
9153           break;
9154         }
9155         case 53:  /* Sync */
9156         {
9157           (void) SyncImage(image,exception);
9158           break;
9159         }
9160         case 54:  /* Texture */
9161         {
9162           if (attribute_flag[0] == 0)
9163             break;
9164           TextureImage(image,argument_list[0].image_reference,exception);
9165           break;
9166         }
9167         case 55:  /* Evalute */
9168         {
9169           MagickEvaluateOperator
9170             op;
9171
9172           op=SetEvaluateOperator;
9173           if (attribute_flag[0] == MagickFalse)
9174             argument_list[0].real_reference=0.0;
9175           if (attribute_flag[1] != MagickFalse)
9176             op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9177           if (attribute_flag[2] != MagickFalse)
9178             channel=(ChannelType) argument_list[2].integer_reference;
9179           channel_mask=SetImageChannelMask(image,channel);
9180           (void) EvaluateImage(image,op,argument_list[0].real_reference,
9181             exception);
9182           (void) SetImageChannelMask(image,channel_mask);
9183           break;
9184         }
9185         case 56:  /* Transparent */
9186         {
9187           double
9188             opacity;
9189
9190           MagickBooleanType
9191             invert;
9192
9193           PixelInfo
9194             target;
9195
9196           (void) QueryColorCompliance("none",AllCompliance,&target,
9197             exception);
9198           if (attribute_flag[0] != 0)
9199             (void) QueryColorCompliance(argument_list[0].string_reference,
9200               AllCompliance,&target,exception);
9201           opacity=TransparentAlpha;
9202           if (attribute_flag[1] != 0)
9203             opacity=StringToDoubleInterval(argument_list[1].string_reference,
9204               (double) QuantumRange+1.0);
9205           if (attribute_flag[2] != 0)
9206             image->fuzz=StringToDoubleInterval(
9207               argument_list[2].string_reference,(double) QuantumRange+1.0);
9208           if (attribute_flag[3] == 0)
9209             argument_list[3].integer_reference=0;
9210           invert=MagickFalse;
9211           if (attribute_flag[3] != 0)
9212             invert=(MagickBooleanType) argument_list[3].integer_reference;
9213           (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9214             invert,exception);
9215           break;
9216         }
9217         case 57:  /* Threshold */
9218         {
9219           double
9220             threshold;
9221
9222           if (attribute_flag[0] == 0)
9223             argument_list[0].string_reference="50%";
9224           if (attribute_flag[1] != 0)
9225             channel=(ChannelType) argument_list[1].integer_reference;
9226           threshold=StringToDoubleInterval(argument_list[0].string_reference,
9227             (double) QuantumRange+1.0);
9228           channel_mask=SetImageChannelMask(image,channel);
9229           (void) BilevelImage(image,threshold,exception);
9230           (void) SetImageChannelMask(image,channel_mask);
9231           break;
9232         }
9233         case 58:  /* Charcoal */
9234         {
9235           if (attribute_flag[0] != 0)
9236             {
9237               flags=ParseGeometry(argument_list[0].string_reference,
9238                 &geometry_info);
9239               if ((flags & SigmaValue) == 0)
9240                 geometry_info.sigma=1.0;
9241             }
9242           if (attribute_flag[1] != 0)
9243             geometry_info.rho=argument_list[1].real_reference;
9244           if (attribute_flag[2] != 0)
9245             geometry_info.sigma=argument_list[2].real_reference;
9246           image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9247             exception);
9248           break;
9249         }
9250         case 59:  /* Trim */
9251         {
9252           if (attribute_flag[0] != 0)
9253             image->fuzz=StringToDoubleInterval(
9254               argument_list[0].string_reference,(double) QuantumRange+1.0);
9255           image=TrimImage(image,exception);
9256           break;
9257         }
9258         case 60:  /* Wave */
9259         {
9260           PixelInterpolateMethod
9261             method;
9262
9263           if (attribute_flag[0] != 0)
9264             {
9265               flags=ParseGeometry(argument_list[0].string_reference,
9266                 &geometry_info);
9267               if ((flags & SigmaValue) == 0)
9268                 geometry_info.sigma=1.0;
9269             }
9270           if (attribute_flag[1] != 0)
9271             geometry_info.rho=argument_list[1].real_reference;
9272           if (attribute_flag[2] != 0)
9273             geometry_info.sigma=argument_list[2].real_reference;
9274           method=UndefinedInterpolatePixel;
9275           if (attribute_flag[3] != 0)
9276             method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9277           image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9278             method,exception);
9279           break;
9280         }
9281         case 61:  /* Separate */
9282         {
9283           if (attribute_flag[0] != 0)
9284             channel=(ChannelType) argument_list[0].integer_reference;
9285           image=SeparateImage(image,channel,exception);
9286           break;
9287         }
9288         case 63:  /* Stereo */
9289         {
9290           if (attribute_flag[0] == 0)
9291             {
9292               ThrowPerlException(exception,OptionError,"StereoImageRequired",
9293                 PackageName);
9294               goto PerlException;
9295             }
9296           if (attribute_flag[1] != 0)
9297             geometry.x=argument_list[1].integer_reference;
9298           if (attribute_flag[2] != 0)
9299             geometry.y=argument_list[2].integer_reference;
9300           image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9301             geometry.x,geometry.y,exception);
9302           break;
9303         }
9304         case 64:  /* Stegano */
9305         {
9306           if (attribute_flag[0] == 0)
9307             {
9308               ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9309                 PackageName);
9310               goto PerlException;
9311             }
9312           if (attribute_flag[1] == 0)
9313             argument_list[1].integer_reference=0;
9314           image->offset=argument_list[1].integer_reference;
9315           image=SteganoImage(image,argument_list[0].image_reference,exception);
9316           break;
9317         }
9318         case 65:  /* Deconstruct */
9319         {
9320           image=CompareImagesLayers(image,CompareAnyLayer,exception);
9321           break;
9322         }
9323         case 66:  /* GaussianBlur */
9324         {
9325           if (attribute_flag[0] != 0)
9326             {
9327               flags=ParseGeometry(argument_list[0].string_reference,
9328                 &geometry_info);
9329               if ((flags & SigmaValue) == 0)
9330                 geometry_info.sigma=1.0;
9331             }
9332           if (attribute_flag[1] != 0)
9333             geometry_info.rho=argument_list[1].real_reference;
9334           if (attribute_flag[2] != 0)
9335             geometry_info.sigma=argument_list[2].real_reference;
9336           if (attribute_flag[3] != 0)
9337             channel=(ChannelType) argument_list[3].integer_reference;
9338           channel_mask=SetImageChannelMask(image,channel);
9339           image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9340             exception);
9341           if (image != (Image *) NULL)
9342             (void) SetImageChannelMask(image,channel_mask);
9343           break;
9344         }
9345         case 67:  /* Convolve */
9346         {
9347           KernelInfo
9348             *kernel;
9349
9350           kernel=(KernelInfo *) NULL;
9351           if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9352             break;
9353           if (attribute_flag[0] != 0)
9354             {
9355               AV
9356                 *av;
9357
9358               size_t
9359                 order;
9360
9361               kernel=AcquireKernelInfo((const char *) NULL);
9362               if (kernel == (KernelInfo *) NULL)
9363                 break;
9364               av=(AV *) argument_list[0].array_reference;
9365               order=(size_t) sqrt(av_len(av)+1);
9366               kernel->width=order;
9367               kernel->height=order;
9368               kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9369                 order*sizeof(*kernel->values));
9370               if (kernel->values == (MagickRealType *) NULL)
9371                 {
9372                   kernel=DestroyKernelInfo(kernel);
9373                   ThrowPerlException(exception,ResourceLimitFatalError,
9374                     "MemoryAllocationFailed",PackageName);
9375                   goto PerlException;
9376                 }
9377               for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9378                 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9379               for ( ; j < (ssize_t) (order*order); j++)
9380                 kernel->values[j]=0.0;
9381             }
9382           if (attribute_flag[1] != 0)
9383             channel=(ChannelType) argument_list[1].integer_reference;
9384           if (attribute_flag[2] != 0)
9385             SetImageArtifact(image,"filter:blur",
9386               argument_list[2].string_reference);
9387           if (attribute_flag[3] != 0)
9388             {
9389               kernel=AcquireKernelInfo(argument_list[3].string_reference);
9390               if (kernel == (KernelInfo *) NULL)
9391                 break;
9392             }
9393           channel_mask=SetImageChannelMask(image,channel);
9394           image=ConvolveImage(image,kernel,exception);
9395           if (image != (Image *) NULL)
9396             (void) SetImageChannelMask(image,channel_mask);
9397           kernel=DestroyKernelInfo(kernel);
9398           break;
9399         }
9400         case 68:  /* Profile */
9401         {
9402           const char
9403             *name;
9404
9405           Image
9406             *profile_image;
9407
9408           ImageInfo
9409             *profile_info;
9410
9411           StringInfo
9412             *profile;
9413
9414           name="*";
9415           if (attribute_flag[0] != 0)
9416             name=argument_list[0].string_reference;
9417           if (attribute_flag[2] != 0)
9418             image->rendering_intent=(RenderingIntent)
9419               argument_list[2].integer_reference;
9420           if (attribute_flag[3] != 0)
9421             image->black_point_compensation=
9422               argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9423           if (attribute_flag[1] != 0)
9424             {
9425               if (argument_list[1].length == 0)
9426                 {
9427                   /*
9428                     Remove a profile from the image.
9429                   */
9430                   (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9431                     exception);
9432                   break;
9433                 }
9434               /*
9435                 Associate user supplied profile with the image.
9436               */
9437               profile=AcquireStringInfo(argument_list[1].length);
9438               SetStringInfoDatum(profile,(const unsigned char *)
9439                 argument_list[1].string_reference);
9440               (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9441                 (size_t) GetStringInfoLength(profile),exception);
9442               profile=DestroyStringInfo(profile);
9443               break;
9444             }
9445           /*
9446             Associate a profile with the image.
9447           */
9448           profile_info=CloneImageInfo(info ? info->image_info :
9449             (ImageInfo *) NULL);
9450           profile_image=ReadImages(profile_info,name,exception);
9451           if (profile_image == (Image *) NULL)
9452             break;
9453           ResetImageProfileIterator(profile_image);
9454           name=GetNextImageProfile(profile_image);
9455           while (name != (const char *) NULL)
9456           {
9457             const StringInfo
9458               *profile;
9459
9460             profile=GetImageProfile(profile_image,name);
9461             if (profile != (const StringInfo *) NULL)
9462               (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9463                 (size_t) GetStringInfoLength(profile),exception);
9464             name=GetNextImageProfile(profile_image);
9465           }
9466           profile_image=DestroyImage(profile_image);
9467           profile_info=DestroyImageInfo(profile_info);
9468           break;
9469         }
9470         case 69:  /* UnsharpMask */
9471         {
9472           if (attribute_flag[0] != 0)
9473             {
9474               flags=ParseGeometry(argument_list[0].string_reference,
9475                 &geometry_info);
9476               if ((flags & SigmaValue) == 0)
9477                 geometry_info.sigma=1.0;
9478               if ((flags & XiValue) == 0)
9479                 geometry_info.xi=1.0;
9480               if ((flags & PsiValue) == 0)
9481                 geometry_info.psi=0.5;
9482             }
9483           if (attribute_flag[1] != 0)
9484             geometry_info.rho=argument_list[1].real_reference;
9485           if (attribute_flag[2] != 0)
9486             geometry_info.sigma=argument_list[2].real_reference;
9487           if (attribute_flag[3] != 0)
9488             geometry_info.xi=argument_list[3].real_reference;
9489           if (attribute_flag[4] != 0)
9490             channel=(ChannelType) argument_list[4].integer_reference;
9491           channel_mask=SetImageChannelMask(image,channel);
9492           image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9493             geometry_info.xi,exception);
9494           if (image != (Image *) NULL)
9495             (void) SetImageChannelMask(image,channel_mask);
9496           break;
9497         }
9498         case 70:  /* MotionBlur */
9499         {
9500           if (attribute_flag[0] != 0)
9501             {
9502               flags=ParseGeometry(argument_list[0].string_reference,
9503                 &geometry_info);
9504               if ((flags & SigmaValue) == 0)
9505                 geometry_info.sigma=1.0;
9506               if ((flags & XiValue) == 0)
9507                 geometry_info.xi=1.0;
9508             }
9509           if (attribute_flag[1] != 0)
9510             geometry_info.rho=argument_list[1].real_reference;
9511           if (attribute_flag[2] != 0)
9512             geometry_info.sigma=argument_list[2].real_reference;
9513           if (attribute_flag[3] != 0)
9514             geometry_info.xi=argument_list[3].real_reference;
9515           if (attribute_flag[4] != 0)
9516             channel=(ChannelType) argument_list[4].integer_reference;
9517           channel_mask=SetImageChannelMask(image,channel);
9518           image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9519             geometry_info.xi,exception);
9520           if (image != (Image *) NULL)
9521             (void) SetImageChannelMask(image,channel_mask);
9522           break;
9523         }
9524         case 71:  /* OrderedDither */
9525         {
9526           if (attribute_flag[0] == 0)
9527             argument_list[0].string_reference="o8x8";
9528           if (attribute_flag[1] != 0)
9529             channel=(ChannelType) argument_list[1].integer_reference;
9530           channel_mask=SetImageChannelMask(image,channel);
9531           (void) OrderedPosterizeImage(image,argument_list[0].string_reference,
9532             exception);
9533           (void) SetImageChannelMask(image,channel_mask);
9534           break;
9535         }
9536         case 72:  /* Shave */
9537         {
9538           if (attribute_flag[0] != 0)
9539             flags=ParsePageGeometry(image,argument_list[0].string_reference,
9540               &geometry,exception);
9541           if (attribute_flag[1] != 0)
9542             geometry.width=argument_list[1].integer_reference;
9543           if (attribute_flag[2] != 0)
9544             geometry.height=argument_list[2].integer_reference;
9545           image=ShaveImage(image,&geometry,exception);
9546           break;
9547         }
9548         case 73:  /* Level */
9549         {
9550           double
9551             black_point,
9552             gamma,
9553             white_point;
9554
9555           black_point=0.0;
9556           white_point=(double) image->columns*image->rows;
9557           gamma=1.0;
9558           if (attribute_flag[0] != 0)
9559             {
9560               flags=ParseGeometry(argument_list[0].string_reference,
9561                 &geometry_info);
9562               black_point=geometry_info.rho;
9563               if ((flags & SigmaValue) != 0)
9564                 white_point=geometry_info.sigma;
9565               if ((flags & XiValue) != 0)
9566                 gamma=geometry_info.xi;
9567               if ((flags & PercentValue) != 0)
9568                 {
9569                   black_point*=(double) (QuantumRange/100.0);
9570                   white_point*=(double) (QuantumRange/100.0);
9571                 }
9572               if ((flags & SigmaValue) == 0)
9573                 white_point=(double) QuantumRange-black_point;
9574             }
9575           if (attribute_flag[1] != 0)
9576             black_point=argument_list[1].real_reference;
9577           if (attribute_flag[2] != 0)
9578             white_point=argument_list[2].real_reference;
9579           if (attribute_flag[3] != 0)
9580             gamma=argument_list[3].real_reference;
9581           if (attribute_flag[4] != 0)
9582             channel=(ChannelType) argument_list[4].integer_reference;
9583           if (attribute_flag[5] != 0)
9584             {
9585               argument_list[0].real_reference=argument_list[5].real_reference;
9586               attribute_flag[0]=attribute_flag[5];
9587             }
9588           channel_mask=SetImageChannelMask(image,channel);
9589           (void) LevelImage(image,black_point,white_point,gamma,exception);
9590           (void) SetImageChannelMask(image,channel_mask);
9591           break;
9592         }
9593         case 74:  /* Clip */
9594         {
9595           if (attribute_flag[0] == 0)
9596             argument_list[0].string_reference="#1";
9597           if (attribute_flag[1] == 0)
9598             argument_list[1].integer_reference=MagickTrue;
9599           (void) ClipImagePath(image,argument_list[0].string_reference,
9600             argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9601             exception);
9602           break;
9603         }
9604         case 75:  /* AffineTransform */
9605         {
9606           DrawInfo
9607             *draw_info;
9608
9609           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9610             (DrawInfo *) NULL);
9611           if (attribute_flag[0] != 0)
9612             {
9613               AV
9614                 *av;
9615
9616               av=(AV *) argument_list[0].array_reference;
9617               if ((av_len(av) != 3) && (av_len(av) != 5))
9618                 {
9619                   ThrowPerlException(exception,OptionError,
9620                     "affine matrix must have 4 or 6 elements",PackageName);
9621                   goto PerlException;
9622                 }
9623               draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9624               draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9625               draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9626               draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9627               if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9628                   draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9629                 {
9630                   ThrowPerlException(exception,OptionError,
9631                     "affine matrix is singular",PackageName);
9632                    goto PerlException;
9633                 }
9634               if (av_len(av) == 5)
9635                 {
9636                   draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9637                   draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9638                 }
9639             }
9640           for (j=1; j < 6; j++)
9641           {
9642             if (attribute_flag[j] == 0)
9643               continue;
9644             value=argument_list[j].string_reference;
9645             angle=argument_list[j].real_reference;
9646             current=draw_info->affine;
9647             GetAffineMatrix(&affine);
9648             switch (j)
9649             {
9650               case 1:
9651               {
9652                 /*
9653                   Translate.
9654                 */
9655                 flags=ParseGeometry(value,&geometry_info);
9656                 affine.tx=geometry_info.xi;
9657                 affine.ty=geometry_info.psi;
9658                 if ((flags & PsiValue) == 0)
9659                   affine.ty=affine.tx;
9660                 break;
9661               }
9662               case 2:
9663               {
9664                 /*
9665                   Scale.
9666                 */
9667                 flags=ParseGeometry(value,&geometry_info);
9668                 affine.sx=geometry_info.rho;
9669                 affine.sy=geometry_info.sigma;
9670                 if ((flags & SigmaValue) == 0)
9671                   affine.sy=affine.sx;
9672                 break;
9673               }
9674               case 3:
9675               {
9676                 /*
9677                   Rotate.
9678                 */
9679                 if (angle == 0.0)
9680                   break;
9681                 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9682                 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9683                 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9684                 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9685                 break;
9686               }
9687               case 4:
9688               {
9689                 /*
9690                   SkewX.
9691                 */
9692                 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9693                 break;
9694               }
9695               case 5:
9696               {
9697                 /*
9698                   SkewY.
9699                 */
9700                 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9701                 break;
9702               }
9703             }
9704             draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9705             draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9706             draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9707             draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9708             draw_info->affine.tx=
9709               current.sx*affine.tx+current.ry*affine.ty+current.tx;
9710             draw_info->affine.ty=
9711               current.rx*affine.tx+current.sy*affine.ty+current.ty;
9712           }
9713           if (attribute_flag[6] != 0)
9714             image->interpolate=(PixelInterpolateMethod)
9715               argument_list[6].integer_reference;
9716           if (attribute_flag[7] != 0)
9717             QueryColorCompliance(argument_list[7].string_reference,
9718               AllCompliance,&image->background_color,exception);
9719           image=AffineTransformImage(image,&draw_info->affine,exception);
9720           draw_info=DestroyDrawInfo(draw_info);
9721           break;
9722         }
9723         case 76:  /* Difference */
9724         {
9725           if (attribute_flag[0] == 0)
9726             {
9727               ThrowPerlException(exception,OptionError,
9728                 "ReferenceImageRequired",PackageName);
9729               goto PerlException;
9730             }
9731           if (attribute_flag[1] != 0)
9732             image->fuzz=StringToDoubleInterval(
9733               argument_list[1].string_reference,(double) QuantumRange+1.0);
9734           (void) IsImagesEqual(image,argument_list[0].image_reference,
9735             exception);
9736           break;
9737         }
9738         case 77:  /* AdaptiveThreshold */
9739         {
9740           if (attribute_flag[0] != 0)
9741             {
9742               flags=ParseGeometry(argument_list[0].string_reference,
9743                 &geometry_info);
9744               if ((flags & PercentValue) != 0)
9745                 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9746             }
9747           if (attribute_flag[1] != 0)
9748             geometry_info.rho=argument_list[1].integer_reference;
9749           if (attribute_flag[2] != 0)
9750             geometry_info.sigma=argument_list[2].integer_reference;
9751           if (attribute_flag[3] != 0)
9752             geometry_info.xi=argument_list[3].integer_reference;;
9753           image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
9754             (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
9755           break;
9756         }
9757         case 78:  /* Resample */
9758         {
9759           size_t
9760             height,
9761             width;
9762
9763           if (attribute_flag[0] != 0)
9764             {
9765               flags=ParseGeometry(argument_list[0].string_reference,
9766                 &geometry_info);
9767               if ((flags & SigmaValue) == 0)
9768                 geometry_info.sigma=geometry_info.rho;
9769             }
9770           if (attribute_flag[1] != 0)
9771             geometry_info.rho=argument_list[1].real_reference;
9772           if (attribute_flag[2] != 0)
9773             geometry_info.sigma=argument_list[2].real_reference;
9774           if (attribute_flag[3] == 0)
9775             argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
9776           if (attribute_flag[4] == 0)
9777             SetImageArtifact(image,"filter:support",
9778               argument_list[4].string_reference);
9779           width=(size_t) (geometry_info.rho*image->columns/
9780             (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
9781           height=(size_t) (geometry_info.sigma*image->rows/
9782             (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
9783           image=ResizeImage(image,width,height,(FilterTypes)
9784             argument_list[3].integer_reference,exception);
9785           if (image != (Image *) NULL)
9786             {
9787               image->resolution.x=geometry_info.rho;
9788               image->resolution.y=geometry_info.sigma;
9789             }
9790           break;
9791         }
9792         case 79:  /* Describe */
9793         {
9794           if (attribute_flag[0] == 0)
9795             argument_list[0].file_reference=(FILE *) NULL;
9796           if (attribute_flag[1] != 0)
9797             (void) SetImageArtifact(image,"identify:features",
9798               argument_list[1].string_reference);
9799           (void) IdentifyImage(image,argument_list[0].file_reference,
9800             MagickTrue,exception);
9801           break;
9802         }
9803         case 80:  /* BlackThreshold */
9804         {
9805           if (attribute_flag[0] == 0)
9806             argument_list[0].string_reference="50%";
9807           if (attribute_flag[2] != 0)
9808             channel=(ChannelType) argument_list[2].integer_reference;
9809           channel_mask=SetImageChannelMask(image,channel);
9810           BlackThresholdImage(image,argument_list[0].string_reference,
9811             exception);
9812           (void) SetImageChannelMask(image,channel_mask);
9813           break;
9814         }
9815         case 81:  /* WhiteThreshold */
9816         {
9817           if (attribute_flag[0] == 0)
9818             argument_list[0].string_reference="50%";
9819           if (attribute_flag[2] != 0)
9820             channel=(ChannelType) argument_list[2].integer_reference;
9821           channel_mask=SetImageChannelMask(image,channel);
9822           WhiteThresholdImage(image,argument_list[0].string_reference,
9823             exception);
9824           (void) SetImageChannelMask(image,channel_mask);
9825           break;
9826         }
9827         case 82:  /* RadialBlur */
9828         {
9829           if (attribute_flag[0] != 0)
9830             {
9831               flags=ParseGeometry(argument_list[0].string_reference,
9832                 &geometry_info);
9833             }
9834           if (attribute_flag[1] != 0)
9835             geometry_info.rho=argument_list[1].real_reference;
9836           if (attribute_flag[2] != 0)
9837             channel=(ChannelType) argument_list[2].integer_reference;
9838           channel_mask=SetImageChannelMask(image,channel);
9839           image=RadialBlurImage(image,geometry_info.rho,exception);
9840           if (image != (Image *) NULL)
9841             (void) SetImageChannelMask(image,channel_mask);
9842           break;
9843         }
9844         case 83:  /* Thumbnail */
9845         {
9846           if (attribute_flag[0] != 0)
9847             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
9848               &geometry,exception);
9849           if (attribute_flag[1] != 0)
9850             geometry.width=argument_list[1].integer_reference;
9851           if (attribute_flag[2] != 0)
9852             geometry.height=argument_list[2].integer_reference;
9853           image=ThumbnailImage(image,geometry.width,geometry.height,exception);
9854           break;
9855         }
9856         case 84:  /* Strip */
9857         {
9858           (void) StripImage(image,exception);
9859           break;
9860         }
9861         case 85:  /* Tint */
9862         {
9863           PixelInfo
9864             tint;
9865
9866           GetPixelInfo(image,&tint);
9867           if (attribute_flag[0] != 0)
9868             (void) QueryColorCompliance(argument_list[0].string_reference,
9869               AllCompliance,&tint,exception);
9870           if (attribute_flag[1] == 0)
9871             argument_list[1].string_reference="100";
9872           image=TintImage(image,argument_list[1].string_reference,&tint,
9873             exception);
9874           break;
9875         }
9876         case 86:  /* Channel */
9877         {
9878           if (attribute_flag[0] != 0)
9879             channel=(ChannelType) argument_list[0].integer_reference;
9880           image=SeparateImage(image,channel,exception);
9881           break;
9882         }
9883         case 87:  /* Splice */
9884         {
9885           if (attribute_flag[0] != 0)
9886             flags=ParseGravityGeometry(image,argument_list[0].string_reference,
9887               &geometry,exception);
9888           if (attribute_flag[1] != 0)
9889             geometry.width=argument_list[1].integer_reference;
9890           if (attribute_flag[2] != 0)
9891             geometry.height=argument_list[2].integer_reference;
9892           if (attribute_flag[3] != 0)
9893             geometry.x=argument_list[3].integer_reference;
9894           if (attribute_flag[4] != 0)
9895             geometry.y=argument_list[4].integer_reference;
9896           if (attribute_flag[5] != 0)
9897             image->fuzz=StringToDoubleInterval(
9898               argument_list[5].string_reference,(double) QuantumRange+1.0);
9899           if (attribute_flag[6] != 0)
9900             (void) QueryColorCompliance(argument_list[6].string_reference,
9901               AllCompliance,&image->background_color,exception);
9902           if (attribute_flag[7] != 0)
9903             image->gravity=(GravityType) argument_list[7].integer_reference;
9904           image=SpliceImage(image,&geometry,exception);
9905           break;
9906         }
9907         case 88:  /* Posterize */
9908         {
9909           if (attribute_flag[0] == 0)
9910             argument_list[0].integer_reference=3;
9911           if (attribute_flag[1] == 0)
9912             argument_list[1].integer_reference=0;
9913           (void) PosterizeImage(image,argument_list[0].integer_reference,
9914             argument_list[1].integer_reference ? RiemersmaDitherMethod :
9915             NoDitherMethod,exception);
9916           break;
9917         }
9918         case 89:  /* Shadow */
9919         {
9920           if (attribute_flag[0] != 0)
9921             {
9922               flags=ParseGeometry(argument_list[0].string_reference,
9923                 &geometry_info);
9924               if ((flags & SigmaValue) == 0)
9925                 geometry_info.sigma=1.0;
9926               if ((flags & XiValue) == 0)
9927                 geometry_info.xi=4.0;
9928               if ((flags & PsiValue) == 0)
9929                 geometry_info.psi=4.0;
9930             }
9931           if (attribute_flag[1] != 0)
9932             geometry_info.rho=argument_list[1].real_reference;
9933           if (attribute_flag[2] != 0)
9934             geometry_info.sigma=argument_list[2].real_reference;
9935           if (attribute_flag[3] != 0)
9936             geometry_info.xi=argument_list[3].integer_reference;
9937           if (attribute_flag[4] != 0)
9938             geometry_info.psi=argument_list[4].integer_reference;
9939           image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
9940             (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
9941             ceil(geometry_info.psi-0.5),exception);
9942           break;
9943         }
9944         case 90:  /* Identify */
9945         {
9946           if (attribute_flag[0] == 0)
9947             argument_list[0].file_reference=(FILE *) NULL;
9948           if (attribute_flag[1] != 0)
9949             (void) SetImageArtifact(image,"identify:features",
9950               argument_list[1].string_reference);
9951           if ((attribute_flag[2] != 0) &&
9952               (argument_list[2].integer_reference != 0))
9953             (void) SetImageArtifact(image,"identify:unique","true");
9954           (void) IdentifyImage(image,argument_list[0].file_reference,
9955             MagickTrue,exception);
9956           break;
9957         }
9958         case 91:  /* SepiaTone */
9959         {
9960           if (attribute_flag[0] == 0)
9961             argument_list[0].real_reference=80.0*QuantumRange/100.0;
9962           image=SepiaToneImage(image,argument_list[0].real_reference,
9963             exception);
9964           break;
9965         }
9966         case 92:  /* SigmoidalContrast */
9967         {
9968           MagickBooleanType
9969             sharpen;
9970
9971           if (attribute_flag[0] != 0)
9972             {
9973               flags=ParseGeometry(argument_list[0].string_reference,
9974                 &geometry_info);
9975               if ((flags & SigmaValue) == 0)
9976                 geometry_info.sigma=QuantumRange/2.0;
9977               if ((flags & PercentValue) != 0)
9978                 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
9979             }
9980           if (attribute_flag[1] != 0)
9981             geometry_info.rho=argument_list[1].real_reference;
9982           if (attribute_flag[2] != 0)
9983             geometry_info.sigma=argument_list[2].real_reference;
9984           if (attribute_flag[3] != 0)
9985             channel=(ChannelType) argument_list[3].integer_reference;
9986           sharpen=MagickTrue;
9987           if (attribute_flag[4] != 0)
9988             sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
9989               MagickFalse;
9990           channel_mask=SetImageChannelMask(image,channel);
9991           (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
9992             geometry_info.sigma,exception);
9993           (void) SetImageChannelMask(image,channel_mask);
9994           break;
9995         }
9996         case 93:  /* Extent */
9997         {
9998           if (attribute_flag[7] != 0)
9999             image->gravity=(GravityType) argument_list[7].integer_reference;
10000           if (attribute_flag[0] != 0)
10001             {
10002               int
10003                 flags;
10004
10005               flags=ParseGravityGeometry(image,
10006                 argument_list[0].string_reference,&geometry,exception);
10007               (void) flags;
10008               if (geometry.width == 0)
10009                 geometry.width=image->columns;
10010               if (geometry.height == 0)
10011                 geometry.height=image->rows;
10012             }
10013           if (attribute_flag[1] != 0)
10014             geometry.width=argument_list[1].integer_reference;
10015           if (attribute_flag[2] != 0)
10016             geometry.height=argument_list[2].integer_reference;
10017           if (attribute_flag[3] != 0)
10018             geometry.x=argument_list[3].integer_reference;
10019           if (attribute_flag[4] != 0)
10020             geometry.y=argument_list[4].integer_reference;
10021           if (attribute_flag[5] != 0)
10022             image->fuzz=StringToDoubleInterval(
10023               argument_list[5].string_reference,(double) QuantumRange+1.0);
10024           if (attribute_flag[6] != 0)
10025             (void) QueryColorCompliance(argument_list[6].string_reference,
10026               AllCompliance,&image->background_color,exception);
10027           image=ExtentImage(image,&geometry,exception);
10028           break;
10029         }
10030         case 94:  /* Vignette */
10031         {
10032           if (attribute_flag[0] != 0)
10033             {
10034               flags=ParseGeometry(argument_list[0].string_reference,
10035                 &geometry_info);
10036               if ((flags & SigmaValue) == 0)
10037                 geometry_info.sigma=1.0;
10038               if ((flags & XiValue) == 0)
10039                 geometry_info.xi=0.1*image->columns;
10040               if ((flags & PsiValue) == 0)
10041                 geometry_info.psi=0.1*image->rows;
10042             }
10043           if (attribute_flag[1] != 0)
10044             geometry_info.rho=argument_list[1].real_reference;
10045           if (attribute_flag[2] != 0)
10046             geometry_info.sigma=argument_list[2].real_reference;
10047           if (attribute_flag[3] != 0)
10048             geometry_info.xi=argument_list[3].integer_reference;
10049           if (attribute_flag[4] != 0)
10050             geometry_info.psi=argument_list[4].integer_reference;
10051           if (attribute_flag[5] != 0)
10052             (void) QueryColorCompliance(argument_list[5].string_reference,
10053               AllCompliance,&image->background_color,exception);
10054           image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10055             (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10056             ceil(geometry_info.psi-0.5),exception);
10057           break;
10058         }
10059         case 95:  /* ContrastStretch */
10060         {
10061           double
10062             black_point,
10063             white_point;
10064
10065           black_point=0.0;
10066           white_point=(double) image->columns*image->rows;
10067           if (attribute_flag[0] != 0)
10068             {
10069               flags=ParseGeometry(argument_list[0].string_reference,
10070                 &geometry_info);
10071               black_point=geometry_info.rho;
10072               white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10073                 black_point;
10074               if ((flags & PercentValue) != 0)
10075                 {
10076                   black_point*=(double) image->columns*image->rows/100.0;
10077                   white_point*=(double) image->columns*image->rows/100.0;
10078                 }
10079               white_point=(double) image->columns*image->rows-
10080                 white_point;
10081             }
10082           if (attribute_flag[1] != 0)
10083             black_point=argument_list[1].real_reference;
10084           if (attribute_flag[2] != 0)
10085             white_point=argument_list[2].real_reference;
10086           if (attribute_flag[4] != 0)
10087             channel=(ChannelType) argument_list[4].integer_reference;
10088           channel_mask=SetImageChannelMask(image,channel);
10089           (void) ContrastStretchImage(image,black_point,white_point,exception);
10090           (void) SetImageChannelMask(image,channel_mask);
10091           break;
10092         }
10093         case 96:  /* Sans0 */
10094         {
10095           break;
10096         }
10097         case 97:  /* Sans1 */
10098         {
10099           break;
10100         }
10101         case 98:  /* AdaptiveSharpen */
10102         {
10103           if (attribute_flag[0] != 0)
10104             {
10105               flags=ParseGeometry(argument_list[0].string_reference,
10106                 &geometry_info);
10107               if ((flags & SigmaValue) == 0)
10108                 geometry_info.sigma=1.0;
10109               if ((flags & XiValue) == 0)
10110                 geometry_info.xi=0.0;
10111             }
10112           if (attribute_flag[1] != 0)
10113             geometry_info.rho=argument_list[1].real_reference;
10114           if (attribute_flag[2] != 0)
10115             geometry_info.sigma=argument_list[2].real_reference;
10116           if (attribute_flag[3] != 0)
10117             geometry_info.xi=argument_list[3].real_reference;
10118           if (attribute_flag[4] != 0)
10119             channel=(ChannelType) argument_list[4].integer_reference;
10120           channel_mask=SetImageChannelMask(image,channel);
10121           image=AdaptiveSharpenImage(image,geometry_info.rho,
10122             geometry_info.sigma,exception);
10123           if (image != (Image *) NULL)
10124             (void) SetImageChannelMask(image,channel_mask);
10125           break;
10126         }
10127         case 99:  /* Transpose */
10128         {
10129           image=TransposeImage(image,exception);
10130           break;
10131         }
10132         case 100:  /* Tranverse */
10133         {
10134           image=TransverseImage(image,exception);
10135           break;
10136         }
10137         case 101:  /* AutoOrient */
10138         {
10139           image=AutoOrientImage(image,image->orientation,exception);
10140           break;
10141         }
10142         case 102:  /* AdaptiveBlur */
10143         {
10144           if (attribute_flag[0] != 0)
10145             {
10146               flags=ParseGeometry(argument_list[0].string_reference,
10147                 &geometry_info);
10148               if ((flags & SigmaValue) == 0)
10149                 geometry_info.sigma=1.0;
10150               if ((flags & XiValue) == 0)
10151                 geometry_info.xi=0.0;
10152             }
10153           if (attribute_flag[1] != 0)
10154             geometry_info.rho=argument_list[1].real_reference;
10155           if (attribute_flag[2] != 0)
10156             geometry_info.sigma=argument_list[2].real_reference;
10157           if (attribute_flag[3] != 0)
10158             channel=(ChannelType) argument_list[3].integer_reference;
10159           channel_mask=SetImageChannelMask(image,channel);
10160           image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10161             exception);
10162           if (image != (Image *) NULL)
10163             (void) SetImageChannelMask(image,channel_mask);
10164           break;
10165         }
10166         case 103:  /* Sketch */
10167         {
10168           if (attribute_flag[0] != 0)
10169             {
10170               flags=ParseGeometry(argument_list[0].string_reference,
10171                 &geometry_info);
10172               if ((flags & SigmaValue) == 0)
10173                 geometry_info.sigma=1.0;
10174               if ((flags & XiValue) == 0)
10175                 geometry_info.xi=1.0;
10176             }
10177           if (attribute_flag[1] != 0)
10178             geometry_info.rho=argument_list[1].real_reference;
10179           if (attribute_flag[2] != 0)
10180             geometry_info.sigma=argument_list[2].real_reference;
10181           if (attribute_flag[3] != 0)
10182             geometry_info.xi=argument_list[3].real_reference;
10183           image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10184             geometry_info.xi,exception);
10185           break;
10186         }
10187         case 104:  /* UniqueColors */
10188         {
10189           image=UniqueImageColors(image,exception);
10190           break;
10191         }
10192         case 105:  /* AdaptiveResize */
10193         {
10194           if (attribute_flag[0] != 0)
10195             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10196               &geometry,exception);
10197           if (attribute_flag[1] != 0)
10198             geometry.width=argument_list[1].integer_reference;
10199           if (attribute_flag[2] != 0)
10200             geometry.height=argument_list[2].integer_reference;
10201           if (attribute_flag[3] != 0)
10202             image->filter=(FilterTypes) argument_list[4].integer_reference;
10203           if (attribute_flag[4] != 0)
10204             SetImageArtifact(image,"filter:support",
10205               argument_list[4].string_reference);
10206           image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10207             exception);
10208           break;
10209         }
10210         case 106:  /* ClipMask */
10211         {
10212           Image
10213             *mask_image;
10214
10215           if (attribute_flag[0] == 0)
10216             {
10217               ThrowPerlException(exception,OptionError,"MaskImageRequired",
10218                 PackageName);
10219               goto PerlException;
10220             }
10221           mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10222             exception);
10223           (void) NegateImage(mask_image,MagickFalse,exception);
10224           (void) SetImageMask(image,mask_image,exception);
10225           mask_image=DestroyImage(mask_image);
10226           break;
10227         }
10228         case 107:  /* LinearStretch */
10229         {
10230            double
10231              black_point,
10232              white_point;
10233
10234            black_point=0.0;
10235            white_point=(double) image->columns*image->rows;
10236            if (attribute_flag[0] != 0)
10237              {
10238                flags=ParseGeometry(argument_list[0].string_reference,
10239                  &geometry_info);
10240                if ((flags & SigmaValue) != 0)
10241                   white_point=geometry_info.sigma;
10242                if ((flags & PercentValue) != 0)
10243                  {
10244                    black_point*=(double) image->columns*image->rows/100.0;
10245                    white_point*=(double) image->columns*image->rows/100.0;
10246                  }
10247                if ((flags & SigmaValue) == 0)
10248                  white_point=(double) image->columns*image->rows-black_point;
10249              }
10250           if (attribute_flag[1] != 0)
10251             black_point=argument_list[1].real_reference;
10252           if (attribute_flag[2] != 0)
10253             white_point=argument_list[2].real_reference;
10254           (void) LinearStretchImage(image,black_point,white_point,exception);
10255           break;
10256         }
10257         case 108:  /* ColorMatrix */
10258         {
10259           AV
10260             *av;
10261
10262           double
10263             *color_matrix;
10264
10265           KernelInfo
10266             *kernel_info;
10267
10268           size_t
10269             order;
10270
10271           if (attribute_flag[0] == 0)
10272             break;
10273           av=(AV *) argument_list[0].array_reference;
10274           order=(size_t) sqrt(av_len(av)+1);
10275           color_matrix=(double *) AcquireQuantumMemory(order,order*
10276             sizeof(*color_matrix));
10277           if (color_matrix == (double *) NULL)
10278             {
10279               ThrowPerlException(exception,ResourceLimitFatalError,
10280                 "MemoryAllocationFailed",PackageName);
10281               goto PerlException;
10282            }
10283           for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10284             color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10285           for ( ; j < (ssize_t) (order*order); j++)
10286             color_matrix[j]=0.0;
10287           kernel_info=AcquireKernelInfo((const char *) NULL);
10288           if (kernel_info == (KernelInfo *) NULL)
10289             break;
10290           kernel_info->width=order;
10291           kernel_info->height=order;
10292           kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10293             order*sizeof(*kernel_info->values));
10294           if (kernel_info->values != (MagickRealType *) NULL)
10295             {
10296               for (i=0; i < (ssize_t) (order*order); i++)
10297                 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10298               image=ColorMatrixImage(image,kernel_info,exception);
10299             }
10300           kernel_info=DestroyKernelInfo(kernel_info);
10301           color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10302           break;
10303         }
10304         case 109:  /* Mask */
10305         {
10306           Image
10307             *mask_image;
10308
10309           if (attribute_flag[0] == 0)
10310             {
10311               ThrowPerlException(exception,OptionError,"MaskImageRequired",
10312                 PackageName);
10313               goto PerlException;
10314             }
10315           mask_image=CloneImage(argument_list[0].image_reference,0,0,
10316             MagickTrue,exception);
10317           (void) NegateImage(mask_image,MagickFalse,exception);
10318           (void) SetImageMask(image,mask_image,exception);
10319           mask_image=DestroyImage(mask_image);
10320           break;
10321         }
10322         case 110:  /* Polaroid */
10323         {
10324           char
10325             *caption;
10326
10327           DrawInfo
10328             *draw_info;
10329
10330           double
10331             angle;
10332
10333           PixelInterpolateMethod
10334             method;
10335
10336           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10337             (DrawInfo *) NULL);
10338           caption=(char *) NULL;
10339           if (attribute_flag[0] != 0)
10340             caption=InterpretImageProperties(info ? info->image_info :
10341               (ImageInfo *) NULL,image,argument_list[0].string_reference,
10342               exception);
10343           angle=0.0;
10344           if (attribute_flag[1] != 0)
10345             angle=argument_list[1].real_reference;
10346           if (attribute_flag[2] != 0)
10347             (void) CloneString(&draw_info->font,
10348               argument_list[2].string_reference);
10349           if (attribute_flag[3] != 0)
10350             (void) QueryColorCompliance(argument_list[3].string_reference,
10351               AllCompliance,&draw_info->stroke,exception);
10352           if (attribute_flag[4] != 0)
10353             (void) QueryColorCompliance(argument_list[4].string_reference,
10354               AllCompliance,&draw_info->fill,exception);
10355           if (attribute_flag[5] != 0)
10356             draw_info->stroke_width=argument_list[5].real_reference;
10357           if (attribute_flag[6] != 0)
10358             draw_info->pointsize=argument_list[6].real_reference;
10359           if (attribute_flag[7] != 0)
10360             draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10361           if (attribute_flag[8] != 0)
10362             (void) QueryColorCompliance(argument_list[8].string_reference,
10363               AllCompliance,&image->background_color,exception);
10364           method=UndefinedInterpolatePixel;
10365           if (attribute_flag[9] != 0)
10366             method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10367           image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10368           draw_info=DestroyDrawInfo(draw_info);
10369           if (caption != (char *) NULL)
10370             caption=DestroyString(caption);
10371           break;
10372         }
10373         case 111:  /* FloodfillPaint */
10374         {
10375           DrawInfo
10376             *draw_info;
10377
10378           MagickBooleanType
10379             invert;
10380
10381           PixelInfo
10382             target;
10383
10384           draw_info=CloneDrawInfo(info ? info->image_info :
10385             (ImageInfo *) NULL,(DrawInfo *) NULL);
10386           if (attribute_flag[0] != 0)
10387             flags=ParsePageGeometry(image,argument_list[0].string_reference,
10388               &geometry,exception);
10389           if (attribute_flag[1] != 0)
10390             geometry.x=argument_list[1].integer_reference;
10391           if (attribute_flag[2] != 0)
10392             geometry.y=argument_list[2].integer_reference;
10393           if (attribute_flag[3] != 0)
10394             (void) QueryColorCompliance(argument_list[3].string_reference,
10395               AllCompliance,&draw_info->fill,exception);
10396           (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10397             geometry.x,geometry.y,&target,exception);
10398           if (attribute_flag[4] != 0)
10399             QueryColorCompliance(argument_list[4].string_reference,
10400               AllCompliance,&target,exception);
10401           if (attribute_flag[5] != 0)
10402             image->fuzz=StringToDoubleInterval(
10403               argument_list[5].string_reference,(double) QuantumRange+1.0);
10404           if (attribute_flag[6] != 0)
10405             channel=(ChannelType) argument_list[6].integer_reference;
10406           invert=MagickFalse;
10407           if (attribute_flag[7] != 0)
10408             invert=(MagickBooleanType) argument_list[7].integer_reference;
10409           channel_mask=SetImageChannelMask(image,channel);
10410           (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10411             geometry.y,invert,exception);
10412           (void) SetImageChannelMask(image,channel_mask);
10413           draw_info=DestroyDrawInfo(draw_info);
10414           break;
10415         }
10416         case 112:  /* Distort */
10417         {
10418           AV
10419             *av;
10420
10421           double
10422             *coordinates;
10423
10424           DistortImageMethod
10425             method;
10426
10427           size_t
10428             number_coordinates;
10429
10430           VirtualPixelMethod
10431             virtual_pixel;
10432
10433           if (attribute_flag[0] == 0)
10434             break;
10435           method=UndefinedDistortion;
10436           if (attribute_flag[1] != 0)
10437             method=(DistortImageMethod) argument_list[1].integer_reference;
10438           av=(AV *) argument_list[0].array_reference;
10439           number_coordinates=(size_t) av_len(av)+1;
10440           coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10441             sizeof(*coordinates));
10442           if (coordinates == (double *) NULL)
10443             {
10444               ThrowPerlException(exception,ResourceLimitFatalError,
10445                 "MemoryAllocationFailed",PackageName);
10446               goto PerlException;
10447             }
10448           for (j=0; j < (ssize_t) number_coordinates; j++)
10449             coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10450           virtual_pixel=UndefinedVirtualPixelMethod;
10451           if (attribute_flag[2] != 0)
10452             virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10453               argument_list[2].integer_reference,exception);
10454           image=DistortImage(image,method,number_coordinates,coordinates,
10455             argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10456             exception);
10457           if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10458             virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10459               exception);
10460           coordinates=(double *) RelinquishMagickMemory(coordinates);
10461           break;
10462         }
10463         case 113:  /* Clut */
10464         {
10465           PixelInterpolateMethod
10466             method;
10467
10468           if (attribute_flag[0] == 0)
10469             {
10470               ThrowPerlException(exception,OptionError,"ClutImageRequired",
10471                 PackageName);
10472               goto PerlException;
10473             }
10474           method=UndefinedInterpolatePixel;
10475           if (attribute_flag[1] != 0)
10476             method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10477           if (attribute_flag[2] != 0)
10478             channel=(ChannelType) argument_list[2].integer_reference;
10479           channel_mask=SetImageChannelMask(image,channel);
10480           (void) ClutImage(image,argument_list[0].image_reference,method,
10481             exception);
10482           (void) SetImageChannelMask(image,channel_mask);
10483           break;
10484         }
10485         case 114:  /* LiquidRescale */
10486         {
10487           if (attribute_flag[0] != 0)
10488             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10489               &geometry,exception);
10490           if (attribute_flag[1] != 0)
10491             geometry.width=argument_list[1].integer_reference;
10492           if (attribute_flag[2] != 0)
10493             geometry.height=argument_list[2].integer_reference;
10494           if (attribute_flag[3] == 0)
10495             argument_list[3].real_reference=1.0;
10496           if (attribute_flag[4] == 0)
10497             argument_list[4].real_reference=0.0;
10498           image=LiquidRescaleImage(image,geometry.width,geometry.height,
10499             argument_list[3].real_reference,argument_list[4].real_reference,
10500             exception);
10501           break;
10502         }
10503         case 115:  /* EncipherImage */
10504         {
10505           (void) EncipherImage(image,argument_list[0].string_reference,
10506             exception);
10507           break;
10508         }
10509         case 116:  /* DecipherImage */
10510         {
10511           (void) DecipherImage(image,argument_list[0].string_reference,
10512             exception);
10513           break;
10514         }
10515         case 117:  /* Deskew */
10516         {
10517           geometry_info.rho=QuantumRange/2.0;
10518           if (attribute_flag[0] != 0)
10519             flags=ParseGeometry(argument_list[0].string_reference,
10520               &geometry_info);
10521           if (attribute_flag[1] != 0)
10522             geometry_info.rho=StringToDoubleInterval(
10523               argument_list[1].string_reference,(double) QuantumRange+1.0);
10524           image=DeskewImage(image,geometry_info.rho,exception);
10525           break;
10526         }
10527         case 118:  /* Remap */
10528         {
10529           QuantizeInfo
10530             *quantize_info;
10531
10532           if (attribute_flag[0] == 0)
10533             {
10534               ThrowPerlException(exception,OptionError,"RemapImageRequired",
10535                 PackageName);
10536               goto PerlException;
10537             }
10538           quantize_info=AcquireQuantizeInfo(info->image_info);
10539           if (attribute_flag[1] != 0)
10540             quantize_info->dither_method=(DitherMethod)
10541               argument_list[1].integer_reference;
10542           (void) RemapImages(quantize_info,image,
10543             argument_list[0].image_reference,exception);
10544           quantize_info=DestroyQuantizeInfo(quantize_info);
10545           break;
10546         }
10547         case 119:  /* SparseColor */
10548         {
10549           AV
10550             *av;
10551
10552           double
10553             *coordinates;
10554
10555           SparseColorMethod
10556             method;
10557
10558           size_t
10559             number_coordinates;
10560
10561           VirtualPixelMethod
10562             virtual_pixel;
10563
10564           if (attribute_flag[0] == 0)
10565             break;
10566           method=UndefinedColorInterpolate;
10567           if (attribute_flag[1] != 0)
10568             method=(SparseColorMethod) argument_list[1].integer_reference;
10569           av=(AV *) argument_list[0].array_reference;
10570           number_coordinates=(size_t) av_len(av)+1;
10571           coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10572             sizeof(*coordinates));
10573           if (coordinates == (double *) NULL)
10574             {
10575               ThrowPerlException(exception,ResourceLimitFatalError,
10576                 "MemoryAllocationFailed",PackageName);
10577               goto PerlException;
10578             }
10579           for (j=0; j < (ssize_t) number_coordinates; j++)
10580             coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10581           virtual_pixel=UndefinedVirtualPixelMethod;
10582           if (attribute_flag[2] != 0)
10583             virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10584               argument_list[2].integer_reference,exception);
10585           if (attribute_flag[3] != 0)
10586             channel=(ChannelType) argument_list[3].integer_reference;
10587           channel_mask=SetImageChannelMask(image,channel);
10588           image=SparseColorImage(image,method,number_coordinates,coordinates,
10589             exception);
10590           if (image != (Image *) NULL)
10591             (void) SetImageChannelMask(image,channel_mask);
10592           if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10593             virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10594               exception);
10595           coordinates=(double *) RelinquishMagickMemory(coordinates);
10596           break;
10597         }
10598         case 120:  /* Function */
10599         {
10600           AV
10601             *av;
10602
10603           double
10604             *parameters;
10605
10606           MagickFunction
10607             function;
10608
10609           size_t
10610             number_parameters;
10611
10612           VirtualPixelMethod
10613             virtual_pixel;
10614
10615           if (attribute_flag[0] == 0)
10616             break;
10617           function=UndefinedFunction;
10618           if (attribute_flag[1] != 0)
10619             function=(MagickFunction) argument_list[1].integer_reference;
10620           av=(AV *) argument_list[0].array_reference;
10621           number_parameters=(size_t) av_len(av)+1;
10622           parameters=(double *) AcquireQuantumMemory(number_parameters,
10623             sizeof(*parameters));
10624           if (parameters == (double *) NULL)
10625             {
10626               ThrowPerlException(exception,ResourceLimitFatalError,
10627                 "MemoryAllocationFailed",PackageName);
10628               goto PerlException;
10629             }
10630           for (j=0; j < (ssize_t) number_parameters; j++)
10631             parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10632           virtual_pixel=UndefinedVirtualPixelMethod;
10633           if (attribute_flag[2] != 0)
10634             virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10635               argument_list[2].integer_reference,exception);
10636           (void) FunctionImage(image,function,number_parameters,parameters,
10637             exception);
10638           if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10639             virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10640               exception);
10641           parameters=(double *) RelinquishMagickMemory(parameters);
10642           break;
10643         }
10644         case 121:  /* SelectiveBlur */
10645         {
10646           if (attribute_flag[0] != 0)
10647             {
10648               flags=ParseGeometry(argument_list[0].string_reference,
10649                 &geometry_info);
10650               if ((flags & SigmaValue) == 0)
10651                 geometry_info.sigma=1.0;
10652               if ((flags & PercentValue) != 0)
10653                 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10654             }
10655           if (attribute_flag[1] != 0)
10656             geometry_info.rho=argument_list[1].real_reference;
10657           if (attribute_flag[2] != 0)
10658             geometry_info.sigma=argument_list[2].real_reference;
10659           if (attribute_flag[3] != 0)
10660             geometry_info.xi=argument_list[3].integer_reference;;
10661           if (attribute_flag[5] != 0)
10662             channel=(ChannelType) argument_list[5].integer_reference;
10663           channel_mask=SetImageChannelMask(image,channel);
10664           image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10665             geometry_info.xi,exception);
10666           if (image != (Image *) NULL)
10667             (void) SetImageChannelMask(image,channel_mask);
10668           break;
10669         }
10670         case 122:  /* HaldClut */
10671         {
10672           if (attribute_flag[0] == 0)
10673             {
10674               ThrowPerlException(exception,OptionError,"ClutImageRequired",
10675                 PackageName);
10676               goto PerlException;
10677             }
10678           if (attribute_flag[1] != 0)
10679             channel=(ChannelType) argument_list[1].integer_reference;
10680           channel_mask=SetImageChannelMask(image,channel);
10681           (void) HaldClutImage(image,argument_list[0].image_reference,
10682             exception);
10683           (void) SetImageChannelMask(image,channel_mask);
10684           break;
10685         }
10686         case 123:  /* BlueShift */
10687         {
10688           if (attribute_flag[0] != 0)
10689             (void) ParseGeometry(argument_list[0].string_reference,
10690               &geometry_info);
10691           image=BlueShiftImage(image,geometry_info.rho,exception);
10692           break;
10693         }
10694         case 124:  /* ForwardFourierTransformImage */
10695         {
10696           image=ForwardFourierTransformImage(image,
10697             argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10698             exception);
10699           break;
10700         }
10701         case 125:  /* InverseFourierTransformImage */
10702         {
10703           image=InverseFourierTransformImage(image,image->next,
10704             argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10705             exception);
10706           break;
10707         }
10708         case 126:  /* ColorDecisionList */
10709         {
10710           if (attribute_flag[0] == 0)
10711             argument_list[0].string_reference=(char *) NULL;
10712           (void) ColorDecisionListImage(image,
10713             argument_list[0].string_reference,exception);
10714           break;
10715         }
10716         case 127:  /* AutoGamma */
10717         {
10718           if (attribute_flag[0] != 0)
10719             channel=(ChannelType) argument_list[0].integer_reference;
10720           channel_mask=SetImageChannelMask(image,channel);
10721           (void) AutoGammaImage(image,exception);
10722           (void) SetImageChannelMask(image,channel_mask);
10723           break;
10724         }
10725         case 128:  /* AutoLevel */
10726         {
10727           if (attribute_flag[0] != 0)
10728             channel=(ChannelType) argument_list[0].integer_reference;
10729           channel_mask=SetImageChannelMask(image,channel);
10730           (void) AutoLevelImage(image,exception);
10731           (void) SetImageChannelMask(image,channel_mask);
10732           break;
10733         }
10734         case 129:  /* LevelColors */
10735         {
10736           PixelInfo
10737             black_point,
10738             white_point;
10739
10740           (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
10741             exception);
10742           (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
10743             exception);
10744           if (attribute_flag[1] != 0)
10745              (void) QueryColorCompliance(
10746                argument_list[1].string_reference,AllCompliance,&black_point,
10747                exception);
10748           if (attribute_flag[2] != 0)
10749              (void) QueryColorCompliance(
10750                argument_list[2].string_reference,AllCompliance,&white_point,
10751                exception);
10752           if (attribute_flag[3] != 0)
10753             channel=(ChannelType) argument_list[3].integer_reference;
10754           channel_mask=SetImageChannelMask(image,channel);
10755           (void) LevelImageColors(image,&black_point,&white_point,
10756             argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10757             exception);
10758           (void) SetImageChannelMask(image,channel_mask);
10759           break;
10760         }
10761         case 130:  /* Clamp */
10762         {
10763           if (attribute_flag[0] != 0)
10764             channel=(ChannelType) argument_list[0].integer_reference;
10765           channel_mask=SetImageChannelMask(image,channel);
10766           (void) ClampImage(image,exception);
10767           (void) SetImageChannelMask(image,channel_mask);
10768           break;
10769         }
10770         case 131:  /* BrightnessContrast */
10771         {
10772           double
10773             brightness,
10774             contrast;
10775
10776           brightness=0.0;
10777           contrast=0.0;
10778           if (attribute_flag[0] != 0)
10779             {
10780               flags=ParseGeometry(argument_list[0].string_reference,
10781                 &geometry_info);
10782               brightness=geometry_info.rho;
10783               if ((flags & SigmaValue) == 0)
10784                 contrast=geometry_info.sigma;
10785             }
10786           if (attribute_flag[1] != 0)
10787             brightness=argument_list[1].real_reference;
10788           if (attribute_flag[2] != 0)
10789             contrast=argument_list[2].real_reference;
10790           if (attribute_flag[4] != 0)
10791             channel=(ChannelType) argument_list[4].integer_reference;
10792           channel_mask=SetImageChannelMask(image,channel);
10793           (void) BrightnessContrastImage(image,brightness,contrast,exception);
10794           (void) SetImageChannelMask(image,channel_mask);
10795           break;
10796         }
10797         case 132:  /* Morphology */
10798         {
10799           KernelInfo
10800             *kernel;
10801
10802           MorphologyMethod
10803             method;
10804
10805           ssize_t
10806             iterations;
10807
10808           if (attribute_flag[0] == 0)
10809             break;
10810           kernel=AcquireKernelInfo(argument_list[0].string_reference);
10811           if (kernel == (KernelInfo *) NULL)
10812             break;
10813           if (attribute_flag[1] != 0)
10814             channel=(ChannelType) argument_list[1].integer_reference;
10815           method=UndefinedMorphology;
10816           if (attribute_flag[2] != 0)
10817             method=argument_list[2].integer_reference;
10818           iterations=1;
10819           if (attribute_flag[3] != 0)
10820             iterations=argument_list[3].integer_reference;
10821           channel_mask=SetImageChannelMask(image,channel);
10822           image=MorphologyImage(image,method,iterations,kernel,exception);
10823           if (image != (Image *) NULL)
10824             (void) SetImageChannelMask(image,channel_mask);
10825           kernel=DestroyKernelInfo(kernel);
10826           break;
10827         }
10828         case 133:  /* Mode */
10829         {
10830           if (attribute_flag[0] != 0)
10831             {
10832               flags=ParseGeometry(argument_list[0].string_reference,
10833                 &geometry_info);
10834               if ((flags & SigmaValue) == 0)
10835                 geometry_info.sigma=1.0;
10836             }
10837           if (attribute_flag[1] != 0)
10838             geometry_info.rho=argument_list[1].real_reference;
10839           if (attribute_flag[2] != 0)
10840             geometry_info.sigma=argument_list[2].real_reference;
10841           if (attribute_flag[3] != 0)
10842             channel=(ChannelType) argument_list[3].integer_reference;
10843           channel_mask=SetImageChannelMask(image,channel);
10844           image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
10845             (size_t) geometry_info.sigma,exception);
10846           if (image != (Image *) NULL)
10847             (void) SetImageChannelMask(image,channel_mask);
10848           break;
10849         }
10850         case 134:  /* Statistic */
10851         {
10852           StatisticType
10853             statistic;
10854
10855           statistic=UndefinedStatistic;
10856           if (attribute_flag[0] != 0)
10857             {
10858               flags=ParseGeometry(argument_list[0].string_reference,
10859                 &geometry_info);
10860               if ((flags & SigmaValue) == 0)
10861                 geometry_info.sigma=1.0;
10862             }
10863           if (attribute_flag[1] != 0)
10864             geometry_info.rho=argument_list[1].real_reference;
10865           if (attribute_flag[2] != 0)
10866             geometry_info.sigma=argument_list[2].real_reference;
10867           if (attribute_flag[3] != 0)
10868             channel=(ChannelType) argument_list[3].integer_reference;
10869           if (attribute_flag[4] != 0)
10870             statistic=(StatisticType) argument_list[4].integer_reference;
10871           channel_mask=SetImageChannelMask(image,channel);
10872           image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
10873             (size_t) geometry_info.sigma,exception);
10874           if (image != (Image *) NULL)
10875             (void) SetImageChannelMask(image,channel_mask);
10876           break;
10877         }
10878         case 135:  /* Perceptible */
10879         {
10880           double
10881             epsilon;
10882
10883           epsilon=MagickEpsilon;
10884           if (attribute_flag[0] != 0)
10885             epsilon=argument_list[0].real_reference;
10886           if (attribute_flag[1] != 0)
10887             channel=(ChannelType) argument_list[1].integer_reference;
10888           channel_mask=SetImageChannelMask(image,channel);
10889           (void) PerceptibleImage(image,epsilon,exception);
10890           (void) SetImageChannelMask(image,channel_mask);
10891           break;
10892         }
10893         case 136:  /* Poly */
10894         {
10895           AV
10896             *av;
10897
10898           double
10899             *terms;
10900
10901           size_t
10902             number_terms;
10903
10904           if (attribute_flag[0] == 0)
10905             break;
10906           if (attribute_flag[1] != 0)
10907             channel=(ChannelType) argument_list[1].integer_reference;
10908           av=(AV *) argument_list[0].array_reference;
10909           number_terms=(size_t) av_len(av);
10910           terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
10911           if (terms == (double *) NULL)
10912             {
10913               ThrowPerlException(exception,ResourceLimitFatalError,
10914                 "MemoryAllocationFailed",PackageName);
10915               goto PerlException;
10916             }
10917           for (j=0; j < av_len(av); j++)
10918             terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
10919           image=PolynomialImage(image,number_terms >> 1,terms,exception);
10920           terms=(double *) RelinquishMagickMemory(terms);
10921           break;
10922         }
10923       }
10924       if (next != (Image *) NULL)
10925         (void) CatchImageException(next);
10926       if (region_image != (Image *) NULL)
10927         {
10928           /*
10929             Composite region.
10930           */ 
10931           status=CompositeImage(region_image,image,CopyCompositeOp,MagickTrue,
10932             region_info.x,region_info.y,exception);
10933           (void) status;
10934           (void) CatchImageException(region_image);
10935           image=DestroyImage(image);
10936           image=region_image;
10937         }
10938       if (image != (Image *) NULL)
10939         {
10940           number_images++;
10941           if (next && (next != image))
10942             {
10943               image->next=next->next;
10944               if (image->next != (Image *) NULL)
10945                 image->next->previous=image;
10946               DeleteImageFromRegistry(*pv,next);
10947             }
10948           sv_setiv(*pv,PTR2IV(image));
10949           next=image;
10950         }
10951       if (*pv)
10952         pv++;
10953     }
10954
10955   PerlException:
10956     if (reference_vector)
10957       reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
10958     InheritPerlException(exception,perl_exception);
10959     exception=DestroyExceptionInfo(exception);
10960     sv_setiv(perl_exception,(IV) number_images);
10961     SvPOK_on(perl_exception);
10962     ST(0)=sv_2mortal(perl_exception);
10963     XSRETURN(1);
10964   }
10965 \f
10966 #
10967 ###############################################################################
10968 #                                                                             #
10969 #                                                                             #
10970 #                                                                             #
10971 #   M o n t a g e                                                             #
10972 #                                                                             #
10973 #                                                                             #
10974 #                                                                             #
10975 ###############################################################################
10976 #
10977 #
10978 void
10979 Montage(ref,...)
10980   Image::Magick::Q16HDRI ref=NO_INIT
10981   ALIAS:
10982     MontageImage  = 1
10983     montage       = 2
10984     montageimage  = 3
10985   PPCODE:
10986   {
10987     AV
10988       *av;
10989
10990     char
10991       *attribute;
10992
10993     ExceptionInfo
10994       *exception;
10995
10996     HV
10997       *hv;
10998
10999     Image
11000       *image,
11001       *next;
11002
11003     PixelInfo
11004       transparent_color;
11005
11006     MontageInfo
11007       *montage_info;
11008
11009     register ssize_t
11010       i;
11011
11012     ssize_t
11013       sp;
11014
11015     struct PackageInfo
11016       *info;
11017
11018     SV
11019       *av_reference,
11020       *perl_exception,
11021       *reference,
11022       *rv,
11023       *sv;
11024
11025     PERL_UNUSED_VAR(ref);
11026     PERL_UNUSED_VAR(ix);
11027     exception=AcquireExceptionInfo();
11028     perl_exception=newSVpv("",0);
11029     sv=NULL;
11030     attribute=NULL;
11031     if (sv_isobject(ST(0)) == 0)
11032       {
11033         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11034           PackageName);
11035         goto PerlException;
11036       }
11037     reference=SvRV(ST(0));
11038     hv=SvSTASH(reference);
11039     av=newAV();
11040     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11041     SvREFCNT_dec(av);
11042     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11043     if (image == (Image *) NULL)
11044       {
11045         ThrowPerlException(exception,OptionError,"NoImagesDefined",
11046           PackageName);
11047         goto PerlException;
11048       }
11049     /*
11050       Get options.
11051     */
11052     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11053     montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11054     (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11055       exception);
11056     for (i=2; i < items; i+=2)
11057     {
11058       attribute=(char *) SvPV(ST(i-1),na);
11059       switch (*attribute)
11060       {
11061         case 'B':
11062         case 'b':
11063         {
11064           if (LocaleCompare(attribute,"background") == 0)
11065             {
11066               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11067                 &montage_info->background_color,exception);
11068               for (next=image; next; next=next->next)
11069                 next->background_color=montage_info->background_color;
11070               break;
11071             }
11072           if (LocaleCompare(attribute,"border") == 0)
11073             {
11074               montage_info->border_width=SvIV(ST(i));
11075               break;
11076             }
11077           if (LocaleCompare(attribute,"bordercolor") == 0)
11078             {
11079               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11080                 &montage_info->border_color,exception);
11081               for (next=image; next; next=next->next)
11082                 next->border_color=montage_info->border_color;
11083               break;
11084             }
11085           if (LocaleCompare(attribute,"borderwidth") == 0)
11086             {
11087               montage_info->border_width=SvIV(ST(i));
11088               break;
11089             }
11090           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11091             attribute);
11092           break;
11093         }
11094         case 'C':
11095         case 'c':
11096         {
11097           if (LocaleCompare(attribute,"compose") == 0)
11098             {
11099               sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11100                 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11101               if (sp < 0)
11102                 {
11103                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
11104                     SvPV(ST(i),na));
11105                   break;
11106                 }
11107               for (next=image; next; next=next->next)
11108                 next->compose=(CompositeOperator) sp;
11109               break;
11110             }
11111           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11112             attribute);
11113           break;
11114         }
11115         case 'F':
11116         case 'f':
11117         {
11118           if (LocaleCompare(attribute,"fill") == 0)
11119             {
11120               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11121                 &montage_info->fill,exception);
11122               break;
11123             }
11124           if (LocaleCompare(attribute,"font") == 0)
11125             {
11126               (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11127               break;
11128             }
11129           if (LocaleCompare(attribute,"frame") == 0)
11130             {
11131               char
11132                 *p;
11133
11134               p=SvPV(ST(i),na);
11135               if (IsGeometry(p) == MagickFalse)
11136                 {
11137                   ThrowPerlException(exception,OptionError,"MissingGeometry",
11138                     p);
11139                   break;
11140                 }
11141               (void) CloneString(&montage_info->frame,p);
11142               if (*p == '\0')
11143                 montage_info->frame=(char *) NULL;
11144               break;
11145             }
11146           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11147             attribute);
11148           break;
11149         }
11150         case 'G':
11151         case 'g':
11152         {
11153           if (LocaleCompare(attribute,"geometry") == 0)
11154             {
11155               char
11156                 *p;
11157
11158               p=SvPV(ST(i),na);
11159               if (IsGeometry(p) == MagickFalse)
11160                 {
11161                   ThrowPerlException(exception,OptionError,"MissingGeometry",
11162                     p);
11163                   break;
11164                 }
11165              (void) CloneString(&montage_info->geometry,p);
11166              if (*p == '\0')
11167                montage_info->geometry=(char *) NULL;
11168              break;
11169            }
11170          if (LocaleCompare(attribute,"gravity") == 0)
11171            {
11172              ssize_t
11173                in;
11174
11175              in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11176                MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11177              if (in < 0)
11178                {
11179                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
11180                    SvPV(ST(i),na));
11181                  return;
11182                }
11183              montage_info->gravity=(GravityType) in;
11184              for (next=image; next; next=next->next)
11185                next->gravity=(GravityType) in;
11186              break;
11187            }
11188           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11189             attribute);
11190           break;
11191         }
11192         case 'L':
11193         case 'l':
11194         {
11195           if (LocaleCompare(attribute,"label") == 0)
11196             {
11197               for (next=image; next; next=next->next)
11198                 (void) SetImageProperty(next,"label",InterpretImageProperties(
11199                   info ? info->image_info : (ImageInfo *) NULL,next,
11200                   SvPV(ST(i),na),exception),exception);
11201               break;
11202             }
11203           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11204             attribute);
11205           break;
11206         }
11207         case 'M':
11208         case 'm':
11209         {
11210           if (LocaleCompare(attribute,"mattecolor") == 0)
11211             {
11212               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11213                 &montage_info->matte_color,exception);
11214               for (next=image; next; next=next->next)
11215                 next->matte_color=montage_info->matte_color;
11216               break;
11217             }
11218           if (LocaleCompare(attribute,"mode") == 0)
11219             {
11220               ssize_t
11221                 in;
11222
11223               in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11224                 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11225               switch (in)
11226               {
11227                 default:
11228                 {
11229                   ThrowPerlException(exception,OptionError,
11230                     "UnrecognizedModeType",SvPV(ST(i),na));
11231                   break;
11232                 }
11233                 case FrameMode:
11234                 {
11235                   (void) CloneString(&montage_info->frame,"15x15+3+3");
11236                   montage_info->shadow=MagickTrue;
11237                   break;
11238                 }
11239                 case UnframeMode:
11240                 {
11241                   montage_info->frame=(char *) NULL;
11242                   montage_info->shadow=MagickFalse;
11243                   montage_info->border_width=0;
11244                   break;
11245                 }
11246                 case ConcatenateMode:
11247                 {
11248                   montage_info->frame=(char *) NULL;
11249                   montage_info->shadow=MagickFalse;
11250                   (void) CloneString(&montage_info->geometry,"+0+0");
11251                   montage_info->border_width=0;
11252                 }
11253               }
11254               break;
11255             }
11256           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11257             attribute);
11258           break;
11259         }
11260         case 'P':
11261         case 'p':
11262         {
11263           if (LocaleCompare(attribute,"pointsize") == 0)
11264             {
11265               montage_info->pointsize=SvIV(ST(i));
11266               break;
11267             }
11268           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11269             attribute);
11270           break;
11271         }
11272         case 'S':
11273         case 's':
11274         {
11275           if (LocaleCompare(attribute,"shadow") == 0)
11276             {
11277               sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11278                 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11279               if (sp < 0)
11280                 {
11281                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
11282                     SvPV(ST(i),na));
11283                   break;
11284                 }
11285              montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11286              break;
11287             }
11288           if (LocaleCompare(attribute,"stroke") == 0)
11289             {
11290               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11291                 &montage_info->stroke,exception);
11292               break;
11293             }
11294           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11295             attribute);
11296           break;
11297         }
11298         case 'T':
11299         case 't':
11300         {
11301           if (LocaleCompare(attribute,"texture") == 0)
11302             {
11303               (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11304               break;
11305             }
11306           if (LocaleCompare(attribute,"tile") == 0)
11307             {
11308               char *p=SvPV(ST(i),na);
11309               if (IsGeometry(p) == MagickFalse)
11310                 {
11311                   ThrowPerlException(exception,OptionError,"MissingGeometry",
11312                     p);
11313                   break;
11314                 }
11315               (void) CloneString(&montage_info->tile,p);
11316               if (*p == '\0')
11317                 montage_info->tile=(char *) NULL;
11318               break;
11319             }
11320           if (LocaleCompare(attribute,"title") == 0)
11321             {
11322               (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11323               break;
11324             }
11325           if (LocaleCompare(attribute,"transparent") == 0)
11326             {
11327               PixelInfo
11328                 transparent_color;
11329
11330               QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11331                 &transparent_color,exception);
11332               for (next=image; next; next=next->next)
11333                 (void) TransparentPaintImage(next,&transparent_color,
11334                   TransparentAlpha,MagickFalse,exception);
11335               break;
11336             }
11337           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11338             attribute);
11339           break;
11340         }
11341         default:
11342         {
11343           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11344             attribute);
11345           break;
11346         }
11347       }
11348     }
11349     image=MontageImageList(info->image_info,montage_info,image,exception);
11350     montage_info=DestroyMontageInfo(montage_info);
11351     if (image == (Image *) NULL)
11352       goto PerlException;
11353     if (transparent_color.alpha != TransparentAlpha)
11354       for (next=image; next; next=next->next)
11355         (void) TransparentPaintImage(next,&transparent_color,
11356           TransparentAlpha,MagickFalse,exception);
11357     for (  ; image; image=image->next)
11358     {
11359       AddImageToRegistry(sv,image);
11360       rv=newRV(sv);
11361       av_push(av,sv_bless(rv,hv));
11362       SvREFCNT_dec(sv);
11363     }
11364     exception=DestroyExceptionInfo(exception);
11365     ST(0)=av_reference;
11366     SvREFCNT_dec(perl_exception);
11367     XSRETURN(1);
11368
11369   PerlException:
11370     InheritPerlException(exception,perl_exception);
11371     exception=DestroyExceptionInfo(exception);
11372     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11373     SvPOK_on(perl_exception);
11374     ST(0)=sv_2mortal(perl_exception);
11375     XSRETURN(1);
11376   }
11377 \f
11378 #
11379 ###############################################################################
11380 #                                                                             #
11381 #                                                                             #
11382 #                                                                             #
11383 #   M o r p h                                                                 #
11384 #                                                                             #
11385 #                                                                             #
11386 #                                                                             #
11387 ###############################################################################
11388 #
11389 #
11390 void
11391 Morph(ref,...)
11392   Image::Magick::Q16HDRI ref=NO_INIT
11393   ALIAS:
11394     MorphImage  = 1
11395     morph       = 2
11396     morphimage  = 3
11397   PPCODE:
11398   {
11399     AV
11400       *av;
11401
11402     char
11403       *attribute;
11404
11405     ExceptionInfo
11406       *exception;
11407
11408     HV
11409       *hv;
11410
11411     Image
11412       *image;
11413
11414     register ssize_t
11415       i;
11416
11417     ssize_t
11418       number_frames;
11419
11420     struct PackageInfo
11421       *info;
11422
11423     SV
11424       *av_reference,
11425       *perl_exception,
11426       *reference,
11427       *rv,
11428       *sv;
11429
11430     PERL_UNUSED_VAR(ref);
11431     PERL_UNUSED_VAR(ix);
11432     exception=AcquireExceptionInfo();
11433     perl_exception=newSVpv("",0);
11434     sv=NULL;
11435     av=NULL;
11436     attribute=NULL;
11437     if (sv_isobject(ST(0)) == 0)
11438       {
11439         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11440           PackageName);
11441         goto PerlException;
11442       }
11443     reference=SvRV(ST(0));
11444     hv=SvSTASH(reference);
11445     av=newAV();
11446     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11447     SvREFCNT_dec(av);
11448     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11449     if (image == (Image *) NULL)
11450       {
11451         ThrowPerlException(exception,OptionError,"NoImagesDefined",
11452           PackageName);
11453         goto PerlException;
11454       }
11455     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11456     /*
11457       Get attribute.
11458     */
11459     number_frames=30;
11460     for (i=2; i < items; i+=2)
11461     {
11462       attribute=(char *) SvPV(ST(i-1),na);
11463       switch (*attribute)
11464       {
11465         case 'F':
11466         case 'f':
11467         {
11468           if (LocaleCompare(attribute,"frames") == 0)
11469             {
11470               number_frames=SvIV(ST(i));
11471               break;
11472             }
11473           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11474             attribute);
11475           break;
11476         }
11477         default:
11478         {
11479           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11480             attribute);
11481           break;
11482         }
11483       }
11484     }
11485     image=MorphImages(image,number_frames,exception);
11486     if (image == (Image *) NULL)
11487       goto PerlException;
11488     for ( ; image; image=image->next)
11489     {
11490       AddImageToRegistry(sv,image);
11491       rv=newRV(sv);
11492       av_push(av,sv_bless(rv,hv));
11493       SvREFCNT_dec(sv);
11494     }
11495     exception=DestroyExceptionInfo(exception);
11496     ST(0)=av_reference;
11497     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
11498     XSRETURN(1);
11499
11500   PerlException:
11501     InheritPerlException(exception,perl_exception);
11502     exception=DestroyExceptionInfo(exception);
11503     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11504     SvPOK_on(perl_exception);
11505     ST(0)=sv_2mortal(perl_exception);
11506     XSRETURN(1);
11507   }
11508 \f
11509 #
11510 ###############################################################################
11511 #                                                                             #
11512 #                                                                             #
11513 #                                                                             #
11514 #   M o s a i c                                                               #
11515 #                                                                             #
11516 #                                                                             #
11517 #                                                                             #
11518 ###############################################################################
11519 #
11520 #
11521 void
11522 Mosaic(ref)
11523   Image::Magick::Q16HDRI ref=NO_INIT
11524   ALIAS:
11525     MosaicImage   = 1
11526     mosaic        = 2
11527     mosaicimage   = 3
11528   PPCODE:
11529   {
11530     AV
11531       *av;
11532
11533     ExceptionInfo
11534       *exception;
11535
11536     HV
11537       *hv;
11538
11539     Image
11540       *image;
11541
11542     struct PackageInfo
11543       *info;
11544
11545     SV
11546       *perl_exception,
11547       *reference,
11548       *rv,
11549       *sv;
11550
11551     PERL_UNUSED_VAR(ref);
11552     PERL_UNUSED_VAR(ix);
11553     exception=AcquireExceptionInfo();
11554     perl_exception=newSVpv("",0);
11555     sv=NULL;
11556     if (sv_isobject(ST(0)) == 0)
11557       {
11558         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11559           PackageName);
11560         goto PerlException;
11561       }
11562     reference=SvRV(ST(0));
11563     hv=SvSTASH(reference);
11564     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11565     if (image == (Image *) NULL)
11566       {
11567         ThrowPerlException(exception,OptionError,"NoImagesDefined",
11568           PackageName);
11569         goto PerlException;
11570       }
11571     image=MergeImageLayers(image,MosaicLayer,exception);
11572     /*
11573       Create blessed Perl array for the returned image.
11574     */
11575     av=newAV();
11576     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11577     SvREFCNT_dec(av);
11578     AddImageToRegistry(sv,image);
11579     rv=newRV(sv);
11580     av_push(av,sv_bless(rv,hv));
11581     SvREFCNT_dec(sv);
11582     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11583     (void) CopyMagickString(info->image_info->filename,image->filename,
11584       MaxTextExtent);
11585     SetImageInfo(info->image_info,0,exception);
11586     exception=DestroyExceptionInfo(exception);
11587     SvREFCNT_dec(perl_exception);
11588     XSRETURN(1);
11589
11590   PerlException:
11591     InheritPerlException(exception,perl_exception);
11592     exception=DestroyExceptionInfo(exception);
11593     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11594     SvPOK_on(perl_exception);  /* return messages in string context */
11595     ST(0)=sv_2mortal(perl_exception);
11596     XSRETURN(1);
11597   }
11598 \f
11599 #
11600 ###############################################################################
11601 #                                                                             #
11602 #                                                                             #
11603 #                                                                             #
11604 #   P i n g                                                                   #
11605 #                                                                             #
11606 #                                                                             #
11607 #                                                                             #
11608 ###############################################################################
11609 #
11610 #
11611 void
11612 Ping(ref,...)
11613   Image::Magick::Q16HDRI ref=NO_INIT
11614   ALIAS:
11615     PingImage  = 1
11616     ping       = 2
11617     pingimage  = 3
11618   PPCODE:
11619   {
11620     AV
11621       *av;
11622
11623     char
11624       **keep,
11625       **list;
11626
11627     ExceptionInfo
11628       *exception;
11629
11630     Image
11631       *image,
11632       *next;
11633
11634     int
11635       n;
11636
11637     MagickBooleanType
11638       status;
11639
11640     register char
11641       **p;
11642
11643     register ssize_t
11644       i;
11645
11646     ssize_t
11647       ac;
11648
11649     STRLEN
11650       *length;
11651
11652     struct PackageInfo
11653       *info,
11654       *package_info;
11655
11656     SV
11657       *perl_exception,
11658       *reference;
11659
11660     size_t
11661       count;
11662
11663     PERL_UNUSED_VAR(ref);
11664     PERL_UNUSED_VAR(ix);
11665     exception=AcquireExceptionInfo();
11666     perl_exception=newSVpv("",0);
11667     package_info=(struct PackageInfo *) NULL;
11668     ac=(items < 2) ? 1 : items-1;
11669     list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
11670     keep=list;
11671     length=(STRLEN *) NULL;
11672     if (list == (char **) NULL)
11673       {
11674         ThrowPerlException(exception,ResourceLimitError,
11675           "MemoryAllocationFailed",PackageName);
11676         goto PerlException;
11677       }
11678     keep=list;
11679     length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
11680     if (length == (STRLEN *) NULL)
11681       {
11682         ThrowPerlException(exception,ResourceLimitError,
11683           "MemoryAllocationFailed",PackageName);
11684         goto PerlException;
11685       }
11686     if (sv_isobject(ST(0)) == 0)
11687       {
11688         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11689           PackageName);
11690         goto PerlException;
11691       }
11692     reference=SvRV(ST(0));
11693     if (SvTYPE(reference) != SVt_PVAV)
11694       {
11695         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11696           PackageName);
11697         goto PerlException;
11698       }
11699     av=(AV *) reference;
11700     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
11701       exception);
11702     package_info=ClonePackageInfo(info,exception);
11703     n=1;
11704     if (items <= 1)
11705       *list=(char *) (*package_info->image_info->filename ?
11706         package_info->image_info->filename : "XC:black");
11707     else
11708       for (n=0, i=0; i < ac; i++)
11709       {
11710         list[n]=(char *) SvPV(ST(i+1),length[n]);
11711         if ((items >= 3) && strEQcase(list[n],"blob"))
11712           {
11713             void
11714               *blob;
11715
11716             i++;
11717             blob=(void *) (SvPV(ST(i+1),length[n]));
11718             SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
11719           }
11720         if ((items >= 3) && strEQcase(list[n],"filename"))
11721           continue;
11722         if ((items >= 3) && strEQcase(list[n],"file"))
11723           {
11724             FILE
11725               *file;
11726
11727             PerlIO
11728               *io_info;
11729
11730             i++;
11731             io_info=IoIFP(sv_2io(ST(i+1)));
11732             if (io_info == (PerlIO *) NULL)
11733               {
11734                 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
11735                   PackageName);
11736                 continue;
11737               }
11738             file=PerlIO_findFILE(io_info);
11739             if (file == (FILE *) NULL)
11740               {
11741                 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
11742                   PackageName);
11743                 continue;
11744               }
11745             SetImageInfoFile(package_info->image_info,file);
11746           }
11747         if ((items >= 3) && strEQcase(list[n],"magick"))
11748           continue;
11749         n++;
11750       }
11751     list[n]=(char *) NULL;
11752     keep=list;
11753     status=ExpandFilenames(&n,&list);
11754     if (status == MagickFalse)
11755       {
11756         ThrowPerlException(exception,ResourceLimitError,
11757           "MemoryAllocationFailed",PackageName);
11758         goto PerlException;
11759       }
11760     count=0;
11761     for (i=0; i < n; i++)
11762     {
11763       (void) CopyMagickString(package_info->image_info->filename,list[i],
11764         MaxTextExtent);
11765       image=PingImage(package_info->image_info,exception);
11766       if (image == (Image *) NULL)
11767         break;
11768       if ((package_info->image_info->file != (FILE *) NULL) ||
11769           (package_info->image_info->blob != (void *) NULL))
11770         DisassociateImageStream(image);
11771       count+=GetImageListLength(image);
11772       EXTEND(sp,4*count);
11773       for (next=image; next; next=next->next)
11774       {
11775         PUSHs(sv_2mortal(newSViv(next->columns)));
11776         PUSHs(sv_2mortal(newSViv(next->rows)));
11777         PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
11778         PUSHs(sv_2mortal(newSVpv(next->magick,0)));
11779       }
11780       image=DestroyImageList(image);
11781     }
11782     /*
11783       Free resources.
11784     */
11785     for (i=0; i < n; i++)
11786       if (list[i] != (char *) NULL)
11787         for (p=keep; list[i] != *p++; )
11788           if (*p == NULL)
11789             {
11790               list[i]=(char *) RelinquishMagickMemory(list[i]);
11791               break;
11792             }
11793
11794   PerlException:
11795     if (package_info != (struct PackageInfo *) NULL)
11796       DestroyPackageInfo(package_info);
11797     if (list && (list != keep))
11798       list=(char **) RelinquishMagickMemory(list);
11799     if (keep)
11800       keep=(char **) RelinquishMagickMemory(keep);
11801     if (length)
11802       length=(STRLEN *) RelinquishMagickMemory(length);
11803     InheritPerlException(exception,perl_exception);
11804     exception=DestroyExceptionInfo(exception);
11805     SvREFCNT_dec(perl_exception);  /* throw away all errors */
11806   }
11807 \f
11808 #
11809 ###############################################################################
11810 #                                                                             #
11811 #                                                                             #
11812 #                                                                             #
11813 #   P r e v i e w                                                             #
11814 #                                                                             #
11815 #                                                                             #
11816 #                                                                             #
11817 ###############################################################################
11818 #
11819 #
11820 void
11821 Preview(ref,...)
11822   Image::Magick::Q16HDRI ref=NO_INIT
11823   ALIAS:
11824     PreviewImage = 1
11825     preview      = 2
11826     previewimage = 3
11827   PPCODE:
11828   {
11829     AV
11830       *av;
11831
11832     ExceptionInfo
11833       *exception;
11834
11835     HV
11836       *hv;
11837
11838     Image
11839       *image,
11840       *preview_image;
11841
11842     PreviewType
11843       preview_type;
11844
11845     struct PackageInfo
11846       *info;
11847
11848     SV
11849       *av_reference,
11850       *perl_exception,
11851       *reference,
11852       *rv,
11853       *sv;
11854
11855     PERL_UNUSED_VAR(ref);
11856     PERL_UNUSED_VAR(ix);
11857     exception=AcquireExceptionInfo();
11858     perl_exception=newSVpv("",0);
11859     sv=NULL;
11860     av=NULL;
11861     if (sv_isobject(ST(0)) == 0)
11862       {
11863         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11864           PackageName);
11865         goto PerlException;
11866       }
11867     reference=SvRV(ST(0));
11868     hv=SvSTASH(reference);
11869     av=newAV();
11870     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11871     SvREFCNT_dec(av);
11872     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11873     if (image == (Image *) NULL)
11874       {
11875         ThrowPerlException(exception,OptionError,"NoImagesDefined",
11876           PackageName);
11877         goto PerlException;
11878       }
11879     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11880     preview_type=GammaPreview;
11881     if (items > 1)
11882       preview_type=(PreviewType)
11883         ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
11884     for ( ; image; image=image->next)
11885     {
11886       preview_image=PreviewImage(image,preview_type,exception);
11887       if (preview_image == (Image *) NULL)
11888         goto PerlException;
11889       AddImageToRegistry(sv,preview_image);
11890       rv=newRV(sv);
11891       av_push(av,sv_bless(rv,hv));
11892       SvREFCNT_dec(sv);
11893     }
11894     exception=DestroyExceptionInfo(exception);
11895     ST(0)=av_reference;
11896     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
11897     XSRETURN(1);
11898
11899   PerlException:
11900     InheritPerlException(exception,perl_exception);
11901     exception=DestroyExceptionInfo(exception);
11902     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11903     SvPOK_on(perl_exception);
11904     ST(0)=sv_2mortal(perl_exception);
11905     XSRETURN(1);
11906   }
11907 \f
11908 #
11909 ###############################################################################
11910 #                                                                             #
11911 #                                                                             #
11912 #                                                                             #
11913 #   Q u e r y C o l o r                                                       #
11914 #                                                                             #
11915 #                                                                             #
11916 #                                                                             #
11917 ###############################################################################
11918 #
11919 #
11920 void
11921 QueryColor(ref,...)
11922   Image::Magick::Q16HDRI ref=NO_INIT
11923   ALIAS:
11924     querycolor = 1
11925   PPCODE:
11926   {
11927     char
11928       *name;
11929
11930     ExceptionInfo
11931       *exception;
11932
11933     PixelInfo
11934       color;
11935
11936     register ssize_t
11937       i;
11938
11939     SV
11940       *perl_exception;
11941
11942     PERL_UNUSED_VAR(ref);
11943     PERL_UNUSED_VAR(ix);
11944     exception=AcquireExceptionInfo();
11945     perl_exception=newSVpv("",0);
11946     if (items == 1)
11947       {
11948         const ColorInfo
11949           **colorlist;
11950
11951         size_t
11952           colors;
11953
11954         colorlist=GetColorInfoList("*",&colors,exception);
11955         EXTEND(sp,colors);
11956         for (i=0; i < (ssize_t) colors; i++)
11957         {
11958           PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
11959         }
11960         colorlist=(const ColorInfo **)
11961           RelinquishMagickMemory((ColorInfo **) colorlist);
11962         goto PerlException;
11963       }
11964     EXTEND(sp,5*items);
11965     for (i=1; i < items; i++)
11966     {
11967       name=(char *) SvPV(ST(i),na);
11968       if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
11969         {
11970           PUSHs(&sv_undef);
11971           continue;
11972         }
11973       PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
11974       PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
11975       PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
11976       if (color.colorspace == CMYKColorspace)
11977         PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
11978       if (color.alpha_trait == BlendPixelTrait)
11979         PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
11980     }
11981
11982   PerlException:
11983     InheritPerlException(exception,perl_exception);
11984     exception=DestroyExceptionInfo(exception);
11985     SvREFCNT_dec(perl_exception);
11986   }
11987 \f
11988 #
11989 ###############################################################################
11990 #                                                                             #
11991 #                                                                             #
11992 #                                                                             #
11993 #   Q u e r y C o l o r N a m e                                               #
11994 #                                                                             #
11995 #                                                                             #
11996 #                                                                             #
11997 ###############################################################################
11998 #
11999 #
12000 void
12001 QueryColorname(ref,...)
12002   Image::Magick::Q16HDRI ref=NO_INIT
12003   ALIAS:
12004     querycolorname = 1
12005   PPCODE:
12006   {
12007     AV
12008       *av;
12009
12010     char
12011       message[MaxTextExtent];
12012
12013     ExceptionInfo
12014       *exception;
12015
12016     Image
12017       *image;
12018
12019     PixelInfo
12020       target_color;
12021
12022     register ssize_t
12023       i;
12024
12025     struct PackageInfo
12026       *info;
12027
12028     SV
12029       *perl_exception,
12030       *reference;  /* reference is the SV* of ref=SvIV(reference) */
12031
12032     PERL_UNUSED_VAR(ref);
12033     PERL_UNUSED_VAR(ix);
12034     exception=AcquireExceptionInfo();
12035     perl_exception=newSVpv("",0);
12036     reference=SvRV(ST(0));
12037     av=(AV *) reference;
12038     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12039       exception);
12040     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12041     if (image == (Image *) NULL)
12042       {
12043         ThrowPerlException(exception,OptionError,"NoImagesDefined",
12044           PackageName);
12045         goto PerlException;
12046       }
12047     EXTEND(sp,items);
12048     for (i=1; i < items; i++)
12049     {
12050       (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12051         exception);
12052       (void) QueryColorname(image,&target_color,SVGCompliance,message,
12053         exception);
12054       PUSHs(sv_2mortal(newSVpv(message,0)));
12055     }
12056
12057   PerlException:
12058     InheritPerlException(exception,perl_exception);
12059     exception=DestroyExceptionInfo(exception);
12060     SvREFCNT_dec(perl_exception);
12061   }
12062 \f
12063 #
12064 ###############################################################################
12065 #                                                                             #
12066 #                                                                             #
12067 #                                                                             #
12068 #   Q u e r y F o n t                                                         #
12069 #                                                                             #
12070 #                                                                             #
12071 #                                                                             #
12072 ###############################################################################
12073 #
12074 #
12075 void
12076 QueryFont(ref,...)
12077   Image::Magick::Q16HDRI ref=NO_INIT
12078   ALIAS:
12079     queryfont = 1
12080   PPCODE:
12081   {
12082     char
12083       *name,
12084       message[MaxTextExtent];
12085
12086     ExceptionInfo
12087       *exception;
12088
12089     register ssize_t
12090       i;
12091
12092     SV
12093       *perl_exception;
12094
12095     volatile const TypeInfo
12096       *type_info;
12097
12098     PERL_UNUSED_VAR(ref);
12099     PERL_UNUSED_VAR(ix);
12100     exception=AcquireExceptionInfo();
12101     perl_exception=newSVpv("",0);
12102     if (items == 1)
12103       {
12104         const TypeInfo
12105           **typelist;
12106
12107         size_t
12108           types;
12109
12110         typelist=GetTypeInfoList("*",&types,exception);
12111         EXTEND(sp,types);
12112         for (i=0; i < (ssize_t) types; i++)
12113         {
12114           PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12115         }
12116         typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12117           typelist);
12118         goto PerlException;
12119       }
12120     EXTEND(sp,10*items);
12121     for (i=1; i < items; i++)
12122     {
12123       name=(char *) SvPV(ST(i),na);
12124       type_info=GetTypeInfo(name,exception);
12125       if (type_info == (TypeInfo *) NULL)
12126         {
12127           PUSHs(&sv_undef);
12128           continue;
12129         }
12130       if (type_info->name == (char *) NULL)
12131         PUSHs(&sv_undef);
12132       else
12133         PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12134       if (type_info->description == (char *) NULL)
12135         PUSHs(&sv_undef);
12136       else
12137         PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12138       if (type_info->family == (char *) NULL)
12139         PUSHs(&sv_undef);
12140       else
12141         PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12142       if (type_info->style == UndefinedStyle)
12143         PUSHs(&sv_undef);
12144       else
12145         PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12146           type_info->style),0)));
12147       if (type_info->stretch == UndefinedStretch)
12148         PUSHs(&sv_undef);
12149       else
12150         PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12151           type_info->stretch),0)));
12152       (void) FormatLocaleString(message,MaxTextExtent,"%.20g",(double)
12153         type_info->weight);
12154       PUSHs(sv_2mortal(newSVpv(message,0)));
12155       if (type_info->encoding == (char *) NULL)
12156         PUSHs(&sv_undef);
12157       else
12158         PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12159       if (type_info->foundry == (char *) NULL)
12160         PUSHs(&sv_undef);
12161       else
12162         PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12163       if (type_info->format == (char *) NULL)
12164         PUSHs(&sv_undef);
12165       else
12166         PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12167       if (type_info->metrics == (char *) NULL)
12168         PUSHs(&sv_undef);
12169       else
12170         PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12171       if (type_info->glyphs == (char *) NULL)
12172         PUSHs(&sv_undef);
12173       else
12174         PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12175     }
12176
12177   PerlException:
12178     InheritPerlException(exception,perl_exception);
12179     exception=DestroyExceptionInfo(exception);
12180     SvREFCNT_dec(perl_exception);
12181   }
12182 \f
12183 #
12184 ###############################################################################
12185 #                                                                             #
12186 #                                                                             #
12187 #                                                                             #
12188 #   Q u e r y F o n t M e t r i c s                                           #
12189 #                                                                             #
12190 #                                                                             #
12191 #                                                                             #
12192 ###############################################################################
12193 #
12194 #
12195 void
12196 QueryFontMetrics(ref,...)
12197   Image::Magick::Q16HDRI ref=NO_INIT
12198   ALIAS:
12199     queryfontmetrics = 1
12200   PPCODE:
12201   {
12202     AffineMatrix
12203       affine,
12204       current;
12205
12206     AV
12207       *av;
12208
12209     char
12210       *attribute;
12211
12212     double
12213       x,
12214       y;
12215
12216     DrawInfo
12217       *draw_info;
12218
12219     ExceptionInfo
12220       *exception;
12221
12222     GeometryInfo
12223       geometry_info;
12224
12225     Image
12226       *image;
12227
12228     MagickBooleanType
12229       status;
12230
12231     MagickStatusType
12232       flags;
12233
12234     register ssize_t
12235       i;
12236
12237     ssize_t
12238       type;
12239
12240     struct PackageInfo
12241       *info,
12242       *package_info;
12243
12244     SV
12245       *perl_exception,
12246       *reference;  /* reference is the SV* of ref=SvIV(reference) */
12247
12248     TypeMetric
12249       metrics;
12250
12251     PERL_UNUSED_VAR(ref);
12252     PERL_UNUSED_VAR(ix);
12253     exception=AcquireExceptionInfo();
12254     package_info=(struct PackageInfo *) NULL;
12255     perl_exception=newSVpv("",0);
12256     reference=SvRV(ST(0));
12257     av=(AV *) reference;
12258     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12259       exception);
12260     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12261     if (image == (Image *) NULL)
12262       {
12263         ThrowPerlException(exception,OptionError,"NoImagesDefined",
12264           PackageName);
12265         goto PerlException;
12266       }
12267     package_info=ClonePackageInfo(info,exception);
12268     draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12269     CloneString(&draw_info->text,"");
12270     current=draw_info->affine;
12271     GetAffineMatrix(&affine);
12272     x=0.0;
12273     y=0.0;
12274     EXTEND(sp,7*items);
12275     for (i=2; i < items; i+=2)
12276     {
12277       attribute=(char *) SvPV(ST(i-1),na);
12278       switch (*attribute)
12279       {
12280         case 'A':
12281         case 'a':
12282         {
12283           if (LocaleCompare(attribute,"antialias") == 0)
12284             {
12285               type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12286                 SvPV(ST(i),na));
12287               if (type < 0)
12288                 {
12289                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
12290                     SvPV(ST(i),na));
12291                   break;
12292                 }
12293               draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12294               break;
12295             }
12296           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12297             attribute);
12298           break;
12299         }
12300         case 'd':
12301         case 'D':
12302         {
12303           if (LocaleCompare(attribute,"density") == 0)
12304             {
12305               CloneString(&draw_info->density,SvPV(ST(i),na));
12306               break;
12307             }
12308           if (LocaleCompare(attribute,"direction") == 0)
12309             {
12310               draw_info->direction=(DirectionType) ParseCommandOption(
12311                 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12312               break;
12313             }
12314           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12315             attribute);
12316           break;
12317         }
12318         case 'e':
12319         case 'E':
12320         {
12321           if (LocaleCompare(attribute,"encoding") == 0)
12322             {
12323               CloneString(&draw_info->encoding,SvPV(ST(i),na));
12324               break;
12325             }
12326           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12327             attribute);
12328           break;
12329         }
12330         case 'f':
12331         case 'F':
12332         {
12333           if (LocaleCompare(attribute,"family") == 0)
12334             {
12335               CloneString(&draw_info->family,SvPV(ST(i),na));
12336               break;
12337             }
12338           if (LocaleCompare(attribute,"fill") == 0)
12339             {
12340               if (info)
12341                 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12342                   &draw_info->fill,exception);
12343               break;
12344             }
12345           if (LocaleCompare(attribute,"font") == 0)
12346             {
12347               CloneString(&draw_info->font,SvPV(ST(i),na));
12348               break;
12349             }
12350           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12351             attribute);
12352           break;
12353         }
12354         case 'g':
12355         case 'G':
12356         {
12357           if (LocaleCompare(attribute,"geometry") == 0)
12358             {
12359               CloneString(&draw_info->geometry,SvPV(ST(i),na));
12360               break;
12361             }
12362           if (LocaleCompare(attribute,"gravity") == 0)
12363             {
12364               draw_info->gravity=(GravityType) ParseCommandOption(
12365                 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12366               break;
12367             }
12368           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12369             attribute);
12370           break;
12371         }
12372         case 'i':
12373         case 'I':
12374         {
12375           if (LocaleCompare(attribute,"interline-spacing") == 0)
12376             {
12377               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12378               draw_info->interline_spacing=geometry_info.rho;
12379               break;
12380             }
12381           if (LocaleCompare(attribute,"interword-spacing") == 0)
12382             {
12383               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12384               draw_info->interword_spacing=geometry_info.rho;
12385               break;
12386             }
12387           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12388             attribute);
12389           break;
12390         }
12391         case 'k':
12392         case 'K':
12393         {
12394           if (LocaleCompare(attribute,"kerning") == 0)
12395             {
12396               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12397               draw_info->kerning=geometry_info.rho;
12398               break;
12399             }
12400           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12401             attribute);
12402           break;
12403         }
12404         case 'p':
12405         case 'P':
12406         {
12407           if (LocaleCompare(attribute,"pointsize") == 0)
12408             {
12409               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12410               draw_info->pointsize=geometry_info.rho;
12411               break;
12412             }
12413           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12414             attribute);
12415           break;
12416         }
12417         case 'r':
12418         case 'R':
12419         {
12420           if (LocaleCompare(attribute,"rotate") == 0)
12421             {
12422               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12423               affine.rx=geometry_info.rho;
12424               affine.ry=geometry_info.sigma;
12425               if ((flags & SigmaValue) == 0)
12426                 affine.ry=affine.rx;
12427               break;
12428             }
12429           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12430             attribute);
12431           break;
12432         }
12433         case 's':
12434         case 'S':
12435         {
12436           if (LocaleCompare(attribute,"scale") == 0)
12437             {
12438               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12439               affine.sx=geometry_info.rho;
12440               affine.sy=geometry_info.sigma;
12441               if ((flags & SigmaValue) == 0)
12442                 affine.sy=affine.sx;
12443               break;
12444             }
12445           if (LocaleCompare(attribute,"skew") == 0)
12446             {
12447               double
12448                 x_angle,
12449                 y_angle;
12450
12451               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12452               x_angle=geometry_info.rho;
12453               y_angle=geometry_info.sigma;
12454               if ((flags & SigmaValue) == 0)
12455                 y_angle=x_angle;
12456               affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12457               affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12458               break;
12459             }
12460           if (LocaleCompare(attribute,"stroke") == 0)
12461             {
12462               if (info)
12463                 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12464                   &draw_info->stroke,exception);
12465               break;
12466             }
12467           if (LocaleCompare(attribute,"style") == 0)
12468             {
12469               type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12470                 SvPV(ST(i),na));
12471               if (type < 0)
12472                 {
12473                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
12474                     SvPV(ST(i),na));
12475                   break;
12476                 }
12477               draw_info->style=(StyleType) type;
12478               break;
12479             }
12480           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12481             attribute);
12482           break;
12483         }
12484         case 't':
12485         case 'T':
12486         {
12487           if (LocaleCompare(attribute,"text") == 0)
12488             {
12489               CloneString(&draw_info->text,SvPV(ST(i),na));
12490               break;
12491             }
12492           if (LocaleCompare(attribute,"translate") == 0)
12493             {
12494               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12495               affine.tx=geometry_info.rho;
12496               affine.ty=geometry_info.sigma;
12497               if ((flags & SigmaValue) == 0)
12498                 affine.ty=affine.tx;
12499               break;
12500             }
12501           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12502             attribute);
12503           break;
12504         }
12505         case 'w':
12506         case 'W':
12507         {
12508           if (LocaleCompare(attribute,"weight") == 0)
12509             {
12510               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12511               draw_info->weight=(size_t) geometry_info.rho;
12512               break;
12513             }
12514           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12515             attribute);
12516           break;
12517         }
12518         case 'x':
12519         case 'X':
12520         {
12521           if (LocaleCompare(attribute,"x") == 0)
12522             {
12523               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12524               x=geometry_info.rho;
12525               break;
12526             }
12527           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12528             attribute);
12529           break;
12530         }
12531         case 'y':
12532         case 'Y':
12533         {
12534           if (LocaleCompare(attribute,"y") == 0)
12535             {
12536               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12537               y=geometry_info.rho;
12538               break;
12539             }
12540           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12541             attribute);
12542           break;
12543         }
12544         default:
12545         {
12546           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12547             attribute);
12548           break;
12549         }
12550       }
12551     }
12552     draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
12553     draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
12554     draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
12555     draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
12556     draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
12557     draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
12558     if (draw_info->geometry == (char *) NULL)
12559       {
12560         draw_info->geometry=AcquireString((char *) NULL);
12561         (void) FormatLocaleString(draw_info->geometry,MaxTextExtent,
12562           "%.15g,%.15g",x,y);
12563       }
12564     status=GetTypeMetrics(image,draw_info,&metrics,exception);
12565     (void) CatchImageException(image);
12566     if (status == MagickFalse)
12567       PUSHs(&sv_undef);
12568     else
12569       {
12570         PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
12571         PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
12572         PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
12573         PUSHs(sv_2mortal(newSVnv(metrics.descent)));
12574         PUSHs(sv_2mortal(newSVnv(metrics.width)));
12575         PUSHs(sv_2mortal(newSVnv(metrics.height)));
12576         PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
12577         PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
12578         PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
12579         PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
12580         PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
12581         PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
12582         PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
12583       }
12584     draw_info=DestroyDrawInfo(draw_info);
12585
12586   PerlException:
12587     if (package_info != (struct PackageInfo *) NULL)
12588       DestroyPackageInfo(package_info);
12589     InheritPerlException(exception,perl_exception);
12590     exception=DestroyExceptionInfo(exception);
12591     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
12592   }
12593 \f
12594 #
12595 ###############################################################################
12596 #                                                                             #
12597 #                                                                             #
12598 #                                                                             #
12599 #   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                         #
12600 #                                                                             #
12601 #                                                                             #
12602 #                                                                             #
12603 ###############################################################################
12604 #
12605 #
12606 void
12607 QueryMultilineFontMetrics(ref,...)
12608   Image::Magick::Q16HDRI ref=NO_INIT
12609   ALIAS:
12610     querymultilinefontmetrics = 1
12611   PPCODE:
12612   {
12613     AffineMatrix
12614       affine,
12615       current;
12616
12617     AV
12618       *av;
12619
12620     char
12621       *attribute;
12622
12623     double
12624       x,
12625       y;
12626
12627     DrawInfo
12628       *draw_info;
12629
12630     ExceptionInfo
12631       *exception;
12632
12633     GeometryInfo
12634       geometry_info;
12635
12636     Image
12637       *image;
12638
12639     MagickBooleanType
12640       status;
12641
12642     MagickStatusType
12643       flags;
12644
12645     register ssize_t
12646       i;
12647
12648     ssize_t
12649       type;
12650
12651     struct PackageInfo
12652       *info,
12653       *package_info;
12654
12655     SV
12656       *perl_exception,
12657       *reference;  /* reference is the SV* of ref=SvIV(reference) */
12658
12659     TypeMetric
12660       metrics;
12661
12662     PERL_UNUSED_VAR(ref);
12663     PERL_UNUSED_VAR(ix);
12664     exception=AcquireExceptionInfo();
12665     package_info=(struct PackageInfo *) NULL;
12666     perl_exception=newSVpv("",0);
12667     reference=SvRV(ST(0));
12668     av=(AV *) reference;
12669     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12670       exception);
12671     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12672     if (image == (Image *) NULL)
12673       {
12674         ThrowPerlException(exception,OptionError,"NoImagesDefined",
12675           PackageName);
12676         goto PerlException;
12677       }
12678     package_info=ClonePackageInfo(info,exception);
12679     draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12680     CloneString(&draw_info->text,"");
12681     current=draw_info->affine;
12682     GetAffineMatrix(&affine);
12683     x=0.0;
12684     y=0.0;
12685     EXTEND(sp,7*items);
12686     for (i=2; i < items; i+=2)
12687     {
12688       attribute=(char *) SvPV(ST(i-1),na);
12689       switch (*attribute)
12690       {
12691         case 'A':
12692         case 'a':
12693         {
12694           if (LocaleCompare(attribute,"antialias") == 0)
12695             {
12696               type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12697                 SvPV(ST(i),na));
12698               if (type < 0)
12699                 {
12700                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
12701                     SvPV(ST(i),na));
12702                   break;
12703                 }
12704               draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12705               break;
12706             }
12707           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12708             attribute);
12709           break;
12710         }
12711         case 'd':
12712         case 'D':
12713         {
12714           if (LocaleCompare(attribute,"density") == 0)
12715             {
12716               CloneString(&draw_info->density,SvPV(ST(i),na));
12717               break;
12718             }
12719           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12720             attribute);
12721           break;
12722         }
12723         case 'e':
12724         case 'E':
12725         {
12726           if (LocaleCompare(attribute,"encoding") == 0)
12727             {
12728               CloneString(&draw_info->encoding,SvPV(ST(i),na));
12729               break;
12730             }
12731           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12732             attribute);
12733           break;
12734         }
12735         case 'f':
12736         case 'F':
12737         {
12738           if (LocaleCompare(attribute,"family") == 0)
12739             {
12740               CloneString(&draw_info->family,SvPV(ST(i),na));
12741               break;
12742             }
12743           if (LocaleCompare(attribute,"fill") == 0)
12744             {
12745               if (info)
12746                 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12747                   &draw_info->fill,exception);
12748               break;
12749             }
12750           if (LocaleCompare(attribute,"font") == 0)
12751             {
12752               CloneString(&draw_info->font,SvPV(ST(i),na));
12753               break;
12754             }
12755           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12756             attribute);
12757           break;
12758         }
12759         case 'g':
12760         case 'G':
12761         {
12762           if (LocaleCompare(attribute,"geometry") == 0)
12763             {
12764               CloneString(&draw_info->geometry,SvPV(ST(i),na));
12765               break;
12766             }
12767           if (LocaleCompare(attribute,"gravity") == 0)
12768             {
12769               draw_info->gravity=(GravityType) ParseCommandOption(
12770                 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12771               break;
12772             }
12773           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12774             attribute);
12775           break;
12776         }
12777         case 'p':
12778         case 'P':
12779         {
12780           if (LocaleCompare(attribute,"pointsize") == 0)
12781             {
12782               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12783               draw_info->pointsize=geometry_info.rho;
12784               break;
12785             }
12786           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12787             attribute);
12788           break;
12789         }
12790         case 'r':
12791         case 'R':
12792         {
12793           if (LocaleCompare(attribute,"rotate") == 0)
12794             {
12795               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12796               affine.rx=geometry_info.rho;
12797               affine.ry=geometry_info.sigma;
12798               if ((flags & SigmaValue) == 0)
12799                 affine.ry=affine.rx;
12800               break;
12801             }
12802           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12803             attribute);
12804           break;
12805         }
12806         case 's':
12807         case 'S':
12808         {
12809           if (LocaleCompare(attribute,"scale") == 0)
12810             {
12811               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12812               affine.sx=geometry_info.rho;
12813               affine.sy=geometry_info.sigma;
12814               if ((flags & SigmaValue) == 0)
12815                 affine.sy=affine.sx;
12816               break;
12817             }
12818           if (LocaleCompare(attribute,"skew") == 0)
12819             {
12820               double
12821                 x_angle,
12822                 y_angle;
12823
12824               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12825               x_angle=geometry_info.rho;
12826               y_angle=geometry_info.sigma;
12827               if ((flags & SigmaValue) == 0)
12828                 y_angle=x_angle;
12829               affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12830               affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12831               break;
12832             }
12833           if (LocaleCompare(attribute,"stroke") == 0)
12834             {
12835               if (info)
12836                 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12837                   &draw_info->stroke,exception);
12838               break;
12839             }
12840           if (LocaleCompare(attribute,"style") == 0)
12841             {
12842               type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12843                 SvPV(ST(i),na));
12844               if (type < 0)
12845                 {
12846                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
12847                     SvPV(ST(i),na));
12848                   break;
12849                 }
12850               draw_info->style=(StyleType) type;
12851               break;
12852             }
12853           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12854             attribute);
12855           break;
12856         }
12857         case 't':
12858         case 'T':
12859         {
12860           if (LocaleCompare(attribute,"text") == 0)
12861             {
12862               CloneString(&draw_info->text,SvPV(ST(i),na));
12863               break;
12864             }
12865           if (LocaleCompare(attribute,"translate") == 0)
12866             {
12867               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12868               affine.tx=geometry_info.rho;
12869               affine.ty=geometry_info.sigma;
12870               if ((flags & SigmaValue) == 0)
12871                 affine.ty=affine.tx;
12872               break;
12873             }
12874           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12875             attribute);
12876           break;
12877         }
12878         case 'w':
12879         case 'W':
12880         {
12881           if (LocaleCompare(attribute,"weight") == 0)
12882             {
12883               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12884               draw_info->weight=(size_t) geometry_info.rho;
12885               break;
12886             }
12887           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12888             attribute);
12889           break;
12890         }
12891         case 'x':
12892         case 'X':
12893         {
12894           if (LocaleCompare(attribute,"x") == 0)
12895             {
12896               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12897               x=geometry_info.rho;
12898               break;
12899             }
12900           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12901             attribute);
12902           break;
12903         }
12904         case 'y':
12905         case 'Y':
12906         {
12907           if (LocaleCompare(attribute,"y") == 0)
12908             {
12909               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12910               y=geometry_info.rho;
12911               break;
12912             }
12913           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12914             attribute);
12915           break;
12916         }
12917         default:
12918         {
12919           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12920             attribute);
12921           break;
12922         }
12923       }
12924     }
12925     draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
12926     draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
12927     draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
12928     draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
12929     draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
12930     draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
12931     if (draw_info->geometry == (char *) NULL)
12932       {
12933         draw_info->geometry=AcquireString((char *) NULL);
12934         (void) FormatLocaleString(draw_info->geometry,MaxTextExtent,
12935           "%.15g,%.15g",x,y);
12936       }
12937     status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
12938     (void) CatchException(exception);
12939     if (status == MagickFalse)
12940       PUSHs(&sv_undef);
12941     else
12942       {
12943         PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
12944         PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
12945         PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
12946         PUSHs(sv_2mortal(newSVnv(metrics.descent)));
12947         PUSHs(sv_2mortal(newSVnv(metrics.width)));
12948         PUSHs(sv_2mortal(newSVnv(metrics.height)));
12949         PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
12950         PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
12951         PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
12952         PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
12953         PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
12954         PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
12955         PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
12956       }
12957     draw_info=DestroyDrawInfo(draw_info);
12958
12959   PerlException:
12960     if (package_info != (struct PackageInfo *) NULL)
12961       DestroyPackageInfo(package_info);
12962     InheritPerlException(exception,perl_exception);
12963     exception=DestroyExceptionInfo(exception);
12964     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
12965   }
12966 \f
12967 #
12968 ###############################################################################
12969 #                                                                             #
12970 #                                                                             #
12971 #                                                                             #
12972 #   Q u e r y F o r m a t                                                     #
12973 #                                                                             #
12974 #                                                                             #
12975 #                                                                             #
12976 ###############################################################################
12977 #
12978 #
12979 void
12980 QueryFormat(ref,...)
12981   Image::Magick::Q16HDRI ref=NO_INIT
12982   ALIAS:
12983     queryformat = 1
12984   PPCODE:
12985   {
12986     char
12987       *name;
12988
12989     ExceptionInfo
12990       *exception;
12991
12992     register ssize_t
12993       i;
12994
12995     SV
12996       *perl_exception;
12997
12998     volatile const MagickInfo
12999       *magick_info;
13000
13001     PERL_UNUSED_VAR(ref);
13002     PERL_UNUSED_VAR(ix);
13003     exception=AcquireExceptionInfo();
13004     perl_exception=newSVpv("",0);
13005     if (items == 1)
13006       {
13007         char
13008           format[MaxTextExtent];
13009
13010         const MagickInfo
13011           **format_list;
13012
13013         size_t
13014           types;
13015
13016         format_list=GetMagickInfoList("*",&types,exception);
13017         EXTEND(sp,types);
13018         for (i=0; i < (ssize_t) types; i++)
13019         {
13020           (void) CopyMagickString(format,format_list[i]->name,MaxTextExtent);
13021           LocaleLower(format);
13022           PUSHs(sv_2mortal(newSVpv(format,0)));
13023         }
13024         format_list=(const MagickInfo **)
13025           RelinquishMagickMemory((MagickInfo *) format_list);
13026         goto PerlException;
13027       }
13028     EXTEND(sp,8*items);
13029     for (i=1; i < items; i++)
13030     {
13031       name=(char *) SvPV(ST(i),na);
13032       magick_info=GetMagickInfo(name,exception);
13033       if (magick_info == (const MagickInfo *) NULL)
13034         {
13035           PUSHs(&sv_undef);
13036           continue;
13037         }
13038       PUSHs(sv_2mortal(newSViv(magick_info->adjoin)));
13039       PUSHs(sv_2mortal(newSViv(magick_info->blob_support)));
13040       PUSHs(sv_2mortal(newSViv(magick_info->raw)));
13041       PUSHs(sv_2mortal(newSViv((long) magick_info->decoder)));
13042       PUSHs(sv_2mortal(newSViv((long) magick_info->encoder)));
13043       if (magick_info->description == (char *) NULL)
13044         PUSHs(&sv_undef);
13045       else
13046         PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13047       if (magick_info->module == (char *) NULL)
13048         PUSHs(&sv_undef);
13049       else
13050         PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
13051     }
13052
13053   PerlException:
13054     InheritPerlException(exception,perl_exception);
13055     exception=DestroyExceptionInfo(exception);
13056     SvREFCNT_dec(perl_exception);
13057   }
13058 \f
13059 #
13060 ###############################################################################
13061 #                                                                             #
13062 #                                                                             #
13063 #                                                                             #
13064 #   Q u e r y O p t i o n                                                     #
13065 #                                                                             #
13066 #                                                                             #
13067 #                                                                             #
13068 ###############################################################################
13069 #
13070 #
13071 void
13072 QueryOption(ref,...)
13073   Image::Magick::Q16HDRI ref=NO_INIT
13074   ALIAS:
13075     queryoption = 1
13076   PPCODE:
13077   {
13078     char
13079       **options;
13080
13081     ExceptionInfo
13082       *exception;
13083
13084     register ssize_t
13085       i;
13086
13087     ssize_t
13088       j,
13089       option;
13090
13091     SV
13092       *perl_exception;
13093
13094     PERL_UNUSED_VAR(ref);
13095     PERL_UNUSED_VAR(ix);
13096     exception=AcquireExceptionInfo();
13097     perl_exception=newSVpv("",0);
13098     EXTEND(sp,8*items);
13099     for (i=1; i < items; i++)
13100     {
13101       option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13102         SvPV(ST(i),na));
13103       options=GetCommandOptions((CommandOption) option);
13104       if (options == (char **) NULL)
13105         PUSHs(&sv_undef);
13106       else
13107         {
13108           for (j=0; options[j] != (char *) NULL; j++)
13109             PUSHs(sv_2mortal(newSVpv(options[j],0)));
13110           options=DestroyStringList(options);
13111         }
13112     }
13113
13114     InheritPerlException(exception,perl_exception);
13115     exception=DestroyExceptionInfo(exception);
13116     SvREFCNT_dec(perl_exception);
13117   }
13118 \f
13119 #
13120 ###############################################################################
13121 #                                                                             #
13122 #                                                                             #
13123 #                                                                             #
13124 #   R e a d                                                                   #
13125 #                                                                             #
13126 #                                                                             #
13127 #                                                                             #
13128 ###############################################################################
13129 #
13130 #
13131 void
13132 Read(ref,...)
13133   Image::Magick::Q16HDRI ref=NO_INIT
13134   ALIAS:
13135     ReadImage  = 1
13136     read       = 2
13137     readimage  = 3
13138   PPCODE:
13139   {
13140     AV
13141       *av;
13142
13143     char
13144       **keep,
13145       **list;
13146
13147     ExceptionInfo
13148       *exception;
13149
13150     HV
13151       *hv;
13152
13153     Image
13154       *image;
13155
13156     int
13157       n;
13158
13159     MagickBooleanType
13160       status;
13161
13162     register char
13163       **p;
13164
13165     register ssize_t
13166       i;
13167
13168     ssize_t
13169       ac,
13170       number_images;
13171
13172     STRLEN
13173       *length;
13174
13175     struct PackageInfo
13176       *info,
13177       *package_info;
13178
13179     SV
13180       *perl_exception,  /* Perl variable for storing messages */
13181       *reference,
13182       *rv,
13183       *sv;
13184
13185     PERL_UNUSED_VAR(ref);
13186     PERL_UNUSED_VAR(ix);
13187     exception=AcquireExceptionInfo();
13188     perl_exception=newSVpv("",0);
13189     sv=NULL;
13190     package_info=(struct PackageInfo *) NULL;
13191     number_images=0;
13192     ac=(items < 2) ? 1 : items-1;
13193     list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13194     keep=list;
13195     length=(STRLEN *) NULL;
13196     if (list == (char **) NULL)
13197       {
13198         ThrowPerlException(exception,ResourceLimitError,
13199           "MemoryAllocationFailed",PackageName);
13200         goto PerlException;
13201       }
13202     length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13203     if (length == (STRLEN *) NULL)
13204       {
13205         ThrowPerlException(exception,ResourceLimitError,
13206           "MemoryAllocationFailed",PackageName);
13207         goto PerlException;
13208       }
13209     if (sv_isobject(ST(0)) == 0)
13210       {
13211         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13212           PackageName);
13213         goto PerlException;
13214       }
13215     reference=SvRV(ST(0));
13216     hv=SvSTASH(reference);
13217     if (SvTYPE(reference) != SVt_PVAV)
13218       {
13219         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13220           PackageName);
13221         goto PerlException;
13222       }
13223     av=(AV *) reference;
13224     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13225       exception);
13226     package_info=ClonePackageInfo(info,exception);
13227     n=1;
13228     if (items <= 1)
13229       *list=(char *) (*package_info->image_info->filename ?
13230         package_info->image_info->filename : "XC:black");
13231     else
13232       for (n=0, i=0; i < ac; i++)
13233       {
13234         list[n]=(char *) SvPV(ST(i+1),length[n]);
13235         if ((items >= 3) && strEQcase(list[n],"blob"))
13236           {
13237             void
13238               *blob;
13239
13240             i++;
13241             blob=(void *) (SvPV(ST(i+1),length[n]));
13242             SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13243           }
13244         if ((items >= 3) && strEQcase(list[n],"filename"))
13245           continue;
13246         if ((items >= 3) && strEQcase(list[n],"file"))
13247           {
13248             FILE
13249               *file;
13250
13251             PerlIO
13252               *io_info;
13253
13254             i++;
13255             io_info=IoIFP(sv_2io(ST(i+1)));
13256             if (io_info == (PerlIO *) NULL)
13257               {
13258                 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13259                   PackageName);
13260                 continue;
13261               }
13262             file=PerlIO_findFILE(io_info);
13263             if (file == (FILE *) NULL)
13264               {
13265                 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13266                   PackageName);
13267                 continue;
13268               }
13269             SetImageInfoFile(package_info->image_info,file);
13270           }
13271         if ((items >= 3) && strEQcase(list[n],"magick"))
13272           continue;
13273         n++;
13274       }
13275     list[n]=(char *) NULL;
13276     keep=list;
13277     status=ExpandFilenames(&n,&list);
13278     if (status == MagickFalse)
13279       {
13280         ThrowPerlException(exception,ResourceLimitError,
13281           "MemoryAllocationFailed",PackageName);
13282         goto PerlException;
13283       }
13284     number_images=0;
13285     for (i=0; i < n; i++)
13286     {
13287       if ((package_info->image_info->file == (FILE *) NULL) &&
13288           (package_info->image_info->blob == (void *) NULL))
13289         image=ReadImages(package_info->image_info,list[i],exception);
13290       else
13291         {
13292           image=ReadImages(package_info->image_info,
13293             package_info->image_info->filename,exception);
13294           if (image != (Image *) NULL)
13295             DisassociateImageStream(image);
13296         }
13297       if (image == (Image *) NULL)
13298         break;
13299       for ( ; image; image=image->next)
13300       {
13301         AddImageToRegistry(sv,image);
13302         rv=newRV(sv);
13303         av_push(av,sv_bless(rv,hv));
13304         SvREFCNT_dec(sv);
13305         number_images++;
13306       }
13307     }
13308     /*
13309       Free resources.
13310     */
13311     for (i=0; i < n; i++)
13312       if (list[i] != (char *) NULL)
13313         for (p=keep; list[i] != *p++; )
13314           if (*p == (char *) NULL)
13315             {
13316               list[i]=(char *) RelinquishMagickMemory(list[i]);
13317               break;
13318             }
13319
13320   PerlException:
13321     if (package_info != (struct PackageInfo *) NULL)
13322       DestroyPackageInfo(package_info);
13323     if (list && (list != keep))
13324       list=(char **) RelinquishMagickMemory(list);
13325     if (keep)
13326       keep=(char **) RelinquishMagickMemory(keep);
13327     if (length)
13328       length=(STRLEN *) RelinquishMagickMemory(length);
13329     InheritPerlException(exception,perl_exception);
13330     exception=DestroyExceptionInfo(exception);
13331     sv_setiv(perl_exception,(IV) number_images);
13332     SvPOK_on(perl_exception);
13333     ST(0)=sv_2mortal(perl_exception);
13334     XSRETURN(1);
13335   }
13336 \f
13337 #
13338 ###############################################################################
13339 #                                                                             #
13340 #                                                                             #
13341 #                                                                             #
13342 #   R e m o t e                                                               #
13343 #                                                                             #
13344 #                                                                             #
13345 #                                                                             #
13346 ###############################################################################
13347 #
13348 #
13349 void
13350 Remote(ref,...)
13351   Image::Magick::Q16HDRI ref=NO_INIT
13352   ALIAS:
13353     RemoteCommand  = 1
13354     remote         = 2
13355     remoteCommand  = 3
13356   PPCODE:
13357   {
13358     AV
13359       *av;
13360
13361     ExceptionInfo
13362       *exception;
13363
13364     register ssize_t
13365       i;
13366
13367     SV
13368       *perl_exception,
13369       *reference;
13370
13371     struct PackageInfo
13372       *info;
13373
13374     PERL_UNUSED_VAR(ref);
13375     PERL_UNUSED_VAR(ix);
13376     exception=AcquireExceptionInfo();
13377     perl_exception=newSVpv("",0);
13378     reference=SvRV(ST(0));
13379     av=(AV *) reference;
13380     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13381       exception);
13382     for (i=1; i < items; i++)
13383       (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13384         SvPV(ST(i),na),exception);
13385     InheritPerlException(exception,perl_exception);
13386     exception=DestroyExceptionInfo(exception);
13387     SvREFCNT_dec(perl_exception);    /* throw away all errors */
13388   }
13389 \f
13390 #
13391 ###############################################################################
13392 #                                                                             #
13393 #                                                                             #
13394 #                                                                             #
13395 #   S e t                                                                     #
13396 #                                                                             #
13397 #                                                                             #
13398 #                                                                             #
13399 ###############################################################################
13400 #
13401 #
13402 void
13403 Set(ref,...)
13404   Image::Magick::Q16HDRI ref=NO_INIT
13405   ALIAS:
13406     SetAttributes  = 1
13407     SetAttribute   = 2
13408     set            = 3
13409     setattributes  = 4
13410     setattribute   = 5
13411   PPCODE:
13412   {
13413     ExceptionInfo
13414       *exception;
13415
13416     Image
13417       *image;
13418
13419     register ssize_t
13420       i;
13421
13422     struct PackageInfo
13423       *info;
13424
13425     SV
13426       *perl_exception,
13427       *reference;  /* reference is the SV* of ref=SvIV(reference) */
13428
13429     PERL_UNUSED_VAR(ref);
13430     PERL_UNUSED_VAR(ix);
13431     exception=AcquireExceptionInfo();
13432     perl_exception=newSVpv("",0);
13433     if (sv_isobject(ST(0)) == 0)
13434       {
13435         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13436           PackageName);
13437         goto PerlException;
13438       }
13439     reference=SvRV(ST(0));
13440     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13441     if (items == 2)
13442       SetAttribute(aTHX_ info,image,"size",ST(1),exception);
13443     else
13444       for (i=2; i < items; i+=2)
13445         SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
13446
13447   PerlException:
13448     InheritPerlException(exception,perl_exception);
13449     exception=DestroyExceptionInfo(exception);
13450     sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
13451     SvPOK_on(perl_exception);
13452     ST(0)=sv_2mortal(perl_exception);
13453     XSRETURN(1);
13454   }
13455 \f
13456 #
13457 ###############################################################################
13458 #                                                                             #
13459 #                                                                             #
13460 #                                                                             #
13461 #   S e t P i x e l                                                           #
13462 #                                                                             #
13463 #                                                                             #
13464 #                                                                             #
13465 ###############################################################################
13466 #
13467 #
13468 void
13469 SetPixel(ref,...)
13470   Image::Magick::Q16HDRI ref=NO_INIT
13471   ALIAS:
13472     setpixel = 1
13473     setPixel = 2
13474   PPCODE:
13475   {
13476     AV
13477       *av;
13478
13479     char
13480       *attribute;
13481
13482     ChannelType
13483       channel,
13484       channel_mask;
13485
13486     ExceptionInfo
13487       *exception;
13488
13489     Image
13490       *image;
13491
13492     MagickBooleanType
13493       normalize;
13494
13495     RectangleInfo
13496       region;
13497
13498     register ssize_t
13499       i;
13500
13501     register Quantum
13502       *q;
13503
13504     ssize_t
13505       option;
13506
13507     struct PackageInfo
13508       *info;
13509
13510     SV
13511       *perl_exception,
13512       *reference;  /* reference is the SV* of ref=SvIV(reference) */
13513
13514     PERL_UNUSED_VAR(ref);
13515     PERL_UNUSED_VAR(ix);
13516     exception=AcquireExceptionInfo();
13517     perl_exception=newSVpv("",0);
13518     reference=SvRV(ST(0));
13519     av=(AV *) reference;
13520     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13521       exception);
13522     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13523     if (image == (Image *) NULL)
13524       {
13525         ThrowPerlException(exception,OptionError,"NoImagesDefined",
13526           PackageName);
13527         goto PerlException;
13528       }
13529     av=(AV *) NULL;
13530     normalize=MagickTrue;
13531     region.x=0;
13532     region.y=0;
13533     region.width=image->columns;
13534     region.height=1;
13535     if (items == 1)
13536       (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
13537     channel=DefaultChannels;
13538     for (i=2; i < items; i+=2)
13539     {
13540       attribute=(char *) SvPV(ST(i-1),na);
13541       switch (*attribute)
13542       {
13543         case 'C':
13544         case 'c':
13545         {
13546           if (LocaleCompare(attribute,"channel") == 0)
13547             {
13548               ssize_t
13549                 option;
13550
13551               option=ParseChannelOption(SvPV(ST(i),na));
13552               if (option < 0)
13553                 {
13554                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
13555                     SvPV(ST(i),na));
13556                   return;
13557                 }
13558               channel=(ChannelType) option;
13559               break;
13560             }
13561           if (LocaleCompare(attribute,"color") == 0)
13562             {
13563               if (SvTYPE(ST(i)) != SVt_RV)
13564                 {
13565                   char
13566                     message[MaxTextExtent];
13567
13568                   (void) FormatLocaleString(message,MaxTextExtent,
13569                     "invalid %.60s value",attribute);
13570                   ThrowPerlException(exception,OptionError,message,
13571                     SvPV(ST(i),na));
13572                 }
13573               av=(AV *) SvRV(ST(i));
13574               break;
13575             }
13576           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13577             attribute);
13578           break;
13579         }
13580         case 'g':
13581         case 'G':
13582         {
13583           if (LocaleCompare(attribute,"geometry") == 0)
13584             {
13585               (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
13586               break;
13587             }
13588           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13589             attribute);
13590           break;
13591         }
13592         case 'N':
13593         case 'n':
13594         {
13595           if (LocaleCompare(attribute,"normalize") == 0)
13596             {
13597               option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13598                 SvPV(ST(i),na));
13599               if (option < 0)
13600                 {
13601                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
13602                     SvPV(ST(i),na));
13603                   break;
13604                 }
13605              normalize=option != 0 ? MagickTrue : MagickFalse;
13606              break;
13607             }
13608           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13609             attribute);
13610           break;
13611         }
13612         case 'x':
13613         case 'X':
13614         {
13615           if (LocaleCompare(attribute,"x") == 0)
13616             {
13617               region.x=SvIV(ST(i));
13618               break;
13619             }
13620           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13621             attribute);
13622           break;
13623         }
13624         case 'y':
13625         case 'Y':
13626         {
13627           if (LocaleCompare(attribute,"y") == 0)
13628             {
13629               region.y=SvIV(ST(i));
13630               break;
13631             }
13632           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13633             attribute);
13634           break;
13635         }
13636         default:
13637         {
13638           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13639             attribute);
13640           break;
13641         }
13642       }
13643     }
13644     (void) SetImageStorageClass(image,DirectClass,exception);
13645     channel_mask=SetImageChannelMask(image,channel);
13646     q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
13647     if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
13648         (SvTYPE(av) != SVt_PVAV))
13649       PUSHs(&sv_undef);
13650     else
13651       {
13652         double
13653           scale;
13654
13655         register ssize_t
13656           i;
13657
13658         i=0;
13659         scale=1.0;
13660         if (normalize != MagickFalse)
13661           scale=QuantumRange;
13662         if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
13663             (i <= av_len(av)))
13664           {
13665             SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
13666               av_fetch(av,i,0)))),q);
13667             i++;
13668           }
13669         if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
13670             (i <= av_len(av)))
13671           {
13672             SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
13673               av_fetch(av,i,0)))),q);
13674             i++;
13675           }
13676         if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
13677             (i <= av_len(av)))
13678           {
13679             SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
13680               av_fetch(av,i,0)))),q);
13681             i++;
13682           }
13683         if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
13684             (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
13685           {
13686             SetPixelBlack(image,ClampToQuantum(scale*
13687               SvNV(*(av_fetch(av,i,0)))),q);
13688             i++;
13689           }
13690         if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
13691             (i <= av_len(av)))
13692           {
13693             SetPixelAlpha(image,ClampToQuantum(scale*
13694               SvNV(*(av_fetch(av,i,0)))),q);
13695             i++;
13696           }
13697         (void) SyncAuthenticPixels(image,exception);
13698       }
13699     (void) SetImageChannelMask(image,channel_mask);
13700
13701   PerlException:
13702     InheritPerlException(exception,perl_exception);
13703     exception=DestroyExceptionInfo(exception);
13704     SvREFCNT_dec(perl_exception);
13705   }
13706 \f
13707 #
13708 ###############################################################################
13709 #                                                                             #
13710 #                                                                             #
13711 #                                                                             #
13712 #   S m u s h                                                                 #
13713 #                                                                             #
13714 #                                                                             #
13715 #                                                                             #
13716 ###############################################################################
13717 #
13718 #
13719 void
13720 Smush(ref,...)
13721   Image::Magick::Q16HDRI ref=NO_INIT
13722   ALIAS:
13723     SmushImage  = 1
13724     smush       = 2
13725     smushimage  = 3
13726   PPCODE:
13727   {
13728     AV
13729       *av;
13730
13731     char
13732       *attribute;
13733
13734     ExceptionInfo
13735       *exception;
13736
13737     HV
13738       *hv;
13739
13740     Image
13741       *image;
13742
13743     register ssize_t
13744       i;
13745
13746     ssize_t
13747       offset,
13748       stack;
13749
13750     struct PackageInfo
13751       *info;
13752
13753     SV
13754       *av_reference,
13755       *perl_exception,
13756       *reference,
13757       *rv,
13758       *sv;
13759
13760     PERL_UNUSED_VAR(ref);
13761     PERL_UNUSED_VAR(ix);
13762     exception=AcquireExceptionInfo();
13763     perl_exception=newSVpv("",0);
13764     sv=NULL;
13765     attribute=NULL;
13766     av=NULL;
13767     if (sv_isobject(ST(0)) == 0)
13768       {
13769         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13770           PackageName);
13771         goto PerlException;
13772       }
13773     reference=SvRV(ST(0));
13774     hv=SvSTASH(reference);
13775     av=newAV();
13776     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
13777     SvREFCNT_dec(av);
13778     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13779     if (image == (Image *) NULL)
13780       {
13781         ThrowPerlException(exception,OptionError,"NoImagesDefined",
13782           PackageName);
13783         goto PerlException;
13784       }
13785     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
13786     /*
13787       Get options.
13788     */
13789     offset=0;
13790     stack=MagickTrue;
13791     for (i=2; i < items; i+=2)
13792     {
13793       attribute=(char *) SvPV(ST(i-1),na);
13794       switch (*attribute)
13795       {
13796         case 'O':
13797         case 'o':
13798         {
13799           if (LocaleCompare(attribute,"offset") == 0)
13800             {
13801               offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
13802               break;
13803             }
13804           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13805             attribute);
13806           break;
13807         }
13808         case 'S':
13809         case 's':
13810         {
13811           if (LocaleCompare(attribute,"stack") == 0)
13812             {
13813               stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13814                 SvPV(ST(i),na));
13815               if (stack < 0)
13816                 {
13817                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
13818                     SvPV(ST(i),na));
13819                   return;
13820                 }
13821               break;
13822             }
13823           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13824             attribute);
13825           break;
13826         }
13827         default:
13828         {
13829           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13830             attribute);
13831           break;
13832         }
13833       }
13834     }
13835     image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
13836       exception);
13837     if (image == (Image *) NULL)
13838       goto PerlException;
13839     for ( ; image; image=image->next)
13840     {
13841       AddImageToRegistry(sv,image);
13842       rv=newRV(sv);
13843       av_push(av,sv_bless(rv,hv));
13844       SvREFCNT_dec(sv);
13845     }
13846     exception=DestroyExceptionInfo(exception);
13847     ST(0)=av_reference;
13848     SvREFCNT_dec(perl_exception);
13849     XSRETURN(1);
13850
13851   PerlException:
13852     InheritPerlException(exception,perl_exception);
13853     exception=DestroyExceptionInfo(exception);
13854     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
13855     SvPOK_on(perl_exception);
13856     ST(0)=sv_2mortal(perl_exception);
13857     XSRETURN(1);
13858   }
13859 \f
13860 #
13861 ###############################################################################
13862 #                                                                             #
13863 #                                                                             #
13864 #                                                                             #
13865 #   S t a t i s t i c s                                                       #
13866 #                                                                             #
13867 #                                                                             #
13868 #                                                                             #
13869 ###############################################################################
13870 #
13871 #
13872 void
13873 Statistics(ref,...)
13874   Image::Magick::Q16HDRI ref=NO_INIT
13875   ALIAS:
13876     StatisticsImage = 1
13877     statistics      = 2
13878     statisticsimage = 3
13879   PPCODE:
13880   {
13881 #define ChannelStatistics(channel) \
13882 { \
13883   (void) FormatLocaleString(message,MaxTextExtent,"%.20g", \
13884     (double) channel_statistics[channel].depth); \
13885   PUSHs(sv_2mortal(newSVpv(message,0))); \
13886   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
13887     channel_statistics[channel].minima/scale); \
13888   PUSHs(sv_2mortal(newSVpv(message,0))); \
13889   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
13890     channel_statistics[channel].maxima/scale); \
13891   PUSHs(sv_2mortal(newSVpv(message,0))); \
13892   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
13893     channel_statistics[channel].mean/scale); \
13894   PUSHs(sv_2mortal(newSVpv(message,0))); \
13895   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
13896     channel_statistics[channel].standard_deviation/scale); \
13897   PUSHs(sv_2mortal(newSVpv(message,0))); \
13898   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
13899     channel_statistics[channel].kurtosis); \
13900   PUSHs(sv_2mortal(newSVpv(message,0))); \
13901   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
13902     channel_statistics[channel].skewness); \
13903   PUSHs(sv_2mortal(newSVpv(message,0))); \
13904 }
13905
13906     AV
13907       *av;
13908
13909     char
13910       message[MaxTextExtent];
13911
13912     ChannelStatistics
13913       *channel_statistics;
13914
13915     double
13916       scale;
13917
13918     ExceptionInfo
13919       *exception;
13920
13921     Image
13922       *image;
13923
13924     ssize_t
13925       count;
13926
13927     struct PackageInfo
13928       *info;
13929
13930     SV
13931       *perl_exception,
13932       *reference;
13933
13934     PERL_UNUSED_VAR(ref);
13935     PERL_UNUSED_VAR(ix);
13936     exception=AcquireExceptionInfo();
13937     perl_exception=newSVpv("",0);
13938     av=NULL;
13939     if (sv_isobject(ST(0)) == 0)
13940       {
13941         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13942           PackageName);
13943         goto PerlException;
13944       }
13945     reference=SvRV(ST(0));
13946     av=newAV();
13947     SvREFCNT_dec(av);
13948     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13949     if (image == (Image *) NULL)
13950       {
13951         ThrowPerlException(exception,OptionError,"NoImagesDefined",
13952           PackageName);
13953         goto PerlException;
13954       }
13955     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
13956     count=0;
13957     for ( ; image; image=image->next)
13958     {
13959       channel_statistics=GetImageStatistics(image,exception);
13960       if (channel_statistics == (ChannelStatistics *) NULL)
13961         continue;
13962       count++;
13963       EXTEND(sp,35*count);
13964       scale=(double) QuantumRange;
13965       ChannelStatistics(RedChannel);
13966       ChannelStatistics(GreenChannel);
13967       ChannelStatistics(BlueChannel);
13968       if (image->colorspace == CMYKColorspace)
13969         ChannelStatistics(BlackChannel);
13970       if (image->alpha_trait == BlendPixelTrait)
13971         ChannelStatistics(AlphaChannel);
13972       channel_statistics=(ChannelStatistics *)
13973         RelinquishMagickMemory(channel_statistics);
13974     }
13975
13976   PerlException:
13977     InheritPerlException(exception,perl_exception);
13978     exception=DestroyExceptionInfo(exception);
13979     SvREFCNT_dec(perl_exception);
13980   }
13981 \f
13982 #
13983 ###############################################################################
13984 #                                                                             #
13985 #                                                                             #
13986 #                                                                             #
13987 #   S y n c A u t h e n t i c P i x e l s                                     #
13988 #                                                                             #
13989 #                                                                             #
13990 #                                                                             #
13991 ###############################################################################
13992 #
13993 #
13994 void
13995 SyncAuthenticPixels(ref,...)
13996   Image::Magick::Q16HDRI ref = NO_INIT
13997   ALIAS:
13998     Syncauthenticpixels = 1
13999     SyncImagePixels = 2
14000     syncimagepixels = 3
14001   CODE:
14002   {
14003     ExceptionInfo
14004       *exception;
14005
14006     Image
14007       *image;
14008
14009     MagickBooleanType
14010       status;
14011
14012     struct PackageInfo
14013       *info;
14014
14015     SV
14016       *perl_exception,
14017       *reference;
14018
14019     PERL_UNUSED_VAR(ref);
14020     PERL_UNUSED_VAR(ix);
14021     exception=AcquireExceptionInfo();
14022     perl_exception=newSVpv("",0);
14023     if (sv_isobject(ST(0)) == 0)
14024       {
14025         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14026           PackageName);
14027         goto PerlException;
14028       }
14029
14030     reference=SvRV(ST(0));
14031     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14032     if (image == (Image *) NULL)
14033       {
14034         ThrowPerlException(exception,OptionError,"NoImagesDefined",
14035           PackageName);
14036         goto PerlException;
14037       }
14038
14039     status=SyncAuthenticPixels(image,exception);
14040     if (status != MagickFalse)
14041       return;
14042
14043   PerlException:
14044     InheritPerlException(exception,perl_exception);
14045     exception=DestroyExceptionInfo(exception);
14046     SvREFCNT_dec(perl_exception);  /* throw away all errors */
14047   }
14048 \f
14049 #
14050 ###############################################################################
14051 #                                                                             #
14052 #                                                                             #
14053 #                                                                             #
14054 #   T r a n s f o r m                                                         #
14055 #                                                                             #
14056 #                                                                             #
14057 #                                                                             #
14058 ###############################################################################
14059 #
14060 #
14061 void
14062 Transform(ref,...)
14063   Image::Magick::Q16HDRI ref=NO_INIT
14064   ALIAS:
14065     TransformImage = 1
14066     transform      = 2
14067     transformimage = 3
14068   PPCODE:
14069   {
14070     AV
14071       *av;
14072
14073     char
14074       *attribute,
14075       *crop_geometry,
14076       *geometry;
14077
14078     ExceptionInfo
14079       *exception;
14080
14081     HV
14082       *hv;
14083
14084     Image
14085       *clone,
14086       *image;
14087
14088     register ssize_t
14089       i;
14090
14091     struct PackageInfo
14092       *info;
14093
14094     SV
14095       *av_reference,
14096       *perl_exception,
14097       *reference,
14098       *rv,
14099       *sv;
14100
14101     PERL_UNUSED_VAR(ref);
14102     PERL_UNUSED_VAR(ix);
14103     exception=AcquireExceptionInfo();
14104     perl_exception=newSVpv("",0);
14105     sv=NULL;
14106     av=NULL;
14107     attribute=NULL;
14108     if (sv_isobject(ST(0)) == 0)
14109       {
14110         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14111           PackageName);
14112         goto PerlException;
14113       }
14114     reference=SvRV(ST(0));
14115     hv=SvSTASH(reference);
14116     av=newAV();
14117     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14118     SvREFCNT_dec(av);
14119     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14120     if (image == (Image *) NULL)
14121       {
14122         ThrowPerlException(exception,OptionError,"NoImagesDefined",
14123           PackageName);
14124         goto PerlException;
14125       }
14126     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14127     /*
14128       Get attribute.
14129     */
14130     crop_geometry=(char *) NULL;
14131     geometry=(char *) NULL;
14132     for (i=2; i < items; i+=2)
14133     {
14134       attribute=(char *) SvPV(ST(i-1),na);
14135       switch (*attribute)
14136       {
14137         case 'c':
14138         case 'C':
14139         {
14140           if (LocaleCompare(attribute,"crop") == 0)
14141             {
14142               crop_geometry=SvPV(ST(i),na);
14143               break;
14144             }
14145           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14146             attribute);
14147           break;
14148         }
14149         case 'g':
14150         case 'G':
14151         {
14152           if (LocaleCompare(attribute,"geometry") == 0)
14153             {
14154               geometry=SvPV(ST(i),na);
14155               break;
14156             }
14157           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14158             attribute);
14159           break;
14160         }
14161         default:
14162         {
14163           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14164             attribute);
14165           break;
14166         }
14167       }
14168     }
14169     for ( ; image; image=image->next)
14170     {
14171       clone=CloneImage(image,0,0,MagickTrue,exception);
14172       if (clone == (Image *) NULL)
14173         goto PerlException;
14174       TransformImage(&clone,crop_geometry,geometry,exception);
14175       for ( ; clone; clone=clone->next)
14176       {
14177         AddImageToRegistry(sv,clone);
14178         rv=newRV(sv);
14179         av_push(av,sv_bless(rv,hv));
14180         SvREFCNT_dec(sv);
14181       }
14182     }
14183     exception=DestroyExceptionInfo(exception);
14184     ST(0)=av_reference;
14185     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
14186     XSRETURN(1);
14187
14188   PerlException:
14189     InheritPerlException(exception,perl_exception);
14190     exception=DestroyExceptionInfo(exception);
14191     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14192     SvPOK_on(perl_exception);
14193     ST(0)=sv_2mortal(perl_exception);
14194     XSRETURN(1);
14195   }
14196 \f
14197 #
14198 ###############################################################################
14199 #                                                                             #
14200 #                                                                             #
14201 #                                                                             #
14202 #   W r i t e                                                                 #
14203 #                                                                             #
14204 #                                                                             #
14205 #                                                                             #
14206 ###############################################################################
14207 #
14208 #
14209 void
14210 Write(ref,...)
14211   Image::Magick::Q16HDRI ref=NO_INIT
14212   ALIAS:
14213     WriteImage    = 1
14214     write         = 2
14215     writeimage    = 3
14216   PPCODE:
14217   {
14218     char
14219       filename[MaxTextExtent];
14220
14221     ExceptionInfo
14222       *exception;
14223
14224     Image
14225       *image,
14226       *next;
14227
14228     register ssize_t
14229       i;
14230
14231     ssize_t
14232       number_images,
14233       scene;
14234
14235     struct PackageInfo
14236       *info,
14237       *package_info;
14238
14239     SV
14240       *perl_exception,
14241       *reference;
14242
14243     PERL_UNUSED_VAR(ref);
14244     PERL_UNUSED_VAR(ix);
14245     exception=AcquireExceptionInfo();
14246     perl_exception=newSVpv("",0);
14247     number_images=0;
14248     package_info=(struct PackageInfo *) NULL;
14249     if (sv_isobject(ST(0)) == 0)
14250       {
14251         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14252           PackageName);
14253         goto PerlException;
14254       }
14255     reference=SvRV(ST(0));
14256     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14257     if (image == (Image *) NULL)
14258       {
14259         ThrowPerlException(exception,OptionError,"NoImagesDefined",
14260           PackageName);
14261         goto PerlException;
14262       }
14263     package_info=ClonePackageInfo(info,exception);
14264     if (items == 2)
14265       SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14266     else
14267       if (items > 2)
14268         for (i=2; i < items; i+=2)
14269           SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14270             exception);
14271     (void) CopyMagickString(filename,package_info->image_info->filename,
14272       MaxTextExtent);
14273     scene=0;
14274     for (next=image; next; next=next->next)
14275     {
14276       (void) CopyMagickString(next->filename,filename,MaxTextExtent);
14277       next->scene=scene++;
14278     }
14279     SetImageInfo(package_info->image_info,(unsigned int)
14280       GetImageListLength(image),exception);
14281     for (next=image; next; next=next->next)
14282     {
14283       (void) WriteImage(package_info->image_info,next,exception);
14284       number_images++;
14285       if (package_info->image_info->adjoin)
14286         break;
14287     }
14288
14289   PerlException:
14290     if (package_info != (struct PackageInfo *) NULL)
14291       DestroyPackageInfo(package_info);
14292     InheritPerlException(exception,perl_exception);
14293     exception=DestroyExceptionInfo(exception);
14294     sv_setiv(perl_exception,(IV) number_images);
14295     SvPOK_on(perl_exception);
14296     ST(0)=sv_2mortal(perl_exception);
14297     XSRETURN(1);
14298   }