]> granicus.if.org Git - imagemagick/blob - PerlMagick/quantum/quantum.xs
54494bbb8d20d0f77553d249c8768ec3b5b66bb0
[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,geometry_info.sigma,
7791             exception);
7792           break;
7793         }
7794         case 11:  /* Emboss */
7795         {
7796           if (attribute_flag[0] != 0)
7797             {
7798               flags=ParseGeometry(argument_list[0].string_reference,
7799                 &geometry_info);
7800               if ((flags & SigmaValue) == 0)
7801                 geometry_info.sigma=1.0;
7802             }
7803           if (attribute_flag[1] != 0)
7804             geometry_info.rho=argument_list[1].real_reference;
7805           if (attribute_flag[2] != 0)
7806             geometry_info.sigma=argument_list[2].real_reference;
7807           image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
7808             exception);
7809           break;
7810         }
7811         case 12:  /* Enhance */
7812         {
7813           image=EnhanceImage(image,exception);
7814           break;
7815         }
7816         case 13:  /* Flip */
7817         {
7818           image=FlipImage(image,exception);
7819           break;
7820         }
7821         case 14:  /* Flop */
7822         {
7823           image=FlopImage(image,exception);
7824           break;
7825         }
7826         case 15:  /* Frame */
7827         {
7828           CompositeOperator
7829             compose;
7830
7831           FrameInfo
7832             frame_info;
7833
7834           if (attribute_flag[0] != 0)
7835             {
7836               flags=ParsePageGeometry(image,argument_list[0].string_reference,
7837                 &geometry,exception);
7838               frame_info.width=geometry.width;
7839               frame_info.height=geometry.height;
7840               frame_info.outer_bevel=geometry.x;
7841               frame_info.inner_bevel=geometry.y;
7842             }
7843           if (attribute_flag[1] != 0)
7844             frame_info.width=argument_list[1].integer_reference;
7845           if (attribute_flag[2] != 0)
7846             frame_info.height=argument_list[2].integer_reference;
7847           if (attribute_flag[3] != 0)
7848             frame_info.inner_bevel=argument_list[3].integer_reference;
7849           if (attribute_flag[4] != 0)
7850             frame_info.outer_bevel=argument_list[4].integer_reference;
7851           if (attribute_flag[5] != 0)
7852             QueryColorCompliance(argument_list[5].string_reference,
7853               AllCompliance,&fill_color,exception);
7854           if (attribute_flag[6] != 0)
7855             QueryColorCompliance(argument_list[6].string_reference,
7856               AllCompliance,&fill_color,exception);
7857           frame_info.x=(ssize_t) frame_info.width;
7858           frame_info.y=(ssize_t) frame_info.height;
7859           frame_info.width=image->columns+2*frame_info.x;
7860           frame_info.height=image->rows+2*frame_info.y;
7861           if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
7862             image->matte_color=fill_color;
7863           compose=image->compose;
7864           if (attribute_flag[7] != 0)
7865             compose=(CompositeOperator) argument_list[7].integer_reference;
7866           image=FrameImage(image,&frame_info,compose,exception);
7867           break;
7868         }
7869         case 16:  /* Implode */
7870         {
7871           PixelInterpolateMethod
7872             method;
7873
7874           if (attribute_flag[0] == 0)
7875             argument_list[0].real_reference=0.5;
7876           method=UndefinedInterpolatePixel;
7877           if (attribute_flag[1] != 0)
7878             method=(PixelInterpolateMethod) argument_list[1].integer_reference;
7879           image=ImplodeImage(image,argument_list[0].real_reference,
7880             method,exception);
7881           break;
7882         }
7883         case 17:  /* Magnify */
7884         {
7885           image=MagnifyImage(image,exception);
7886           break;
7887         }
7888         case 18:  /* MedianFilter */
7889         {
7890           if (attribute_flag[0] != 0)
7891             {
7892               flags=ParseGeometry(argument_list[0].string_reference,
7893                 &geometry_info);
7894               if ((flags & SigmaValue) == 0)
7895                 geometry_info.sigma=geometry_info.rho;
7896             }
7897           if (attribute_flag[1] != 0)
7898             geometry_info.rho=argument_list[1].real_reference;
7899           if (attribute_flag[2] != 0)
7900             geometry_info.sigma=argument_list[2].real_reference;
7901           if (attribute_flag[3] != 0)
7902             channel=(ChannelType) argument_list[3].integer_reference;
7903           channel_mask=SetImageChannelMask(image,channel);
7904           image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
7905             (size_t) geometry_info.sigma,exception);
7906           if (image != (Image *) NULL)
7907             (void) SetImageChannelMask(image,channel_mask);
7908           break;
7909         }
7910         case 19:  /* Minify */
7911         {
7912           image=MinifyImage(image,exception);
7913           break;
7914         }
7915         case 20:  /* OilPaint */
7916         {
7917           if (attribute_flag[0] == 0)
7918             argument_list[0].real_reference=0.0;
7919           if (attribute_flag[1] == 0)
7920             argument_list[1].real_reference=1.0;
7921           image=OilPaintImage(image,argument_list[0].real_reference,
7922             argument_list[1].real_reference,exception);
7923           break;
7924         }
7925         case 21:  /* ReduceNoise */
7926         {
7927           if (attribute_flag[0] != 0)
7928             {
7929               flags=ParseGeometry(argument_list[0].string_reference,
7930                 &geometry_info);
7931               if ((flags & SigmaValue) == 0)
7932                 geometry_info.sigma=1.0;
7933             }
7934           if (attribute_flag[1] != 0)
7935             geometry_info.rho=argument_list[1].real_reference;
7936           if (attribute_flag[2] != 0)
7937             geometry_info.sigma=argument_list[2].real_reference;
7938           if (attribute_flag[3] != 0)
7939             channel=(ChannelType) argument_list[3].integer_reference;
7940           channel_mask=SetImageChannelMask(image,channel);
7941           image=StatisticImage(image,NonpeakStatistic,(size_t)
7942             geometry_info.rho,(size_t) geometry_info.sigma,exception);
7943           if (image != (Image *) NULL)
7944             (void) SetImageChannelMask(image,channel_mask);
7945           break;
7946         }
7947         case 22:  /* Roll */
7948         {
7949           if (attribute_flag[0] != 0)
7950             flags=ParsePageGeometry(image,argument_list[0].string_reference,
7951               &geometry,exception);
7952           if (attribute_flag[1] != 0)
7953             geometry.x=argument_list[1].integer_reference;
7954           if (attribute_flag[2] != 0)
7955             geometry.y=argument_list[2].integer_reference;
7956           image=RollImage(image,geometry.x,geometry.y,exception);
7957           break;
7958         }
7959         case 23:  /* Rotate */
7960         {
7961           if (attribute_flag[0] == 0)
7962             argument_list[0].real_reference=90.0;
7963           if (attribute_flag[1] != 0)
7964             {
7965               QueryColorCompliance(argument_list[1].string_reference,
7966                 AllCompliance,&image->background_color,exception);
7967               if ((image->background_color.alpha_trait == BlendPixelTrait) &&
7968                   (image->alpha_trait != BlendPixelTrait))
7969                 (void) SetImageAlpha(image,OpaqueAlpha,exception);
7970             }
7971           image=RotateImage(image,argument_list[0].real_reference,exception);
7972           break;
7973         }
7974         case 24:  /* Sample */
7975         {
7976           if (attribute_flag[0] != 0)
7977             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
7978               &geometry,exception);
7979           if (attribute_flag[1] != 0)
7980             geometry.width=argument_list[1].integer_reference;
7981           if (attribute_flag[2] != 0)
7982             geometry.height=argument_list[2].integer_reference;
7983           image=SampleImage(image,geometry.width,geometry.height,exception);
7984           break;
7985         }
7986         case 25:  /* Scale */
7987         {
7988           if (attribute_flag[0] != 0)
7989             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
7990               &geometry,exception);
7991           if (attribute_flag[1] != 0)
7992             geometry.width=argument_list[1].integer_reference;
7993           if (attribute_flag[2] != 0)
7994             geometry.height=argument_list[2].integer_reference;
7995           image=ScaleImage(image,geometry.width,geometry.height,exception);
7996           break;
7997         }
7998         case 26:  /* Shade */
7999         {
8000           if (attribute_flag[0] != 0)
8001             {
8002               flags=ParseGeometry(argument_list[0].string_reference,
8003                 &geometry_info);
8004               if ((flags & SigmaValue) == 0)
8005                 geometry_info.sigma=0.0;
8006             }
8007           if (attribute_flag[1] != 0)
8008             geometry_info.rho=argument_list[1].real_reference;
8009           if (attribute_flag[2] != 0)
8010             geometry_info.sigma=argument_list[2].real_reference;
8011           image=ShadeImage(image,
8012             argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8013             geometry_info.rho,geometry_info.sigma,exception);
8014           break;
8015         }
8016         case 27:  /* Sharpen */
8017         {
8018           if (attribute_flag[0] != 0)
8019             {
8020               flags=ParseGeometry(argument_list[0].string_reference,
8021                 &geometry_info);
8022               if ((flags & SigmaValue) == 0)
8023                 geometry_info.sigma=1.0;
8024             }
8025           if (attribute_flag[1] != 0)
8026             geometry_info.rho=argument_list[1].real_reference;
8027           if (attribute_flag[2] != 0)
8028             geometry_info.sigma=argument_list[2].real_reference;
8029           if (attribute_flag[3] != 0)
8030             channel=(ChannelType) argument_list[3].integer_reference;
8031           channel_mask=SetImageChannelMask(image,channel);
8032           image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8033             exception);
8034           if (image != (Image *) NULL)
8035             (void) SetImageChannelMask(image,channel_mask);
8036           break;
8037         }
8038         case 28:  /* Shear */
8039         {
8040           if (attribute_flag[0] != 0)
8041             {
8042               flags=ParseGeometry(argument_list[0].string_reference,
8043                 &geometry_info);
8044               if ((flags & SigmaValue) == 0)
8045                 geometry_info.sigma=geometry_info.rho;
8046             }
8047           if (attribute_flag[1] != 0)
8048             geometry_info.rho=argument_list[1].real_reference;
8049           if (attribute_flag[2] != 0)
8050             geometry_info.sigma=argument_list[2].real_reference;
8051           if (attribute_flag[3] != 0)
8052             QueryColorCompliance(argument_list[3].string_reference,
8053               AllCompliance,&image->background_color,exception);
8054           if (attribute_flag[4] != 0)
8055             QueryColorCompliance(argument_list[4].string_reference,
8056               AllCompliance,&image->background_color,exception);
8057           image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8058             exception);
8059           break;
8060         }
8061         case 29:  /* Spread */
8062         {
8063           PixelInterpolateMethod
8064             method;
8065
8066           if (attribute_flag[0] == 0)
8067             argument_list[0].real_reference=1.0;
8068           method=UndefinedInterpolatePixel;
8069           if (attribute_flag[1] != 0)
8070             method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8071           image=SpreadImage(image,argument_list[0].real_reference,method,
8072             exception);
8073           break;
8074         }
8075         case 30:  /* Swirl */
8076         {
8077           PixelInterpolateMethod
8078             method;
8079
8080           if (attribute_flag[0] == 0)
8081             argument_list[0].real_reference=50.0;
8082           method=UndefinedInterpolatePixel;
8083           if (attribute_flag[1] != 0)
8084             method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8085           image=SwirlImage(image,argument_list[0].real_reference,
8086             method,exception);
8087           break;
8088         }
8089         case 31:  /* Resize */
8090         case 32:  /* Zoom */
8091         {
8092           if (attribute_flag[0] != 0)
8093             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8094               &geometry,exception);
8095           if (attribute_flag[1] != 0)
8096             geometry.width=argument_list[1].integer_reference;
8097           if (attribute_flag[2] != 0)
8098             geometry.height=argument_list[2].integer_reference;
8099           if (attribute_flag[3] == 0)
8100             argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8101           if (attribute_flag[4] != 0)
8102             SetImageArtifact(image,"filter:support",
8103               argument_list[4].string_reference);
8104           image=ResizeImage(image,geometry.width,geometry.height,
8105             (FilterTypes) argument_list[3].integer_reference,
8106             exception);
8107           break;
8108         }
8109         case 33:  /* Annotate */
8110         {
8111           DrawInfo
8112             *draw_info;
8113
8114           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8115             (DrawInfo *) NULL);
8116           if (attribute_flag[0] != 0)
8117             {
8118               char
8119                 *text;
8120
8121               text=InterpretImageProperties(info ? info->image_info :
8122                 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8123                 exception);
8124               (void) CloneString(&draw_info->text,text);
8125               text=DestroyString(text);
8126             }
8127           if (attribute_flag[1] != 0)
8128             (void) CloneString(&draw_info->font,
8129               argument_list[1].string_reference);
8130           if (attribute_flag[2] != 0)
8131             draw_info->pointsize=argument_list[2].real_reference;
8132           if (attribute_flag[3] != 0)
8133             (void) CloneString(&draw_info->density,
8134               argument_list[3].string_reference);
8135           if (attribute_flag[4] != 0)
8136             (void) QueryColorCompliance(argument_list[4].string_reference,
8137               AllCompliance,&draw_info->undercolor,exception);
8138           if (attribute_flag[5] != 0)
8139             {
8140               (void) QueryColorCompliance(argument_list[5].string_reference,
8141                 AllCompliance,&draw_info->stroke,exception);
8142               if (argument_list[5].image_reference != (Image *) NULL)
8143                 draw_info->stroke_pattern=CloneImage(
8144                   argument_list[5].image_reference,0,0,MagickTrue,exception);
8145             }
8146           if (attribute_flag[6] != 0)
8147             {
8148               (void) QueryColorCompliance(argument_list[6].string_reference,
8149                 AllCompliance,&draw_info->fill,exception);
8150               if (argument_list[6].image_reference != (Image *) NULL)
8151                 draw_info->fill_pattern=CloneImage(
8152                   argument_list[6].image_reference,0,0,MagickTrue,exception);
8153             }
8154           if (attribute_flag[7] != 0)
8155             {
8156               (void) CloneString(&draw_info->geometry,
8157                 argument_list[7].string_reference);
8158               flags=ParsePageGeometry(image,argument_list[7].string_reference,
8159                 &geometry,exception);
8160               if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8161                 geometry_info.sigma=geometry_info.xi;
8162             }
8163           if (attribute_flag[8] != 0)
8164             (void) QueryColorCompliance(argument_list[8].string_reference,
8165               AllCompliance,&draw_info->fill,exception);
8166           if (attribute_flag[11] != 0)
8167             draw_info->gravity=(GravityType)
8168               argument_list[11].integer_reference;
8169           if (attribute_flag[25] != 0)
8170             {
8171               AV
8172                 *av;
8173
8174               av=(AV *) argument_list[25].array_reference;
8175               if ((av_len(av) != 3) && (av_len(av) != 5))
8176                 {
8177                   ThrowPerlException(exception,OptionError,
8178                     "affine matrix must have 4 or 6 elements",PackageName);
8179                   goto PerlException;
8180                 }
8181               draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8182               draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8183               draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8184               draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8185               if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8186                   draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8187                 {
8188                   ThrowPerlException(exception,OptionError,
8189                     "affine matrix is singular",PackageName);
8190                    goto PerlException;
8191                 }
8192               if (av_len(av) == 5)
8193                 {
8194                   draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8195                   draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8196                 }
8197             }
8198           for (j=12; j < 17; j++)
8199           {
8200             if (attribute_flag[j] == 0)
8201               continue;
8202             value=argument_list[j].string_reference;
8203             angle=argument_list[j].real_reference;
8204             current=draw_info->affine;
8205             GetAffineMatrix(&affine);
8206             switch (j)
8207             {
8208               case 12:
8209               {
8210                 /*
8211                   Translate.
8212                 */
8213                 flags=ParseGeometry(value,&geometry_info);
8214                 affine.tx=geometry_info.xi;
8215                 affine.ty=geometry_info.psi;
8216                 if ((flags & PsiValue) == 0)
8217                   affine.ty=affine.tx;
8218                 break;
8219               }
8220               case 13:
8221               {
8222                 /*
8223                   Scale.
8224                 */
8225                 flags=ParseGeometry(value,&geometry_info);
8226                 affine.sx=geometry_info.rho;
8227                 affine.sy=geometry_info.sigma;
8228                 if ((flags & SigmaValue) == 0)
8229                   affine.sy=affine.sx;
8230                 break;
8231               }
8232               case 14:
8233               {
8234                 /*
8235                   Rotate.
8236                 */
8237                 if (angle == 0.0)
8238                   break;
8239                 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8240                 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8241                 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8242                 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8243                 break;
8244               }
8245               case 15:
8246               {
8247                 /*
8248                   SkewX.
8249                 */
8250                 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8251                 break;
8252               }
8253               case 16:
8254               {
8255                 /*
8256                   SkewY.
8257                 */
8258                 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8259                 break;
8260               }
8261             }
8262             draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8263             draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8264             draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8265             draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8266             draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8267               current.tx;
8268             draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8269               current.ty;
8270           }
8271           if (attribute_flag[9] == 0)
8272             argument_list[9].real_reference=0.0;
8273           if (attribute_flag[10] == 0)
8274             argument_list[10].real_reference=0.0;
8275           if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8276             {
8277               char
8278                 geometry[MaxTextExtent];
8279
8280               (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
8281                 (double) argument_list[9].real_reference+draw_info->affine.tx,
8282                 (double) argument_list[10].real_reference+draw_info->affine.ty);
8283               (void) CloneString(&draw_info->geometry,geometry);
8284             }
8285           if (attribute_flag[17] != 0)
8286             draw_info->stroke_width=argument_list[17].real_reference;
8287           if (attribute_flag[18] != 0)
8288             {
8289               draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8290                 MagickTrue : MagickFalse;
8291               draw_info->stroke_antialias=draw_info->text_antialias;
8292             }
8293           if (attribute_flag[19] != 0)
8294             (void) CloneString(&draw_info->family,
8295               argument_list[19].string_reference);
8296           if (attribute_flag[20] != 0)
8297             draw_info->style=(StyleType) argument_list[20].integer_reference;
8298           if (attribute_flag[21] != 0)
8299             draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8300           if (attribute_flag[22] != 0)
8301             draw_info->weight=argument_list[22].integer_reference;
8302           if (attribute_flag[23] != 0)
8303             draw_info->align=(AlignType) argument_list[23].integer_reference;
8304           if (attribute_flag[24] != 0)
8305             (void) CloneString(&draw_info->encoding,
8306               argument_list[24].string_reference);
8307           if (attribute_flag[25] != 0)
8308             draw_info->fill_pattern=CloneImage(
8309               argument_list[25].image_reference,0,0,MagickTrue,exception);
8310           if (attribute_flag[26] != 0)
8311             draw_info->fill_pattern=CloneImage(
8312               argument_list[26].image_reference,0,0,MagickTrue,exception);
8313           if (attribute_flag[27] != 0)
8314             draw_info->stroke_pattern=CloneImage(
8315               argument_list[27].image_reference,0,0,MagickTrue,exception);
8316           if (attribute_flag[29] != 0)
8317             draw_info->kerning=argument_list[29].real_reference;
8318           if (attribute_flag[30] != 0)
8319             draw_info->interline_spacing=argument_list[30].real_reference;
8320           if (attribute_flag[31] != 0)
8321             draw_info->interword_spacing=argument_list[31].real_reference;
8322           if (attribute_flag[32] != 0)
8323             draw_info->direction=(DirectionType)
8324               argument_list[32].integer_reference;
8325           (void) AnnotateImage(image,draw_info,exception);
8326           draw_info=DestroyDrawInfo(draw_info);
8327           break;
8328         }
8329         case 34:  /* ColorFloodfill */
8330         {
8331           DrawInfo
8332             *draw_info;
8333
8334           MagickBooleanType
8335             invert;
8336
8337           PixelInfo
8338             target;
8339
8340           draw_info=CloneDrawInfo(info ? info->image_info :
8341             (ImageInfo *) NULL,(DrawInfo *) NULL);
8342           if (attribute_flag[0] != 0)
8343             flags=ParsePageGeometry(image,argument_list[0].string_reference,
8344               &geometry,exception);
8345           if (attribute_flag[1] != 0)
8346             geometry.x=argument_list[1].integer_reference;
8347           if (attribute_flag[2] != 0)
8348             geometry.y=argument_list[2].integer_reference;
8349           if (attribute_flag[3] != 0)
8350             (void) QueryColorCompliance(argument_list[3].string_reference,
8351               AllCompliance,&draw_info->fill,exception);
8352           (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8353             geometry.x,geometry.y,&target,exception);
8354           invert=MagickFalse;
8355           if (attribute_flag[4] != 0)
8356             {
8357               QueryColorCompliance(argument_list[4].string_reference,
8358                 AllCompliance,&target,exception);
8359               invert=MagickTrue;
8360             }
8361           if (attribute_flag[5] != 0)
8362             image->fuzz=StringToDoubleInterval(
8363               argument_list[5].string_reference,(double) QuantumRange+1.0);
8364           if (attribute_flag[6] != 0)
8365             invert=(MagickBooleanType) argument_list[6].integer_reference;
8366           (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8367             geometry.y,invert,exception);
8368           draw_info=DestroyDrawInfo(draw_info);
8369           break;
8370         }
8371         case 35:  /* Composite */
8372         {
8373           char
8374             composite_geometry[MaxTextExtent];
8375
8376           Image
8377             *composite_image,
8378             *rotate_image;
8379
8380           MagickBooleanType
8381             clip_to_self;
8382
8383           compose=OverCompositeOp;
8384           if (attribute_flag[0] != 0)
8385             composite_image=argument_list[0].image_reference;
8386           else
8387             {
8388               ThrowPerlException(exception,OptionError,
8389                 "CompositeImageRequired",PackageName);
8390               goto PerlException;
8391             }
8392           /*
8393             Parameter Handling used for BOTH normal and tiled composition.
8394           */
8395           if (attribute_flag[1] != 0) /* compose */
8396             compose=(CompositeOperator) argument_list[1].integer_reference;
8397           if (attribute_flag[6] != 0) /* opacity  */
8398             {
8399               if (compose != DissolveCompositeOp)
8400                 (void) SetImageAlpha(composite_image,(Quantum)
8401                   StringToDoubleInterval(argument_list[6].string_reference,
8402                   (double) QuantumRange+1.0),exception);
8403               else
8404                 {
8405                   CacheView
8406                     *composite_view;
8407
8408                   double
8409                     opacity;
8410
8411                   MagickBooleanType
8412                     sync;
8413
8414                   register ssize_t
8415                     x;
8416
8417                   register Quantum
8418                     *q;
8419
8420                   ssize_t
8421                     y;
8422
8423                   /*
8424                     Handle dissolve composite operator (patch by
8425                     Kevin A. McGrail).
8426                   */
8427                   (void) CloneString(&image->geometry,
8428                     argument_list[6].string_reference);
8429                   opacity=(Quantum) StringToDoubleInterval(
8430                     argument_list[6].string_reference,(double) QuantumRange+
8431                     1.0);
8432                   if (composite_image->alpha_trait == BlendPixelTrait)
8433                     (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8434                   composite_view=AcquireAuthenticCacheView(composite_image,exception);
8435                   for (y=0; y < (ssize_t) composite_image->rows ; y++)
8436                   {
8437                     q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8438                       composite_image->columns,1,exception);
8439                     for (x=0; x < (ssize_t) composite_image->columns; x++)
8440                     {
8441                       if (GetPixelAlpha(image,q) == OpaqueAlpha)
8442                         SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8443                           q);
8444                       q+=GetPixelChannels(composite_image);
8445                     }
8446                     sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8447                     if (sync == MagickFalse)
8448                       break;
8449                   }
8450                   composite_view=DestroyCacheView(composite_view);
8451                 }
8452             }
8453           if (attribute_flag[9] != 0)    /* "color=>" */
8454             QueryColorCompliance(argument_list[9].string_reference,
8455               AllCompliance,&composite_image->background_color,exception);
8456           if (attribute_flag[12] != 0) /* "interpolate=>" */
8457             image->interpolate=(PixelInterpolateMethod)
8458               argument_list[12].integer_reference;
8459           if (attribute_flag[13] != 0)   /* "args=>" */
8460             (void) SetImageArtifact(composite_image,"compose:args",
8461               argument_list[13].string_reference);
8462           if (attribute_flag[14] != 0)   /* "blend=>"  depreciated */
8463             (void) SetImageArtifact(composite_image,"compose:args",
8464               argument_list[14].string_reference);
8465           clip_to_self=MagickTrue;
8466           if (attribute_flag[15] != 0)
8467             clip_to_self=(MagickBooleanType)
8468               argument_list[15].integer_reference;
8469           /*
8470             Tiling Composition (with orthogonal rotate).
8471           */
8472           rotate_image=(Image *) NULL;
8473           if (attribute_flag[8] != 0)   /* "rotate=>" */
8474             {
8475                /*
8476                  Rotate image.
8477                */
8478                rotate_image=RotateImage(composite_image,
8479                  argument_list[8].real_reference,exception);
8480                if (rotate_image == (Image *) NULL)
8481                  break;
8482             }
8483           if ((attribute_flag[7] != 0) &&
8484               (argument_list[7].integer_reference != 0)) /* tile */
8485             {
8486               ssize_t
8487                 x,
8488                 y;
8489
8490               /*
8491                 Tile the composite image.
8492               */
8493              if (attribute_flag[8] != 0)   /* "tile=>" */
8494                (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
8495                  "false");
8496              else
8497                (void) SetImageArtifact(composite_image,
8498                  "compose:outside-overlay","false");
8499              for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8500                 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8501                 {
8502                   if (attribute_flag[8] != 0) /* rotate */
8503                     (void) CompositeImage(image,rotate_image,compose,
8504                       MagickTrue,x,y,exception);
8505                   else
8506                     (void) CompositeImage(image,composite_image,compose,
8507                       MagickTrue,x,y,exception);
8508                 }
8509               if (attribute_flag[8] != 0) /* rotate */
8510                 rotate_image=DestroyImage(rotate_image);
8511               break;
8512             }
8513           /*
8514             Parameter Handling used used ONLY for normal composition.
8515           */
8516           if (attribute_flag[5] != 0) /* gravity */
8517             image->gravity=(GravityType) argument_list[5].integer_reference;
8518           if (attribute_flag[2] != 0) /* geometry offset */
8519             {
8520               SetGeometry(image,&geometry);
8521               (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8522                 &geometry);
8523               GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8524                 &geometry);
8525             }
8526           if (attribute_flag[3] != 0) /* x offset */
8527             geometry.x=argument_list[3].integer_reference;
8528           if (attribute_flag[4] != 0) /* y offset */
8529             geometry.y=argument_list[4].integer_reference;
8530           if (attribute_flag[10] != 0) /* mask */
8531             {
8532               if ((image->compose == DisplaceCompositeOp) ||
8533                   (image->compose == DistortCompositeOp))
8534                 {
8535                   /*
8536                     Merge Y displacement into X displacement image.
8537                   */
8538                   composite_image=CloneImage(composite_image,0,0,MagickTrue,
8539                     exception);
8540                   (void) CompositeImage(composite_image,
8541                     argument_list[10].image_reference,CopyGreenCompositeOp,
8542                     MagickTrue,0,0,exception);
8543                 }
8544               else
8545                 {
8546                   Image
8547                     *mask_image;
8548
8549                   /*
8550                     Set a blending mask for the composition.
8551                   */
8552                   mask_image=CloneImage(argument_list[10].image_reference,0,0,
8553                     MagickTrue,exception);
8554                   (void) NegateImage(mask_image,MagickFalse,exception);
8555                   (void) SetImageMask(composite_image,mask_image,exception);
8556                   mask_image=DestroyImage(mask_image);
8557                 }
8558             }
8559           if (attribute_flag[11] != 0) /* channel */
8560             channel=(ChannelType) argument_list[11].integer_reference;
8561           /*
8562             Composite two images (normal composition).
8563           */
8564           (void) FormatLocaleString(composite_geometry,MaxTextExtent,
8565             "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8566             (double) composite_image->rows,(double) geometry.x,(double)
8567             geometry.y);
8568           flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8569             exception);
8570           channel_mask=SetImageChannelMask(image,channel);
8571           if (attribute_flag[8] == 0) /* no rotate */
8572             CompositeImage(image,composite_image,compose,clip_to_self,
8573               geometry.x,geometry.y,exception);
8574           else
8575             {
8576               /*
8577                 Position adjust rotated image then composite.
8578               */
8579               geometry.x-=(ssize_t) (rotate_image->columns-
8580                 composite_image->columns)/2;
8581               geometry.y-=(ssize_t) (rotate_image->rows-
8582                 composite_image->rows)/2;
8583               CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8584                 geometry.y,exception);
8585               rotate_image=DestroyImage(rotate_image);
8586             }
8587           if (attribute_flag[10] != 0) /* mask */
8588             {
8589               if ((image->compose == DisplaceCompositeOp) ||
8590                   (image->compose == DistortCompositeOp))
8591                 composite_image=DestroyImage(composite_image);
8592               else
8593                 (void) SetImageMask(image,(Image *) NULL,exception);
8594             }
8595           (void) SetImageChannelMask(image,channel_mask);
8596           break;
8597         }
8598         case 36:  /* Contrast */
8599         {
8600           if (attribute_flag[0] == 0)
8601             argument_list[0].integer_reference=0;
8602           (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8603             MagickTrue : MagickFalse,exception);
8604           break;
8605         }
8606         case 37:  /* CycleColormap */
8607         {
8608           if (attribute_flag[0] == 0)
8609             argument_list[0].integer_reference=6;
8610           (void) CycleColormapImage(image,argument_list[0].integer_reference,
8611             exception);
8612           break;
8613         }
8614         case 38:  /* Draw */
8615         {
8616           DrawInfo
8617             *draw_info;
8618
8619           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8620             (DrawInfo *) NULL);
8621           (void) CloneString(&draw_info->primitive,"point");
8622           if (attribute_flag[0] != 0)
8623             {
8624               if (argument_list[0].integer_reference < 0)
8625                 (void) CloneString(&draw_info->primitive,
8626                   argument_list[0].string_reference);
8627               else
8628                 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8629                   MagickPrimitiveOptions,argument_list[0].integer_reference));
8630             }
8631           if (attribute_flag[1] != 0)
8632             {
8633               if (LocaleCompare(draw_info->primitive,"path") == 0)
8634                 {
8635                   (void) ConcatenateString(&draw_info->primitive," '");
8636                   ConcatenateString(&draw_info->primitive,
8637                     argument_list[1].string_reference);
8638                   (void) ConcatenateString(&draw_info->primitive,"'");
8639                 }
8640               else
8641                 {
8642                   (void) ConcatenateString(&draw_info->primitive," ");
8643                   ConcatenateString(&draw_info->primitive,
8644                     argument_list[1].string_reference);
8645                 }
8646             }
8647           if (attribute_flag[2] != 0)
8648             {
8649               (void) ConcatenateString(&draw_info->primitive," ");
8650               (void) ConcatenateString(&draw_info->primitive,
8651                 CommandOptionToMnemonic(MagickMethodOptions,
8652                 argument_list[2].integer_reference));
8653             }
8654           if (attribute_flag[3] != 0)
8655             {
8656               (void) QueryColorCompliance(argument_list[3].string_reference,
8657                 AllCompliance,&draw_info->stroke,exception);
8658               if (argument_list[3].image_reference != (Image *) NULL)
8659                 draw_info->stroke_pattern=CloneImage(
8660                   argument_list[3].image_reference,0,0,MagickTrue,exception);
8661             }
8662           if (attribute_flag[4] != 0)
8663             {
8664               (void) QueryColorCompliance(argument_list[4].string_reference,
8665                 AllCompliance,&draw_info->fill,exception);
8666               if (argument_list[4].image_reference != (Image *) NULL)
8667                 draw_info->fill_pattern=CloneImage(
8668                   argument_list[4].image_reference,0,0,MagickTrue,exception);
8669             }
8670           if (attribute_flag[5] != 0)
8671             draw_info->stroke_width=argument_list[5].real_reference;
8672           if (attribute_flag[6] != 0)
8673             (void) CloneString(&draw_info->font,
8674               argument_list[6].string_reference);
8675           if (attribute_flag[7] != 0)
8676             (void) QueryColorCompliance(argument_list[7].string_reference,
8677               AllCompliance,&draw_info->border_color,exception);
8678           if (attribute_flag[8] != 0)
8679             draw_info->affine.tx=argument_list[8].real_reference;
8680           if (attribute_flag[9] != 0)
8681             draw_info->affine.ty=argument_list[9].real_reference;
8682           if (attribute_flag[20] != 0)
8683             {
8684               AV
8685                 *av;
8686
8687               av=(AV *) argument_list[20].array_reference;
8688               if ((av_len(av) != 3) && (av_len(av) != 5))
8689                 {
8690                   ThrowPerlException(exception,OptionError,
8691                     "affine matrix must have 4 or 6 elements",PackageName);
8692                   goto PerlException;
8693                 }
8694               draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8695               draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8696               draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8697               draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8698               if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8699                   draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8700                 {
8701                   ThrowPerlException(exception,OptionError,
8702                     "affine matrix is singular",PackageName);
8703                    goto PerlException;
8704                 }
8705               if (av_len(av) == 5)
8706                 {
8707                   draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8708                   draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8709                 }
8710             }
8711           for (j=10; j < 15; j++)
8712           {
8713             if (attribute_flag[j] == 0)
8714               continue;
8715             value=argument_list[j].string_reference;
8716             angle=argument_list[j].real_reference;
8717             current=draw_info->affine;
8718             GetAffineMatrix(&affine);
8719             switch (j)
8720             {
8721               case 10:
8722               {
8723                 /*
8724                   Translate.
8725                 */
8726                 flags=ParseGeometry(value,&geometry_info);
8727                 affine.tx=geometry_info.xi;
8728                 affine.ty=geometry_info.psi;
8729                 if ((flags & PsiValue) == 0)
8730                   affine.ty=affine.tx;
8731                 break;
8732               }
8733               case 11:
8734               {
8735                 /*
8736                   Scale.
8737                 */
8738                 flags=ParseGeometry(value,&geometry_info);
8739                 affine.sx=geometry_info.rho;
8740                 affine.sy=geometry_info.sigma;
8741                 if ((flags & SigmaValue) == 0)
8742                   affine.sy=affine.sx;
8743                 break;
8744               }
8745               case 12:
8746               {
8747                 /*
8748                   Rotate.
8749                 */
8750                 if (angle == 0.0)
8751                   break;
8752                 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8753                 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8754                 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8755                 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8756                 break;
8757               }
8758               case 13:
8759               {
8760                 /*
8761                   SkewX.
8762                 */
8763                 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8764                 break;
8765               }
8766               case 14:
8767               {
8768                 /*
8769                   SkewY.
8770                 */
8771                 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8772                 break;
8773               }
8774             }
8775             draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8776             draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8777             draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8778             draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8779             draw_info->affine.tx=
8780               current.sx*affine.tx+current.ry*affine.ty+current.tx;
8781             draw_info->affine.ty=
8782               current.rx*affine.tx+current.sy*affine.ty+current.ty;
8783           }
8784           if (attribute_flag[15] != 0)
8785             draw_info->fill_pattern=CloneImage(
8786               argument_list[15].image_reference,0,0,MagickTrue,exception);
8787           if (attribute_flag[16] != 0)
8788             draw_info->pointsize=argument_list[16].real_reference;
8789           if (attribute_flag[17] != 0)
8790             {
8791               draw_info->stroke_antialias=argument_list[17].integer_reference != 0
8792                 ? MagickTrue : MagickFalse;
8793               draw_info->text_antialias=draw_info->stroke_antialias;
8794             }
8795           if (attribute_flag[18] != 0)
8796             (void) CloneString(&draw_info->density,
8797               argument_list[18].string_reference);
8798           if (attribute_flag[19] != 0)
8799             draw_info->stroke_width=argument_list[19].real_reference;
8800           if (attribute_flag[21] != 0)
8801             draw_info->dash_offset=argument_list[21].real_reference;
8802           if (attribute_flag[22] != 0)
8803             {
8804               AV
8805                 *av;
8806
8807               av=(AV *) argument_list[22].array_reference;
8808               draw_info->dash_pattern=(double *) AcquireQuantumMemory(
8809                 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
8810               if (draw_info->dash_pattern != (double *) NULL)
8811                 {
8812                   for (i=0; i <= av_len(av); i++)
8813                     draw_info->dash_pattern[i]=(double)
8814                       SvNV(*(av_fetch(av,i,0)));
8815                   draw_info->dash_pattern[i]=0.0;
8816                 }
8817             }
8818           if (attribute_flag[23] != 0)
8819             image->interpolate=(PixelInterpolateMethod)
8820               argument_list[23].integer_reference;
8821           if ((attribute_flag[24] != 0) &&
8822               (draw_info->fill_pattern != (Image *) NULL))
8823             flags=ParsePageGeometry(draw_info->fill_pattern,
8824               argument_list[24].string_reference,
8825               &draw_info->fill_pattern->tile_offset,exception);
8826           if (attribute_flag[25] != 0)
8827             {
8828               (void) ConcatenateString(&draw_info->primitive," '");
8829               (void) ConcatenateString(&draw_info->primitive,
8830                 argument_list[25].string_reference);
8831               (void) ConcatenateString(&draw_info->primitive,"'");
8832             }
8833           if (attribute_flag[26] != 0)
8834             draw_info->fill_pattern=CloneImage(
8835               argument_list[26].image_reference,0,0,MagickTrue,exception);
8836           if (attribute_flag[27] != 0)
8837             draw_info->stroke_pattern=CloneImage(
8838               argument_list[27].image_reference,0,0,MagickTrue,exception);
8839           if (attribute_flag[28] != 0)
8840             (void) CloneString(&draw_info->primitive,
8841               argument_list[28].string_reference);
8842           if (attribute_flag[29] != 0)
8843             draw_info->kerning=argument_list[29].real_reference;
8844           if (attribute_flag[30] != 0)
8845             draw_info->interline_spacing=argument_list[30].real_reference;
8846           if (attribute_flag[31] != 0)
8847             draw_info->interword_spacing=argument_list[31].real_reference;
8848           if (attribute_flag[32] != 0)
8849             draw_info->direction=(DirectionType)
8850               argument_list[32].integer_reference;
8851           DrawImage(image,draw_info,exception);
8852           draw_info=DestroyDrawInfo(draw_info);
8853           break;
8854         }
8855         case 39:  /* Equalize */
8856         {
8857           if (attribute_flag[0] != 0)
8858             channel=(ChannelType) argument_list[0].integer_reference;
8859           channel_mask=SetImageChannelMask(image,channel);
8860           EqualizeImage(image,exception);
8861           (void) SetImageChannelMask(image,channel_mask);
8862           break;
8863         }
8864         case 40:  /* Gamma */
8865         {
8866           if (attribute_flag[1] != 0)
8867             channel=(ChannelType) argument_list[1].integer_reference;
8868           if (attribute_flag[2] == 0)
8869             argument_list[2].real_reference=1.0;
8870           if (attribute_flag[3] == 0)
8871             argument_list[3].real_reference=1.0;
8872           if (attribute_flag[4] == 0)
8873             argument_list[4].real_reference=1.0;
8874           if (attribute_flag[0] == 0)
8875             {
8876               (void) FormatLocaleString(message,MaxTextExtent,
8877                 "%.15g,%.15g,%.15g",(double) argument_list[2].real_reference,
8878                 (double) argument_list[3].real_reference,
8879                 (double) argument_list[4].real_reference);
8880               argument_list[0].string_reference=message;
8881             }
8882           (void) GammaImage(image,StringToDouble(
8883             argument_list[0].string_reference,(char **) NULL),exception);
8884           break;
8885         }
8886         case 41:  /* Map */
8887         {
8888           QuantizeInfo
8889             *quantize_info;
8890
8891           if (attribute_flag[0] == 0)
8892             {
8893               ThrowPerlException(exception,OptionError,"MapImageRequired",
8894                 PackageName);
8895               goto PerlException;
8896             }
8897           quantize_info=AcquireQuantizeInfo(info->image_info);
8898           if (attribute_flag[1] != 0)
8899             quantize_info->dither_method=(DitherMethod)
8900               argument_list[1].integer_reference;
8901           (void) RemapImages(quantize_info,image,
8902             argument_list[0].image_reference,exception);
8903           quantize_info=DestroyQuantizeInfo(quantize_info);
8904           break;
8905         }
8906         case 42:  /* MatteFloodfill */
8907         {
8908           DrawInfo
8909             *draw_info;
8910
8911           MagickBooleanType
8912             invert;
8913
8914           PixelInfo
8915             target;
8916
8917           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8918             (DrawInfo *) NULL);
8919           if (attribute_flag[0] != 0)
8920             flags=ParsePageGeometry(image,argument_list[0].string_reference,
8921               &geometry,exception);
8922           if (attribute_flag[1] != 0)
8923             geometry.x=argument_list[1].integer_reference;
8924           if (attribute_flag[2] != 0)
8925             geometry.y=argument_list[2].integer_reference;
8926           if (image->alpha_trait != BlendPixelTrait)
8927             (void) SetImageAlpha(image,OpaqueAlpha,exception);
8928           (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8929             geometry.x,geometry.y,&target,exception);
8930           if (attribute_flag[4] != 0)
8931             QueryColorCompliance(argument_list[4].string_reference,
8932               AllCompliance,&target,exception);
8933           if (attribute_flag[3] != 0)
8934             target.alpha=StringToDoubleInterval(
8935               argument_list[3].string_reference,(double) (double) QuantumRange+
8936               1.0);
8937           if (attribute_flag[5] != 0)
8938             image->fuzz=StringToDoubleInterval(
8939               argument_list[5].string_reference,(double) QuantumRange+1.0);
8940           invert=MagickFalse;
8941           if (attribute_flag[6] != 0)
8942             invert=(MagickBooleanType) argument_list[6].integer_reference;
8943           channel_mask=SetImageChannelMask(image,AlphaChannel);
8944           (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8945             geometry.y,invert,exception);
8946           (void) SetImageChannelMask(image,channel_mask);
8947           draw_info=DestroyDrawInfo(draw_info);
8948           break;
8949         }
8950         case 43:  /* Modulate */
8951         {
8952           char
8953             modulate[MaxTextExtent];
8954
8955           geometry_info.rho=100.0;
8956           geometry_info.sigma=100.0;
8957           geometry_info.xi=100.0;
8958           if (attribute_flag[0] != 0)
8959             (void)ParseGeometry(argument_list[0].string_reference,
8960               &geometry_info);
8961           if (attribute_flag[1] != 0)
8962             geometry_info.xi=argument_list[1].real_reference;
8963           if (attribute_flag[2] != 0)
8964             geometry_info.sigma=argument_list[2].real_reference;
8965           if (attribute_flag[3] != 0)
8966             {
8967               geometry_info.sigma=argument_list[3].real_reference;
8968               SetImageArtifact(image,"modulate:colorspace","HWB");
8969             }
8970           if (attribute_flag[4] != 0)
8971             {
8972               geometry_info.rho=argument_list[4].real_reference;
8973               SetImageArtifact(image,"modulate:colorspace","HSB");
8974             }
8975           if (attribute_flag[5] != 0)
8976             {
8977               geometry_info.sigma=argument_list[5].real_reference;
8978               SetImageArtifact(image,"modulate:colorspace","HSL");
8979             }
8980           if (attribute_flag[6] != 0)
8981             {
8982               geometry_info.rho=argument_list[6].real_reference;
8983               SetImageArtifact(image,"modulate:colorspace","HWB");
8984             }
8985           (void) FormatLocaleString(modulate,MaxTextExtent,"%.15g,%.15g,%.15g",
8986             geometry_info.rho,geometry_info.sigma,geometry_info.xi);
8987           (void) ModulateImage(image,modulate,exception);
8988           break;
8989         }
8990         case 44:  /* Negate */
8991         {
8992           if (attribute_flag[0] == 0)
8993             argument_list[0].integer_reference=0;
8994           if (attribute_flag[1] != 0)
8995             channel=(ChannelType) argument_list[1].integer_reference;
8996           channel_mask=SetImageChannelMask(image,channel);
8997           (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
8998             MagickTrue : MagickFalse,exception);
8999           (void) SetImageChannelMask(image,channel_mask);
9000           break;
9001         }
9002         case 45:  /* Normalize */
9003         {
9004           if (attribute_flag[0] != 0)
9005             channel=(ChannelType) argument_list[0].integer_reference;
9006           channel_mask=SetImageChannelMask(image,channel);
9007           NormalizeImage(image,exception);
9008           (void) SetImageChannelMask(image,channel_mask);
9009           break;
9010         }
9011         case 46:  /* NumberColors */
9012           break;
9013         case 47:  /* Opaque */
9014         {
9015           MagickBooleanType
9016             invert;
9017
9018           PixelInfo
9019             fill_color,
9020             target;
9021
9022           (void) QueryColorCompliance("none",AllCompliance,&target,
9023              exception);
9024           (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9025             exception);
9026           if (attribute_flag[0] != 0)
9027             (void) QueryColorCompliance(argument_list[0].string_reference,
9028               AllCompliance,&target,exception);
9029           if (attribute_flag[1] != 0)
9030             (void) QueryColorCompliance(argument_list[1].string_reference,
9031               AllCompliance,&fill_color,exception);
9032           if (attribute_flag[2] != 0)
9033             image->fuzz=StringToDoubleInterval(
9034               argument_list[2].string_reference,(double) QuantumRange+1.0);
9035           if (attribute_flag[3] != 0)
9036             channel=(ChannelType) argument_list[3].integer_reference;
9037           invert=MagickFalse;
9038           if (attribute_flag[4] != 0)
9039             invert=(MagickBooleanType) argument_list[4].integer_reference;
9040           channel_mask=SetImageChannelMask(image,channel);
9041           (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9042           (void) SetImageChannelMask(image,channel_mask);
9043           break;
9044         }
9045         case 48:  /* Quantize */
9046         {
9047           QuantizeInfo
9048             *quantize_info;
9049
9050           quantize_info=AcquireQuantizeInfo(info->image_info);
9051           if (attribute_flag[0] != 0)
9052             quantize_info->number_colors=(size_t)
9053               argument_list[0].integer_reference;
9054           if (attribute_flag[1] != 0)
9055             quantize_info->tree_depth=(size_t)
9056               argument_list[1].integer_reference;
9057           if (attribute_flag[2] != 0)
9058             quantize_info->colorspace=(ColorspaceType)
9059               argument_list[2].integer_reference;
9060           if (attribute_flag[3] != 0)
9061             quantize_info->dither_method=(DitherMethod)
9062               argument_list[3].integer_reference;
9063           if (attribute_flag[4] != 0)
9064             quantize_info->measure_error=argument_list[4].integer_reference !=
9065               0 ? MagickTrue : MagickFalse;
9066           if (attribute_flag[5] != 0)
9067             (void) QueryColorCompliance(argument_list[5].string_reference,
9068               AllCompliance,&image->transparent_color,exception);
9069           if (attribute_flag[5] && argument_list[5].integer_reference)
9070             {
9071               (void) QuantizeImages(quantize_info,image,exception);
9072               goto PerlException;
9073             }
9074           if (attribute_flag[6] != 0)
9075             quantize_info->dither_method=(DitherMethod)
9076               argument_list[6].integer_reference;
9077           if ((image->storage_class == DirectClass) ||
9078               (image->colors > quantize_info->number_colors) ||
9079               (quantize_info->colorspace == GRAYColorspace))
9080             (void) QuantizeImage(quantize_info,image,exception);
9081           else
9082             CompressImageColormap(image,exception);
9083           quantize_info=DestroyQuantizeInfo(quantize_info);
9084           break;
9085         }
9086         case 49:  /* Raise */
9087         {
9088           if (attribute_flag[0] != 0)
9089             flags=ParsePageGeometry(image,argument_list[0].string_reference,
9090               &geometry,exception);
9091           if (attribute_flag[1] != 0)
9092             geometry.width=argument_list[1].integer_reference;
9093           if (attribute_flag[2] != 0)
9094             geometry.height=argument_list[2].integer_reference;
9095           if (attribute_flag[3] == 0)
9096             argument_list[3].integer_reference=1;
9097           (void) RaiseImage(image,&geometry,
9098             argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9099             exception);
9100           break;
9101         }
9102         case 50:  /* Segment */
9103         {
9104           ColorspaceType
9105             colorspace;
9106
9107           double
9108             cluster_threshold,
9109             smoothing_threshold;
9110
9111           MagickBooleanType
9112             verbose;
9113
9114           cluster_threshold=1.0;
9115           smoothing_threshold=1.5;
9116           colorspace=sRGBColorspace;
9117           verbose=MagickFalse;
9118           if (attribute_flag[0] != 0)
9119             {
9120               flags=ParseGeometry(argument_list[0].string_reference,
9121                 &geometry_info);
9122               cluster_threshold=geometry_info.rho;
9123               if (flags & SigmaValue)
9124                 smoothing_threshold=geometry_info.sigma;
9125             }
9126           if (attribute_flag[1] != 0)
9127             cluster_threshold=argument_list[1].real_reference;
9128           if (attribute_flag[2] != 0)
9129             smoothing_threshold=argument_list[2].real_reference;
9130           if (attribute_flag[3] != 0)
9131             colorspace=(ColorspaceType) argument_list[3].integer_reference;
9132           if (attribute_flag[4] != 0)
9133             verbose=argument_list[4].integer_reference != 0 ?
9134               MagickTrue : MagickFalse;
9135           (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9136             smoothing_threshold,exception);
9137           break;
9138         }
9139         case 51:  /* Signature */
9140         {
9141           (void) SignatureImage(image,exception);
9142           break;
9143         }
9144         case 52:  /* Solarize */
9145         {
9146           geometry_info.rho=QuantumRange/2.0;
9147           if (attribute_flag[0] != 0)
9148             flags=ParseGeometry(argument_list[0].string_reference,
9149               &geometry_info);
9150           if (attribute_flag[1] != 0)
9151             geometry_info.rho=StringToDoubleInterval(
9152               argument_list[1].string_reference,(double) QuantumRange+1.0);
9153           (void) SolarizeImage(image,geometry_info.rho,exception);
9154           break;
9155         }
9156         case 53:  /* Sync */
9157         {
9158           (void) SyncImage(image,exception);
9159           break;
9160         }
9161         case 54:  /* Texture */
9162         {
9163           if (attribute_flag[0] == 0)
9164             break;
9165           TextureImage(image,argument_list[0].image_reference,exception);
9166           break;
9167         }
9168         case 55:  /* Evalute */
9169         {
9170           MagickEvaluateOperator
9171             op;
9172
9173           op=SetEvaluateOperator;
9174           if (attribute_flag[0] == MagickFalse)
9175             argument_list[0].real_reference=0.0;
9176           if (attribute_flag[1] != MagickFalse)
9177             op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9178           if (attribute_flag[2] != MagickFalse)
9179             channel=(ChannelType) argument_list[2].integer_reference;
9180           channel_mask=SetImageChannelMask(image,channel);
9181           (void) EvaluateImage(image,op,argument_list[0].real_reference,
9182             exception);
9183           (void) SetImageChannelMask(image,channel_mask);
9184           break;
9185         }
9186         case 56:  /* Transparent */
9187         {
9188           double
9189             opacity;
9190
9191           MagickBooleanType
9192             invert;
9193
9194           PixelInfo
9195             target;
9196
9197           (void) QueryColorCompliance("none",AllCompliance,&target,
9198             exception);
9199           if (attribute_flag[0] != 0)
9200             (void) QueryColorCompliance(argument_list[0].string_reference,
9201               AllCompliance,&target,exception);
9202           opacity=TransparentAlpha;
9203           if (attribute_flag[1] != 0)
9204             opacity=StringToDoubleInterval(argument_list[1].string_reference,
9205               (double) QuantumRange+1.0);
9206           if (attribute_flag[2] != 0)
9207             image->fuzz=StringToDoubleInterval(
9208               argument_list[2].string_reference,(double) QuantumRange+1.0);
9209           if (attribute_flag[3] == 0)
9210             argument_list[3].integer_reference=0;
9211           invert=MagickFalse;
9212           if (attribute_flag[3] != 0)
9213             invert=(MagickBooleanType) argument_list[3].integer_reference;
9214           (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9215             invert,exception);
9216           break;
9217         }
9218         case 57:  /* Threshold */
9219         {
9220           double
9221             threshold;
9222
9223           if (attribute_flag[0] == 0)
9224             argument_list[0].string_reference="50%";
9225           if (attribute_flag[1] != 0)
9226             channel=(ChannelType) argument_list[1].integer_reference;
9227           threshold=StringToDoubleInterval(argument_list[0].string_reference,
9228             (double) QuantumRange+1.0);
9229           channel_mask=SetImageChannelMask(image,channel);
9230           (void) BilevelImage(image,threshold,exception);
9231           (void) SetImageChannelMask(image,channel_mask);
9232           break;
9233         }
9234         case 58:  /* Charcoal */
9235         {
9236           if (attribute_flag[0] != 0)
9237             {
9238               flags=ParseGeometry(argument_list[0].string_reference,
9239                 &geometry_info);
9240               if ((flags & SigmaValue) == 0)
9241                 geometry_info.sigma=1.0;
9242             }
9243           if (attribute_flag[1] != 0)
9244             geometry_info.rho=argument_list[1].real_reference;
9245           if (attribute_flag[2] != 0)
9246             geometry_info.sigma=argument_list[2].real_reference;
9247           image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9248             exception);
9249           break;
9250         }
9251         case 59:  /* Trim */
9252         {
9253           if (attribute_flag[0] != 0)
9254             image->fuzz=StringToDoubleInterval(
9255               argument_list[0].string_reference,(double) QuantumRange+1.0);
9256           image=TrimImage(image,exception);
9257           break;
9258         }
9259         case 60:  /* Wave */
9260         {
9261           PixelInterpolateMethod
9262             method;
9263
9264           if (attribute_flag[0] != 0)
9265             {
9266               flags=ParseGeometry(argument_list[0].string_reference,
9267                 &geometry_info);
9268               if ((flags & SigmaValue) == 0)
9269                 geometry_info.sigma=1.0;
9270             }
9271           if (attribute_flag[1] != 0)
9272             geometry_info.rho=argument_list[1].real_reference;
9273           if (attribute_flag[2] != 0)
9274             geometry_info.sigma=argument_list[2].real_reference;
9275           method=UndefinedInterpolatePixel;
9276           if (attribute_flag[3] != 0)
9277             method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9278           image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9279             method,exception);
9280           break;
9281         }
9282         case 61:  /* Separate */
9283         {
9284           if (attribute_flag[0] != 0)
9285             channel=(ChannelType) argument_list[0].integer_reference;
9286           image=SeparateImage(image,channel,exception);
9287           break;
9288         }
9289         case 63:  /* Stereo */
9290         {
9291           if (attribute_flag[0] == 0)
9292             {
9293               ThrowPerlException(exception,OptionError,"StereoImageRequired",
9294                 PackageName);
9295               goto PerlException;
9296             }
9297           if (attribute_flag[1] != 0)
9298             geometry.x=argument_list[1].integer_reference;
9299           if (attribute_flag[2] != 0)
9300             geometry.y=argument_list[2].integer_reference;
9301           image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9302             geometry.x,geometry.y,exception);
9303           break;
9304         }
9305         case 64:  /* Stegano */
9306         {
9307           if (attribute_flag[0] == 0)
9308             {
9309               ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9310                 PackageName);
9311               goto PerlException;
9312             }
9313           if (attribute_flag[1] == 0)
9314             argument_list[1].integer_reference=0;
9315           image->offset=argument_list[1].integer_reference;
9316           image=SteganoImage(image,argument_list[0].image_reference,exception);
9317           break;
9318         }
9319         case 65:  /* Deconstruct */
9320         {
9321           image=CompareImagesLayers(image,CompareAnyLayer,exception);
9322           break;
9323         }
9324         case 66:  /* GaussianBlur */
9325         {
9326           if (attribute_flag[0] != 0)
9327             {
9328               flags=ParseGeometry(argument_list[0].string_reference,
9329                 &geometry_info);
9330               if ((flags & SigmaValue) == 0)
9331                 geometry_info.sigma=1.0;
9332             }
9333           if (attribute_flag[1] != 0)
9334             geometry_info.rho=argument_list[1].real_reference;
9335           if (attribute_flag[2] != 0)
9336             geometry_info.sigma=argument_list[2].real_reference;
9337           if (attribute_flag[3] != 0)
9338             channel=(ChannelType) argument_list[3].integer_reference;
9339           channel_mask=SetImageChannelMask(image,channel);
9340           image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9341             exception);
9342           if (image != (Image *) NULL)
9343             (void) SetImageChannelMask(image,channel_mask);
9344           break;
9345         }
9346         case 67:  /* Convolve */
9347         {
9348           KernelInfo
9349             *kernel;
9350
9351           kernel=(KernelInfo *) NULL;
9352           if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9353             break;
9354           if (attribute_flag[0] != 0)
9355             {
9356               AV
9357                 *av;
9358
9359               size_t
9360                 order;
9361
9362               kernel=AcquireKernelInfo((const char *) NULL);
9363               if (kernel == (KernelInfo *) NULL)
9364                 break;
9365               av=(AV *) argument_list[0].array_reference;
9366               order=(size_t) sqrt(av_len(av)+1);
9367               kernel->width=order;
9368               kernel->height=order;
9369               kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9370                 order*sizeof(*kernel->values));
9371               if (kernel->values == (MagickRealType *) NULL)
9372                 {
9373                   kernel=DestroyKernelInfo(kernel);
9374                   ThrowPerlException(exception,ResourceLimitFatalError,
9375                     "MemoryAllocationFailed",PackageName);
9376                   goto PerlException;
9377                 }
9378               for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9379                 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9380               for ( ; j < (ssize_t) (order*order); j++)
9381                 kernel->values[j]=0.0;
9382             }
9383           if (attribute_flag[1] != 0)
9384             channel=(ChannelType) argument_list[1].integer_reference;
9385           if (attribute_flag[2] != 0)
9386             SetImageArtifact(image,"filter:blur",
9387               argument_list[2].string_reference);
9388           if (attribute_flag[3] != 0)
9389             {
9390               kernel=AcquireKernelInfo(argument_list[3].string_reference);
9391               if (kernel == (KernelInfo *) NULL)
9392                 break;
9393             }
9394           channel_mask=SetImageChannelMask(image,channel);
9395           image=ConvolveImage(image,kernel,exception);
9396           if (image != (Image *) NULL)
9397             (void) SetImageChannelMask(image,channel_mask);
9398           kernel=DestroyKernelInfo(kernel);
9399           break;
9400         }
9401         case 68:  /* Profile */
9402         {
9403           const char
9404             *name;
9405
9406           Image
9407             *profile_image;
9408
9409           ImageInfo
9410             *profile_info;
9411
9412           StringInfo
9413             *profile;
9414
9415           name="*";
9416           if (attribute_flag[0] != 0)
9417             name=argument_list[0].string_reference;
9418           if (attribute_flag[2] != 0)
9419             image->rendering_intent=(RenderingIntent)
9420               argument_list[2].integer_reference;
9421           if (attribute_flag[3] != 0)
9422             image->black_point_compensation=
9423               argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9424           if (attribute_flag[1] != 0)
9425             {
9426               if (argument_list[1].length == 0)
9427                 {
9428                   /*
9429                     Remove a profile from the image.
9430                   */
9431                   (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9432                     exception);
9433                   break;
9434                 }
9435               /*
9436                 Associate user supplied profile with the image.
9437               */
9438               profile=AcquireStringInfo(argument_list[1].length);
9439               SetStringInfoDatum(profile,(const unsigned char *)
9440                 argument_list[1].string_reference);
9441               (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9442                 (size_t) GetStringInfoLength(profile),exception);
9443               profile=DestroyStringInfo(profile);
9444               break;
9445             }
9446           /*
9447             Associate a profile with the image.
9448           */
9449           profile_info=CloneImageInfo(info ? info->image_info :
9450             (ImageInfo *) NULL);
9451           profile_image=ReadImages(profile_info,name,exception);
9452           if (profile_image == (Image *) NULL)
9453             break;
9454           ResetImageProfileIterator(profile_image);
9455           name=GetNextImageProfile(profile_image);
9456           while (name != (const char *) NULL)
9457           {
9458             const StringInfo
9459               *profile;
9460
9461             profile=GetImageProfile(profile_image,name);
9462             if (profile != (const StringInfo *) NULL)
9463               (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9464                 (size_t) GetStringInfoLength(profile),exception);
9465             name=GetNextImageProfile(profile_image);
9466           }
9467           profile_image=DestroyImage(profile_image);
9468           profile_info=DestroyImageInfo(profile_info);
9469           break;
9470         }
9471         case 69:  /* UnsharpMask */
9472         {
9473           if (attribute_flag[0] != 0)
9474             {
9475               flags=ParseGeometry(argument_list[0].string_reference,
9476                 &geometry_info);
9477               if ((flags & SigmaValue) == 0)
9478                 geometry_info.sigma=1.0;
9479               if ((flags & XiValue) == 0)
9480                 geometry_info.xi=1.0;
9481               if ((flags & PsiValue) == 0)
9482                 geometry_info.psi=0.5;
9483             }
9484           if (attribute_flag[1] != 0)
9485             geometry_info.rho=argument_list[1].real_reference;
9486           if (attribute_flag[2] != 0)
9487             geometry_info.sigma=argument_list[2].real_reference;
9488           if (attribute_flag[3] != 0)
9489             geometry_info.xi=argument_list[3].real_reference;
9490           if (attribute_flag[4] != 0)
9491             channel=(ChannelType) argument_list[4].integer_reference;
9492           channel_mask=SetImageChannelMask(image,channel);
9493           image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9494             geometry_info.xi,exception);
9495           if (image != (Image *) NULL)
9496             (void) SetImageChannelMask(image,channel_mask);
9497           break;
9498         }
9499         case 70:  /* MotionBlur */
9500         {
9501           if (attribute_flag[0] != 0)
9502             {
9503               flags=ParseGeometry(argument_list[0].string_reference,
9504                 &geometry_info);
9505               if ((flags & SigmaValue) == 0)
9506                 geometry_info.sigma=1.0;
9507               if ((flags & XiValue) == 0)
9508                 geometry_info.xi=1.0;
9509             }
9510           if (attribute_flag[1] != 0)
9511             geometry_info.rho=argument_list[1].real_reference;
9512           if (attribute_flag[2] != 0)
9513             geometry_info.sigma=argument_list[2].real_reference;
9514           if (attribute_flag[3] != 0)
9515             geometry_info.xi=argument_list[3].real_reference;
9516           if (attribute_flag[4] != 0)
9517             channel=(ChannelType) argument_list[4].integer_reference;
9518           channel_mask=SetImageChannelMask(image,channel);
9519           image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9520             geometry_info.xi,exception);
9521           if (image != (Image *) NULL)
9522             (void) SetImageChannelMask(image,channel_mask);
9523           break;
9524         }
9525         case 71:  /* OrderedDither */
9526         {
9527           if (attribute_flag[0] == 0)
9528             argument_list[0].string_reference="o8x8";
9529           if (attribute_flag[1] != 0)
9530             channel=(ChannelType) argument_list[1].integer_reference;
9531           channel_mask=SetImageChannelMask(image,channel);
9532           (void) OrderedPosterizeImage(image,argument_list[0].string_reference,
9533             exception);
9534           (void) SetImageChannelMask(image,channel_mask);
9535           break;
9536         }
9537         case 72:  /* Shave */
9538         {
9539           if (attribute_flag[0] != 0)
9540             flags=ParsePageGeometry(image,argument_list[0].string_reference,
9541               &geometry,exception);
9542           if (attribute_flag[1] != 0)
9543             geometry.width=argument_list[1].integer_reference;
9544           if (attribute_flag[2] != 0)
9545             geometry.height=argument_list[2].integer_reference;
9546           image=ShaveImage(image,&geometry,exception);
9547           break;
9548         }
9549         case 73:  /* Level */
9550         {
9551           double
9552             black_point,
9553             gamma,
9554             white_point;
9555
9556           black_point=0.0;
9557           white_point=(double) image->columns*image->rows;
9558           gamma=1.0;
9559           if (attribute_flag[0] != 0)
9560             {
9561               flags=ParseGeometry(argument_list[0].string_reference,
9562                 &geometry_info);
9563               black_point=geometry_info.rho;
9564               if ((flags & SigmaValue) != 0)
9565                 white_point=geometry_info.sigma;
9566               if ((flags & XiValue) != 0)
9567                 gamma=geometry_info.xi;
9568               if ((flags & PercentValue) != 0)
9569                 {
9570                   black_point*=(double) (QuantumRange/100.0);
9571                   white_point*=(double) (QuantumRange/100.0);
9572                 }
9573               if ((flags & SigmaValue) == 0)
9574                 white_point=(double) QuantumRange-black_point;
9575             }
9576           if (attribute_flag[1] != 0)
9577             black_point=argument_list[1].real_reference;
9578           if (attribute_flag[2] != 0)
9579             white_point=argument_list[2].real_reference;
9580           if (attribute_flag[3] != 0)
9581             gamma=argument_list[3].real_reference;
9582           if (attribute_flag[4] != 0)
9583             channel=(ChannelType) argument_list[4].integer_reference;
9584           if (attribute_flag[5] != 0)
9585             {
9586               argument_list[0].real_reference=argument_list[5].real_reference;
9587               attribute_flag[0]=attribute_flag[5];
9588             }
9589           channel_mask=SetImageChannelMask(image,channel);
9590           (void) LevelImage(image,black_point,white_point,gamma,exception);
9591           (void) SetImageChannelMask(image,channel_mask);
9592           break;
9593         }
9594         case 74:  /* Clip */
9595         {
9596           if (attribute_flag[0] == 0)
9597             argument_list[0].string_reference="#1";
9598           if (attribute_flag[1] == 0)
9599             argument_list[1].integer_reference=MagickTrue;
9600           (void) ClipImagePath(image,argument_list[0].string_reference,
9601             argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9602             exception);
9603           break;
9604         }
9605         case 75:  /* AffineTransform */
9606         {
9607           DrawInfo
9608             *draw_info;
9609
9610           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9611             (DrawInfo *) NULL);
9612           if (attribute_flag[0] != 0)
9613             {
9614               AV
9615                 *av;
9616
9617               av=(AV *) argument_list[0].array_reference;
9618               if ((av_len(av) != 3) && (av_len(av) != 5))
9619                 {
9620                   ThrowPerlException(exception,OptionError,
9621                     "affine matrix must have 4 or 6 elements",PackageName);
9622                   goto PerlException;
9623                 }
9624               draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9625               draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9626               draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9627               draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9628               if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9629                   draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9630                 {
9631                   ThrowPerlException(exception,OptionError,
9632                     "affine matrix is singular",PackageName);
9633                    goto PerlException;
9634                 }
9635               if (av_len(av) == 5)
9636                 {
9637                   draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9638                   draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9639                 }
9640             }
9641           for (j=1; j < 6; j++)
9642           {
9643             if (attribute_flag[j] == 0)
9644               continue;
9645             value=argument_list[j].string_reference;
9646             angle=argument_list[j].real_reference;
9647             current=draw_info->affine;
9648             GetAffineMatrix(&affine);
9649             switch (j)
9650             {
9651               case 1:
9652               {
9653                 /*
9654                   Translate.
9655                 */
9656                 flags=ParseGeometry(value,&geometry_info);
9657                 affine.tx=geometry_info.xi;
9658                 affine.ty=geometry_info.psi;
9659                 if ((flags & PsiValue) == 0)
9660                   affine.ty=affine.tx;
9661                 break;
9662               }
9663               case 2:
9664               {
9665                 /*
9666                   Scale.
9667                 */
9668                 flags=ParseGeometry(value,&geometry_info);
9669                 affine.sx=geometry_info.rho;
9670                 affine.sy=geometry_info.sigma;
9671                 if ((flags & SigmaValue) == 0)
9672                   affine.sy=affine.sx;
9673                 break;
9674               }
9675               case 3:
9676               {
9677                 /*
9678                   Rotate.
9679                 */
9680                 if (angle == 0.0)
9681                   break;
9682                 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9683                 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9684                 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9685                 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9686                 break;
9687               }
9688               case 4:
9689               {
9690                 /*
9691                   SkewX.
9692                 */
9693                 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9694                 break;
9695               }
9696               case 5:
9697               {
9698                 /*
9699                   SkewY.
9700                 */
9701                 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9702                 break;
9703               }
9704             }
9705             draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9706             draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9707             draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9708             draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9709             draw_info->affine.tx=
9710               current.sx*affine.tx+current.ry*affine.ty+current.tx;
9711             draw_info->affine.ty=
9712               current.rx*affine.tx+current.sy*affine.ty+current.ty;
9713           }
9714           if (attribute_flag[6] != 0)
9715             image->interpolate=(PixelInterpolateMethod)
9716               argument_list[6].integer_reference;
9717           if (attribute_flag[7] != 0)
9718             QueryColorCompliance(argument_list[7].string_reference,
9719               AllCompliance,&image->background_color,exception);
9720           image=AffineTransformImage(image,&draw_info->affine,exception);
9721           draw_info=DestroyDrawInfo(draw_info);
9722           break;
9723         }
9724         case 76:  /* Difference */
9725         {
9726           if (attribute_flag[0] == 0)
9727             {
9728               ThrowPerlException(exception,OptionError,
9729                 "ReferenceImageRequired",PackageName);
9730               goto PerlException;
9731             }
9732           if (attribute_flag[1] != 0)
9733             image->fuzz=StringToDoubleInterval(
9734               argument_list[1].string_reference,(double) QuantumRange+1.0);
9735           (void) IsImagesEqual(image,argument_list[0].image_reference,
9736             exception);
9737           break;
9738         }
9739         case 77:  /* AdaptiveThreshold */
9740         {
9741           if (attribute_flag[0] != 0)
9742             {
9743               flags=ParseGeometry(argument_list[0].string_reference,
9744                 &geometry_info);
9745               if ((flags & PercentValue) != 0)
9746                 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9747             }
9748           if (attribute_flag[1] != 0)
9749             geometry_info.rho=argument_list[1].integer_reference;
9750           if (attribute_flag[2] != 0)
9751             geometry_info.sigma=argument_list[2].integer_reference;
9752           if (attribute_flag[3] != 0)
9753             geometry_info.xi=argument_list[3].integer_reference;;
9754           image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
9755             (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
9756           break;
9757         }
9758         case 78:  /* Resample */
9759         {
9760           size_t
9761             height,
9762             width;
9763
9764           if (attribute_flag[0] != 0)
9765             {
9766               flags=ParseGeometry(argument_list[0].string_reference,
9767                 &geometry_info);
9768               if ((flags & SigmaValue) == 0)
9769                 geometry_info.sigma=geometry_info.rho;
9770             }
9771           if (attribute_flag[1] != 0)
9772             geometry_info.rho=argument_list[1].real_reference;
9773           if (attribute_flag[2] != 0)
9774             geometry_info.sigma=argument_list[2].real_reference;
9775           if (attribute_flag[3] == 0)
9776             argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
9777           if (attribute_flag[4] == 0)
9778             SetImageArtifact(image,"filter:support",
9779               argument_list[4].string_reference);
9780           width=(size_t) (geometry_info.rho*image->columns/
9781             (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
9782           height=(size_t) (geometry_info.sigma*image->rows/
9783             (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
9784           image=ResizeImage(image,width,height,(FilterTypes)
9785             argument_list[3].integer_reference,exception);
9786           if (image != (Image *) NULL)
9787             {
9788               image->resolution.x=geometry_info.rho;
9789               image->resolution.y=geometry_info.sigma;
9790             }
9791           break;
9792         }
9793         case 79:  /* Describe */
9794         {
9795           if (attribute_flag[0] == 0)
9796             argument_list[0].file_reference=(FILE *) NULL;
9797           if (attribute_flag[1] != 0)
9798             (void) SetImageArtifact(image,"identify:features",
9799               argument_list[1].string_reference);
9800           (void) IdentifyImage(image,argument_list[0].file_reference,
9801             MagickTrue,exception);
9802           break;
9803         }
9804         case 80:  /* BlackThreshold */
9805         {
9806           if (attribute_flag[0] == 0)
9807             argument_list[0].string_reference="50%";
9808           if (attribute_flag[2] != 0)
9809             channel=(ChannelType) argument_list[2].integer_reference;
9810           channel_mask=SetImageChannelMask(image,channel);
9811           BlackThresholdImage(image,argument_list[0].string_reference,
9812             exception);
9813           (void) SetImageChannelMask(image,channel_mask);
9814           break;
9815         }
9816         case 81:  /* WhiteThreshold */
9817         {
9818           if (attribute_flag[0] == 0)
9819             argument_list[0].string_reference="50%";
9820           if (attribute_flag[2] != 0)
9821             channel=(ChannelType) argument_list[2].integer_reference;
9822           channel_mask=SetImageChannelMask(image,channel);
9823           WhiteThresholdImage(image,argument_list[0].string_reference,
9824             exception);
9825           (void) SetImageChannelMask(image,channel_mask);
9826           break;
9827         }
9828         case 82:  /* RadialBlur */
9829         {
9830           if (attribute_flag[0] != 0)
9831             {
9832               flags=ParseGeometry(argument_list[0].string_reference,
9833                 &geometry_info);
9834             }
9835           if (attribute_flag[1] != 0)
9836             geometry_info.rho=argument_list[1].real_reference;
9837           if (attribute_flag[2] != 0)
9838             channel=(ChannelType) argument_list[2].integer_reference;
9839           channel_mask=SetImageChannelMask(image,channel);
9840           image=RadialBlurImage(image,geometry_info.rho,exception);
9841           if (image != (Image *) NULL)
9842             (void) SetImageChannelMask(image,channel_mask);
9843           break;
9844         }
9845         case 83:  /* Thumbnail */
9846         {
9847           if (attribute_flag[0] != 0)
9848             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
9849               &geometry,exception);
9850           if (attribute_flag[1] != 0)
9851             geometry.width=argument_list[1].integer_reference;
9852           if (attribute_flag[2] != 0)
9853             geometry.height=argument_list[2].integer_reference;
9854           image=ThumbnailImage(image,geometry.width,geometry.height,exception);
9855           break;
9856         }
9857         case 84:  /* Strip */
9858         {
9859           (void) StripImage(image,exception);
9860           break;
9861         }
9862         case 85:  /* Tint */
9863         {
9864           PixelInfo
9865             tint;
9866
9867           GetPixelInfo(image,&tint);
9868           if (attribute_flag[0] != 0)
9869             (void) QueryColorCompliance(argument_list[0].string_reference,
9870               AllCompliance,&tint,exception);
9871           if (attribute_flag[1] == 0)
9872             argument_list[1].string_reference="100";
9873           image=TintImage(image,argument_list[1].string_reference,&tint,
9874             exception);
9875           break;
9876         }
9877         case 86:  /* Channel */
9878         {
9879           if (attribute_flag[0] != 0)
9880             channel=(ChannelType) argument_list[0].integer_reference;
9881           image=SeparateImage(image,channel,exception);
9882           break;
9883         }
9884         case 87:  /* Splice */
9885         {
9886           if (attribute_flag[0] != 0)
9887             flags=ParseGravityGeometry(image,argument_list[0].string_reference,
9888               &geometry,exception);
9889           if (attribute_flag[1] != 0)
9890             geometry.width=argument_list[1].integer_reference;
9891           if (attribute_flag[2] != 0)
9892             geometry.height=argument_list[2].integer_reference;
9893           if (attribute_flag[3] != 0)
9894             geometry.x=argument_list[3].integer_reference;
9895           if (attribute_flag[4] != 0)
9896             geometry.y=argument_list[4].integer_reference;
9897           if (attribute_flag[5] != 0)
9898             image->fuzz=StringToDoubleInterval(
9899               argument_list[5].string_reference,(double) QuantumRange+1.0);
9900           if (attribute_flag[6] != 0)
9901             (void) QueryColorCompliance(argument_list[6].string_reference,
9902               AllCompliance,&image->background_color,exception);
9903           if (attribute_flag[7] != 0)
9904             image->gravity=(GravityType) argument_list[7].integer_reference;
9905           image=SpliceImage(image,&geometry,exception);
9906           break;
9907         }
9908         case 88:  /* Posterize */
9909         {
9910           if (attribute_flag[0] == 0)
9911             argument_list[0].integer_reference=3;
9912           if (attribute_flag[1] == 0)
9913             argument_list[1].integer_reference=0;
9914           (void) PosterizeImage(image,argument_list[0].integer_reference,
9915             argument_list[1].integer_reference ? RiemersmaDitherMethod :
9916             NoDitherMethod,exception);
9917           break;
9918         }
9919         case 89:  /* Shadow */
9920         {
9921           if (attribute_flag[0] != 0)
9922             {
9923               flags=ParseGeometry(argument_list[0].string_reference,
9924                 &geometry_info);
9925               if ((flags & SigmaValue) == 0)
9926                 geometry_info.sigma=1.0;
9927               if ((flags & XiValue) == 0)
9928                 geometry_info.xi=4.0;
9929               if ((flags & PsiValue) == 0)
9930                 geometry_info.psi=4.0;
9931             }
9932           if (attribute_flag[1] != 0)
9933             geometry_info.rho=argument_list[1].real_reference;
9934           if (attribute_flag[2] != 0)
9935             geometry_info.sigma=argument_list[2].real_reference;
9936           if (attribute_flag[3] != 0)
9937             geometry_info.xi=argument_list[3].integer_reference;
9938           if (attribute_flag[4] != 0)
9939             geometry_info.psi=argument_list[4].integer_reference;
9940           image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
9941             (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
9942             ceil(geometry_info.psi-0.5),exception);
9943           break;
9944         }
9945         case 90:  /* Identify */
9946         {
9947           if (attribute_flag[0] == 0)
9948             argument_list[0].file_reference=(FILE *) NULL;
9949           if (attribute_flag[1] != 0)
9950             (void) SetImageArtifact(image,"identify:features",
9951               argument_list[1].string_reference);
9952           if ((attribute_flag[2] != 0) &&
9953               (argument_list[2].integer_reference != 0))
9954             (void) SetImageArtifact(image,"identify:unique","true");
9955           (void) IdentifyImage(image,argument_list[0].file_reference,
9956             MagickTrue,exception);
9957           break;
9958         }
9959         case 91:  /* SepiaTone */
9960         {
9961           if (attribute_flag[0] == 0)
9962             argument_list[0].real_reference=80.0*QuantumRange/100.0;
9963           image=SepiaToneImage(image,argument_list[0].real_reference,
9964             exception);
9965           break;
9966         }
9967         case 92:  /* SigmoidalContrast */
9968         {
9969           MagickBooleanType
9970             sharpen;
9971
9972           if (attribute_flag[0] != 0)
9973             {
9974               flags=ParseGeometry(argument_list[0].string_reference,
9975                 &geometry_info);
9976               if ((flags & SigmaValue) == 0)
9977                 geometry_info.sigma=QuantumRange/2.0;
9978               if ((flags & PercentValue) != 0)
9979                 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
9980             }
9981           if (attribute_flag[1] != 0)
9982             geometry_info.rho=argument_list[1].real_reference;
9983           if (attribute_flag[2] != 0)
9984             geometry_info.sigma=argument_list[2].real_reference;
9985           if (attribute_flag[3] != 0)
9986             channel=(ChannelType) argument_list[3].integer_reference;
9987           sharpen=MagickTrue;
9988           if (attribute_flag[4] != 0)
9989             sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
9990               MagickFalse;
9991           channel_mask=SetImageChannelMask(image,channel);
9992           (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
9993             geometry_info.sigma,exception);
9994           (void) SetImageChannelMask(image,channel_mask);
9995           break;
9996         }
9997         case 93:  /* Extent */
9998         {
9999           if (attribute_flag[7] != 0)
10000             image->gravity=(GravityType) argument_list[7].integer_reference;
10001           if (attribute_flag[0] != 0)
10002             {
10003               int
10004                 flags;
10005
10006               flags=ParseGravityGeometry(image,
10007                 argument_list[0].string_reference,&geometry,exception);
10008               (void) flags;
10009               if (geometry.width == 0)
10010                 geometry.width=image->columns;
10011               if (geometry.height == 0)
10012                 geometry.height=image->rows;
10013             }
10014           if (attribute_flag[1] != 0)
10015             geometry.width=argument_list[1].integer_reference;
10016           if (attribute_flag[2] != 0)
10017             geometry.height=argument_list[2].integer_reference;
10018           if (attribute_flag[3] != 0)
10019             geometry.x=argument_list[3].integer_reference;
10020           if (attribute_flag[4] != 0)
10021             geometry.y=argument_list[4].integer_reference;
10022           if (attribute_flag[5] != 0)
10023             image->fuzz=StringToDoubleInterval(
10024               argument_list[5].string_reference,(double) QuantumRange+1.0);
10025           if (attribute_flag[6] != 0)
10026             (void) QueryColorCompliance(argument_list[6].string_reference,
10027               AllCompliance,&image->background_color,exception);
10028           image=ExtentImage(image,&geometry,exception);
10029           break;
10030         }
10031         case 94:  /* Vignette */
10032         {
10033           if (attribute_flag[0] != 0)
10034             {
10035               flags=ParseGeometry(argument_list[0].string_reference,
10036                 &geometry_info);
10037               if ((flags & SigmaValue) == 0)
10038                 geometry_info.sigma=1.0;
10039               if ((flags & XiValue) == 0)
10040                 geometry_info.xi=0.1*image->columns;
10041               if ((flags & PsiValue) == 0)
10042                 geometry_info.psi=0.1*image->rows;
10043             }
10044           if (attribute_flag[1] != 0)
10045             geometry_info.rho=argument_list[1].real_reference;
10046           if (attribute_flag[2] != 0)
10047             geometry_info.sigma=argument_list[2].real_reference;
10048           if (attribute_flag[3] != 0)
10049             geometry_info.xi=argument_list[3].integer_reference;
10050           if (attribute_flag[4] != 0)
10051             geometry_info.psi=argument_list[4].integer_reference;
10052           if (attribute_flag[5] != 0)
10053             (void) QueryColorCompliance(argument_list[5].string_reference,
10054               AllCompliance,&image->background_color,exception);
10055           image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10056             (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10057             ceil(geometry_info.psi-0.5),exception);
10058           break;
10059         }
10060         case 95:  /* ContrastStretch */
10061         {
10062           double
10063             black_point,
10064             white_point;
10065
10066           black_point=0.0;
10067           white_point=(double) image->columns*image->rows;
10068           if (attribute_flag[0] != 0)
10069             {
10070               flags=ParseGeometry(argument_list[0].string_reference,
10071                 &geometry_info);
10072               black_point=geometry_info.rho;
10073               white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10074                 black_point;
10075               if ((flags & PercentValue) != 0)
10076                 {
10077                   black_point*=(double) image->columns*image->rows/100.0;
10078                   white_point*=(double) image->columns*image->rows/100.0;
10079                 }
10080               white_point=(double) image->columns*image->rows-
10081                 white_point;
10082             }
10083           if (attribute_flag[1] != 0)
10084             black_point=argument_list[1].real_reference;
10085           if (attribute_flag[2] != 0)
10086             white_point=argument_list[2].real_reference;
10087           if (attribute_flag[4] != 0)
10088             channel=(ChannelType) argument_list[4].integer_reference;
10089           channel_mask=SetImageChannelMask(image,channel);
10090           (void) ContrastStretchImage(image,black_point,white_point,exception);
10091           (void) SetImageChannelMask(image,channel_mask);
10092           break;
10093         }
10094         case 96:  /* Sans0 */
10095         {
10096           break;
10097         }
10098         case 97:  /* Sans1 */
10099         {
10100           break;
10101         }
10102         case 98:  /* AdaptiveSharpen */
10103         {
10104           if (attribute_flag[0] != 0)
10105             {
10106               flags=ParseGeometry(argument_list[0].string_reference,
10107                 &geometry_info);
10108               if ((flags & SigmaValue) == 0)
10109                 geometry_info.sigma=1.0;
10110               if ((flags & XiValue) == 0)
10111                 geometry_info.xi=0.0;
10112             }
10113           if (attribute_flag[1] != 0)
10114             geometry_info.rho=argument_list[1].real_reference;
10115           if (attribute_flag[2] != 0)
10116             geometry_info.sigma=argument_list[2].real_reference;
10117           if (attribute_flag[3] != 0)
10118             geometry_info.xi=argument_list[3].real_reference;
10119           if (attribute_flag[4] != 0)
10120             channel=(ChannelType) argument_list[4].integer_reference;
10121           channel_mask=SetImageChannelMask(image,channel);
10122           image=AdaptiveSharpenImage(image,geometry_info.rho,
10123             geometry_info.sigma,exception);
10124           if (image != (Image *) NULL)
10125             (void) SetImageChannelMask(image,channel_mask);
10126           break;
10127         }
10128         case 99:  /* Transpose */
10129         {
10130           image=TransposeImage(image,exception);
10131           break;
10132         }
10133         case 100:  /* Tranverse */
10134         {
10135           image=TransverseImage(image,exception);
10136           break;
10137         }
10138         case 101:  /* AutoOrient */
10139         {
10140           image=AutoOrientImage(image,image->orientation,exception);
10141           break;
10142         }
10143         case 102:  /* AdaptiveBlur */
10144         {
10145           if (attribute_flag[0] != 0)
10146             {
10147               flags=ParseGeometry(argument_list[0].string_reference,
10148                 &geometry_info);
10149               if ((flags & SigmaValue) == 0)
10150                 geometry_info.sigma=1.0;
10151               if ((flags & XiValue) == 0)
10152                 geometry_info.xi=0.0;
10153             }
10154           if (attribute_flag[1] != 0)
10155             geometry_info.rho=argument_list[1].real_reference;
10156           if (attribute_flag[2] != 0)
10157             geometry_info.sigma=argument_list[2].real_reference;
10158           if (attribute_flag[3] != 0)
10159             channel=(ChannelType) argument_list[3].integer_reference;
10160           channel_mask=SetImageChannelMask(image,channel);
10161           image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10162             exception);
10163           if (image != (Image *) NULL)
10164             (void) SetImageChannelMask(image,channel_mask);
10165           break;
10166         }
10167         case 103:  /* Sketch */
10168         {
10169           if (attribute_flag[0] != 0)
10170             {
10171               flags=ParseGeometry(argument_list[0].string_reference,
10172                 &geometry_info);
10173               if ((flags & SigmaValue) == 0)
10174                 geometry_info.sigma=1.0;
10175               if ((flags & XiValue) == 0)
10176                 geometry_info.xi=1.0;
10177             }
10178           if (attribute_flag[1] != 0)
10179             geometry_info.rho=argument_list[1].real_reference;
10180           if (attribute_flag[2] != 0)
10181             geometry_info.sigma=argument_list[2].real_reference;
10182           if (attribute_flag[3] != 0)
10183             geometry_info.xi=argument_list[3].real_reference;
10184           image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10185             geometry_info.xi,exception);
10186           break;
10187         }
10188         case 104:  /* UniqueColors */
10189         {
10190           image=UniqueImageColors(image,exception);
10191           break;
10192         }
10193         case 105:  /* AdaptiveResize */
10194         {
10195           if (attribute_flag[0] != 0)
10196             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10197               &geometry,exception);
10198           if (attribute_flag[1] != 0)
10199             geometry.width=argument_list[1].integer_reference;
10200           if (attribute_flag[2] != 0)
10201             geometry.height=argument_list[2].integer_reference;
10202           if (attribute_flag[3] != 0)
10203             image->filter=(FilterTypes) argument_list[4].integer_reference;
10204           if (attribute_flag[4] != 0)
10205             SetImageArtifact(image,"filter:support",
10206               argument_list[4].string_reference);
10207           image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10208             exception);
10209           break;
10210         }
10211         case 106:  /* ClipMask */
10212         {
10213           Image
10214             *mask_image;
10215
10216           if (attribute_flag[0] == 0)
10217             {
10218               ThrowPerlException(exception,OptionError,"MaskImageRequired",
10219                 PackageName);
10220               goto PerlException;
10221             }
10222           mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10223             exception);
10224           (void) NegateImage(mask_image,MagickFalse,exception);
10225           (void) SetImageMask(image,mask_image,exception);
10226           mask_image=DestroyImage(mask_image);
10227           break;
10228         }
10229         case 107:  /* LinearStretch */
10230         {
10231            double
10232              black_point,
10233              white_point;
10234
10235            black_point=0.0;
10236            white_point=(double) image->columns*image->rows;
10237            if (attribute_flag[0] != 0)
10238              {
10239                flags=ParseGeometry(argument_list[0].string_reference,
10240                  &geometry_info);
10241                if ((flags & SigmaValue) != 0)
10242                   white_point=geometry_info.sigma;
10243                if ((flags & PercentValue) != 0)
10244                  {
10245                    black_point*=(double) image->columns*image->rows/100.0;
10246                    white_point*=(double) image->columns*image->rows/100.0;
10247                  }
10248                if ((flags & SigmaValue) == 0)
10249                  white_point=(double) image->columns*image->rows-black_point;
10250              }
10251           if (attribute_flag[1] != 0)
10252             black_point=argument_list[1].real_reference;
10253           if (attribute_flag[2] != 0)
10254             white_point=argument_list[2].real_reference;
10255           (void) LinearStretchImage(image,black_point,white_point,exception);
10256           break;
10257         }
10258         case 108:  /* ColorMatrix */
10259         {
10260           AV
10261             *av;
10262
10263           double
10264             *color_matrix;
10265
10266           KernelInfo
10267             *kernel_info;
10268
10269           size_t
10270             order;
10271
10272           if (attribute_flag[0] == 0)
10273             break;
10274           av=(AV *) argument_list[0].array_reference;
10275           order=(size_t) sqrt(av_len(av)+1);
10276           color_matrix=(double *) AcquireQuantumMemory(order,order*
10277             sizeof(*color_matrix));
10278           if (color_matrix == (double *) NULL)
10279             {
10280               ThrowPerlException(exception,ResourceLimitFatalError,
10281                 "MemoryAllocationFailed",PackageName);
10282               goto PerlException;
10283            }
10284           for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10285             color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10286           for ( ; j < (ssize_t) (order*order); j++)
10287             color_matrix[j]=0.0;
10288           kernel_info=AcquireKernelInfo((const char *) NULL);
10289           if (kernel_info == (KernelInfo *) NULL)
10290             break;
10291           kernel_info->width=order;
10292           kernel_info->height=order;
10293           kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10294             order*sizeof(*kernel_info->values));
10295           if (kernel_info->values != (MagickRealType *) NULL)
10296             {
10297               for (i=0; i < (ssize_t) (order*order); i++)
10298                 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10299               image=ColorMatrixImage(image,kernel_info,exception);
10300             }
10301           kernel_info=DestroyKernelInfo(kernel_info);
10302           color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10303           break;
10304         }
10305         case 109:  /* Mask */
10306         {
10307           Image
10308             *mask_image;
10309
10310           if (attribute_flag[0] == 0)
10311             {
10312               ThrowPerlException(exception,OptionError,"MaskImageRequired",
10313                 PackageName);
10314               goto PerlException;
10315             }
10316           mask_image=CloneImage(argument_list[0].image_reference,0,0,
10317             MagickTrue,exception);
10318           (void) NegateImage(mask_image,MagickFalse,exception);
10319           (void) SetImageMask(image,mask_image,exception);
10320           mask_image=DestroyImage(mask_image);
10321           break;
10322         }
10323         case 110:  /* Polaroid */
10324         {
10325           char
10326             *caption;
10327
10328           DrawInfo
10329             *draw_info;
10330
10331           double
10332             angle;
10333
10334           PixelInterpolateMethod
10335             method;
10336
10337           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10338             (DrawInfo *) NULL);
10339           caption=(char *) NULL;
10340           if (attribute_flag[0] != 0)
10341             caption=InterpretImageProperties(info ? info->image_info :
10342               (ImageInfo *) NULL,image,argument_list[0].string_reference,
10343               exception);
10344           angle=0.0;
10345           if (attribute_flag[1] != 0)
10346             angle=argument_list[1].real_reference;
10347           if (attribute_flag[2] != 0)
10348             (void) CloneString(&draw_info->font,
10349               argument_list[2].string_reference);
10350           if (attribute_flag[3] != 0)
10351             (void) QueryColorCompliance(argument_list[3].string_reference,
10352               AllCompliance,&draw_info->stroke,exception);
10353           if (attribute_flag[4] != 0)
10354             (void) QueryColorCompliance(argument_list[4].string_reference,
10355               AllCompliance,&draw_info->fill,exception);
10356           if (attribute_flag[5] != 0)
10357             draw_info->stroke_width=argument_list[5].real_reference;
10358           if (attribute_flag[6] != 0)
10359             draw_info->pointsize=argument_list[6].real_reference;
10360           if (attribute_flag[7] != 0)
10361             draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10362           if (attribute_flag[8] != 0)
10363             (void) QueryColorCompliance(argument_list[8].string_reference,
10364               AllCompliance,&image->background_color,exception);
10365           method=UndefinedInterpolatePixel;
10366           if (attribute_flag[9] != 0)
10367             method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10368           image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10369           draw_info=DestroyDrawInfo(draw_info);
10370           if (caption != (char *) NULL)
10371             caption=DestroyString(caption);
10372           break;
10373         }
10374         case 111:  /* FloodfillPaint */
10375         {
10376           DrawInfo
10377             *draw_info;
10378
10379           MagickBooleanType
10380             invert;
10381
10382           PixelInfo
10383             target;
10384
10385           draw_info=CloneDrawInfo(info ? info->image_info :
10386             (ImageInfo *) NULL,(DrawInfo *) NULL);
10387           if (attribute_flag[0] != 0)
10388             flags=ParsePageGeometry(image,argument_list[0].string_reference,
10389               &geometry,exception);
10390           if (attribute_flag[1] != 0)
10391             geometry.x=argument_list[1].integer_reference;
10392           if (attribute_flag[2] != 0)
10393             geometry.y=argument_list[2].integer_reference;
10394           if (attribute_flag[3] != 0)
10395             (void) QueryColorCompliance(argument_list[3].string_reference,
10396               AllCompliance,&draw_info->fill,exception);
10397           (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10398             geometry.x,geometry.y,&target,exception);
10399           if (attribute_flag[4] != 0)
10400             QueryColorCompliance(argument_list[4].string_reference,
10401               AllCompliance,&target,exception);
10402           if (attribute_flag[5] != 0)
10403             image->fuzz=StringToDoubleInterval(
10404               argument_list[5].string_reference,(double) QuantumRange+1.0);
10405           if (attribute_flag[6] != 0)
10406             channel=(ChannelType) argument_list[6].integer_reference;
10407           invert=MagickFalse;
10408           if (attribute_flag[7] != 0)
10409             invert=(MagickBooleanType) argument_list[7].integer_reference;
10410           channel_mask=SetImageChannelMask(image,channel);
10411           (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10412             geometry.y,invert,exception);
10413           (void) SetImageChannelMask(image,channel_mask);
10414           draw_info=DestroyDrawInfo(draw_info);
10415           break;
10416         }
10417         case 112:  /* Distort */
10418         {
10419           AV
10420             *av;
10421
10422           double
10423             *coordinates;
10424
10425           DistortImageMethod
10426             method;
10427
10428           size_t
10429             number_coordinates;
10430
10431           VirtualPixelMethod
10432             virtual_pixel;
10433
10434           if (attribute_flag[0] == 0)
10435             break;
10436           method=UndefinedDistortion;
10437           if (attribute_flag[1] != 0)
10438             method=(DistortImageMethod) argument_list[1].integer_reference;
10439           av=(AV *) argument_list[0].array_reference;
10440           number_coordinates=(size_t) av_len(av)+1;
10441           coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10442             sizeof(*coordinates));
10443           if (coordinates == (double *) NULL)
10444             {
10445               ThrowPerlException(exception,ResourceLimitFatalError,
10446                 "MemoryAllocationFailed",PackageName);
10447               goto PerlException;
10448             }
10449           for (j=0; j < (ssize_t) number_coordinates; j++)
10450             coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10451           virtual_pixel=UndefinedVirtualPixelMethod;
10452           if (attribute_flag[2] != 0)
10453             virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10454               argument_list[2].integer_reference,exception);
10455           image=DistortImage(image,method,number_coordinates,coordinates,
10456             argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10457             exception);
10458           if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10459             virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10460               exception);
10461           coordinates=(double *) RelinquishMagickMemory(coordinates);
10462           break;
10463         }
10464         case 113:  /* Clut */
10465         {
10466           PixelInterpolateMethod
10467             method;
10468
10469           if (attribute_flag[0] == 0)
10470             {
10471               ThrowPerlException(exception,OptionError,"ClutImageRequired",
10472                 PackageName);
10473               goto PerlException;
10474             }
10475           method=UndefinedInterpolatePixel;
10476           if (attribute_flag[1] != 0)
10477             method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10478           if (attribute_flag[2] != 0)
10479             channel=(ChannelType) argument_list[2].integer_reference;
10480           channel_mask=SetImageChannelMask(image,channel);
10481           (void) ClutImage(image,argument_list[0].image_reference,method,
10482             exception);
10483           (void) SetImageChannelMask(image,channel_mask);
10484           break;
10485         }
10486         case 114:  /* LiquidRescale */
10487         {
10488           if (attribute_flag[0] != 0)
10489             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10490               &geometry,exception);
10491           if (attribute_flag[1] != 0)
10492             geometry.width=argument_list[1].integer_reference;
10493           if (attribute_flag[2] != 0)
10494             geometry.height=argument_list[2].integer_reference;
10495           if (attribute_flag[3] == 0)
10496             argument_list[3].real_reference=1.0;
10497           if (attribute_flag[4] == 0)
10498             argument_list[4].real_reference=0.0;
10499           image=LiquidRescaleImage(image,geometry.width,geometry.height,
10500             argument_list[3].real_reference,argument_list[4].real_reference,
10501             exception);
10502           break;
10503         }
10504         case 115:  /* EncipherImage */
10505         {
10506           (void) EncipherImage(image,argument_list[0].string_reference,
10507             exception);
10508           break;
10509         }
10510         case 116:  /* DecipherImage */
10511         {
10512           (void) DecipherImage(image,argument_list[0].string_reference,
10513             exception);
10514           break;
10515         }
10516         case 117:  /* Deskew */
10517         {
10518           geometry_info.rho=QuantumRange/2.0;
10519           if (attribute_flag[0] != 0)
10520             flags=ParseGeometry(argument_list[0].string_reference,
10521               &geometry_info);
10522           if (attribute_flag[1] != 0)
10523             geometry_info.rho=StringToDoubleInterval(
10524               argument_list[1].string_reference,(double) QuantumRange+1.0);
10525           image=DeskewImage(image,geometry_info.rho,exception);
10526           break;
10527         }
10528         case 118:  /* Remap */
10529         {
10530           QuantizeInfo
10531             *quantize_info;
10532
10533           if (attribute_flag[0] == 0)
10534             {
10535               ThrowPerlException(exception,OptionError,"RemapImageRequired",
10536                 PackageName);
10537               goto PerlException;
10538             }
10539           quantize_info=AcquireQuantizeInfo(info->image_info);
10540           if (attribute_flag[1] != 0)
10541             quantize_info->dither_method=(DitherMethod)
10542               argument_list[1].integer_reference;
10543           (void) RemapImages(quantize_info,image,
10544             argument_list[0].image_reference,exception);
10545           quantize_info=DestroyQuantizeInfo(quantize_info);
10546           break;
10547         }
10548         case 119:  /* SparseColor */
10549         {
10550           AV
10551             *av;
10552
10553           double
10554             *coordinates;
10555
10556           SparseColorMethod
10557             method;
10558
10559           size_t
10560             number_coordinates;
10561
10562           VirtualPixelMethod
10563             virtual_pixel;
10564
10565           if (attribute_flag[0] == 0)
10566             break;
10567           method=UndefinedColorInterpolate;
10568           if (attribute_flag[1] != 0)
10569             method=(SparseColorMethod) argument_list[1].integer_reference;
10570           av=(AV *) argument_list[0].array_reference;
10571           number_coordinates=(size_t) av_len(av)+1;
10572           coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10573             sizeof(*coordinates));
10574           if (coordinates == (double *) NULL)
10575             {
10576               ThrowPerlException(exception,ResourceLimitFatalError,
10577                 "MemoryAllocationFailed",PackageName);
10578               goto PerlException;
10579             }
10580           for (j=0; j < (ssize_t) number_coordinates; j++)
10581             coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10582           virtual_pixel=UndefinedVirtualPixelMethod;
10583           if (attribute_flag[2] != 0)
10584             virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10585               argument_list[2].integer_reference,exception);
10586           if (attribute_flag[3] != 0)
10587             channel=(ChannelType) argument_list[3].integer_reference;
10588           channel_mask=SetImageChannelMask(image,channel);
10589           image=SparseColorImage(image,method,number_coordinates,coordinates,
10590             exception);
10591           if (image != (Image *) NULL)
10592             (void) SetImageChannelMask(image,channel_mask);
10593           if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10594             virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10595               exception);
10596           coordinates=(double *) RelinquishMagickMemory(coordinates);
10597           break;
10598         }
10599         case 120:  /* Function */
10600         {
10601           AV
10602             *av;
10603
10604           double
10605             *parameters;
10606
10607           MagickFunction
10608             function;
10609
10610           size_t
10611             number_parameters;
10612
10613           VirtualPixelMethod
10614             virtual_pixel;
10615
10616           if (attribute_flag[0] == 0)
10617             break;
10618           function=UndefinedFunction;
10619           if (attribute_flag[1] != 0)
10620             function=(MagickFunction) argument_list[1].integer_reference;
10621           av=(AV *) argument_list[0].array_reference;
10622           number_parameters=(size_t) av_len(av)+1;
10623           parameters=(double *) AcquireQuantumMemory(number_parameters,
10624             sizeof(*parameters));
10625           if (parameters == (double *) NULL)
10626             {
10627               ThrowPerlException(exception,ResourceLimitFatalError,
10628                 "MemoryAllocationFailed",PackageName);
10629               goto PerlException;
10630             }
10631           for (j=0; j < (ssize_t) number_parameters; j++)
10632             parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10633           virtual_pixel=UndefinedVirtualPixelMethod;
10634           if (attribute_flag[2] != 0)
10635             virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10636               argument_list[2].integer_reference,exception);
10637           (void) FunctionImage(image,function,number_parameters,parameters,
10638             exception);
10639           if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10640             virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10641               exception);
10642           parameters=(double *) RelinquishMagickMemory(parameters);
10643           break;
10644         }
10645         case 121:  /* SelectiveBlur */
10646         {
10647           if (attribute_flag[0] != 0)
10648             {
10649               flags=ParseGeometry(argument_list[0].string_reference,
10650                 &geometry_info);
10651               if ((flags & SigmaValue) == 0)
10652                 geometry_info.sigma=1.0;
10653               if ((flags & PercentValue) != 0)
10654                 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10655             }
10656           if (attribute_flag[1] != 0)
10657             geometry_info.rho=argument_list[1].real_reference;
10658           if (attribute_flag[2] != 0)
10659             geometry_info.sigma=argument_list[2].real_reference;
10660           if (attribute_flag[3] != 0)
10661             geometry_info.xi=argument_list[3].integer_reference;;
10662           if (attribute_flag[5] != 0)
10663             channel=(ChannelType) argument_list[5].integer_reference;
10664           channel_mask=SetImageChannelMask(image,channel);
10665           image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10666             geometry_info.xi,exception);
10667           if (image != (Image *) NULL)
10668             (void) SetImageChannelMask(image,channel_mask);
10669           break;
10670         }
10671         case 122:  /* HaldClut */
10672         {
10673           if (attribute_flag[0] == 0)
10674             {
10675               ThrowPerlException(exception,OptionError,"ClutImageRequired",
10676                 PackageName);
10677               goto PerlException;
10678             }
10679           if (attribute_flag[1] != 0)
10680             channel=(ChannelType) argument_list[1].integer_reference;
10681           channel_mask=SetImageChannelMask(image,channel);
10682           (void) HaldClutImage(image,argument_list[0].image_reference,
10683             exception);
10684           (void) SetImageChannelMask(image,channel_mask);
10685           break;
10686         }
10687         case 123:  /* BlueShift */
10688         {
10689           if (attribute_flag[0] != 0)
10690             (void) ParseGeometry(argument_list[0].string_reference,
10691               &geometry_info);
10692           image=BlueShiftImage(image,geometry_info.rho,exception);
10693           break;
10694         }
10695         case 124:  /* ForwardFourierTransformImage */
10696         {
10697           image=ForwardFourierTransformImage(image,
10698             argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10699             exception);
10700           break;
10701         }
10702         case 125:  /* InverseFourierTransformImage */
10703         {
10704           image=InverseFourierTransformImage(image,image->next,
10705             argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10706             exception);
10707           break;
10708         }
10709         case 126:  /* ColorDecisionList */
10710         {
10711           if (attribute_flag[0] == 0)
10712             argument_list[0].string_reference=(char *) NULL;
10713           (void) ColorDecisionListImage(image,
10714             argument_list[0].string_reference,exception);
10715           break;
10716         }
10717         case 127:  /* AutoGamma */
10718         {
10719           if (attribute_flag[0] != 0)
10720             channel=(ChannelType) argument_list[0].integer_reference;
10721           channel_mask=SetImageChannelMask(image,channel);
10722           (void) AutoGammaImage(image,exception);
10723           (void) SetImageChannelMask(image,channel_mask);
10724           break;
10725         }
10726         case 128:  /* AutoLevel */
10727         {
10728           if (attribute_flag[0] != 0)
10729             channel=(ChannelType) argument_list[0].integer_reference;
10730           channel_mask=SetImageChannelMask(image,channel);
10731           (void) AutoLevelImage(image,exception);
10732           (void) SetImageChannelMask(image,channel_mask);
10733           break;
10734         }
10735         case 129:  /* LevelColors */
10736         {
10737           PixelInfo
10738             black_point,
10739             white_point;
10740
10741           (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
10742             exception);
10743           (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
10744             exception);
10745           if (attribute_flag[1] != 0)
10746              (void) QueryColorCompliance(
10747                argument_list[1].string_reference,AllCompliance,&black_point,
10748                exception);
10749           if (attribute_flag[2] != 0)
10750              (void) QueryColorCompliance(
10751                argument_list[2].string_reference,AllCompliance,&white_point,
10752                exception);
10753           if (attribute_flag[3] != 0)
10754             channel=(ChannelType) argument_list[3].integer_reference;
10755           channel_mask=SetImageChannelMask(image,channel);
10756           (void) LevelImageColors(image,&black_point,&white_point,
10757             argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10758             exception);
10759           (void) SetImageChannelMask(image,channel_mask);
10760           break;
10761         }
10762         case 130:  /* Clamp */
10763         {
10764           if (attribute_flag[0] != 0)
10765             channel=(ChannelType) argument_list[0].integer_reference;
10766           channel_mask=SetImageChannelMask(image,channel);
10767           (void) ClampImage(image,exception);
10768           (void) SetImageChannelMask(image,channel_mask);
10769           break;
10770         }
10771         case 131:  /* BrightnessContrast */
10772         {
10773           double
10774             brightness,
10775             contrast;
10776
10777           brightness=0.0;
10778           contrast=0.0;
10779           if (attribute_flag[0] != 0)
10780             {
10781               flags=ParseGeometry(argument_list[0].string_reference,
10782                 &geometry_info);
10783               brightness=geometry_info.rho;
10784               if ((flags & SigmaValue) == 0)
10785                 contrast=geometry_info.sigma;
10786             }
10787           if (attribute_flag[1] != 0)
10788             brightness=argument_list[1].real_reference;
10789           if (attribute_flag[2] != 0)
10790             contrast=argument_list[2].real_reference;
10791           if (attribute_flag[4] != 0)
10792             channel=(ChannelType) argument_list[4].integer_reference;
10793           channel_mask=SetImageChannelMask(image,channel);
10794           (void) BrightnessContrastImage(image,brightness,contrast,exception);
10795           (void) SetImageChannelMask(image,channel_mask);
10796           break;
10797         }
10798         case 132:  /* Morphology */
10799         {
10800           KernelInfo
10801             *kernel;
10802
10803           MorphologyMethod
10804             method;
10805
10806           ssize_t
10807             iterations;
10808
10809           if (attribute_flag[0] == 0)
10810             break;
10811           kernel=AcquireKernelInfo(argument_list[0].string_reference);
10812           if (kernel == (KernelInfo *) NULL)
10813             break;
10814           if (attribute_flag[1] != 0)
10815             channel=(ChannelType) argument_list[1].integer_reference;
10816           method=UndefinedMorphology;
10817           if (attribute_flag[2] != 0)
10818             method=argument_list[2].integer_reference;
10819           iterations=1;
10820           if (attribute_flag[3] != 0)
10821             iterations=argument_list[3].integer_reference;
10822           channel_mask=SetImageChannelMask(image,channel);
10823           image=MorphologyImage(image,method,iterations,kernel,exception);
10824           if (image != (Image *) NULL)
10825             (void) SetImageChannelMask(image,channel_mask);
10826           kernel=DestroyKernelInfo(kernel);
10827           break;
10828         }
10829         case 133:  /* Mode */
10830         {
10831           if (attribute_flag[0] != 0)
10832             {
10833               flags=ParseGeometry(argument_list[0].string_reference,
10834                 &geometry_info);
10835               if ((flags & SigmaValue) == 0)
10836                 geometry_info.sigma=1.0;
10837             }
10838           if (attribute_flag[1] != 0)
10839             geometry_info.rho=argument_list[1].real_reference;
10840           if (attribute_flag[2] != 0)
10841             geometry_info.sigma=argument_list[2].real_reference;
10842           if (attribute_flag[3] != 0)
10843             channel=(ChannelType) argument_list[3].integer_reference;
10844           channel_mask=SetImageChannelMask(image,channel);
10845           image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
10846             (size_t) geometry_info.sigma,exception);
10847           if (image != (Image *) NULL)
10848             (void) SetImageChannelMask(image,channel_mask);
10849           break;
10850         }
10851         case 134:  /* Statistic */
10852         {
10853           StatisticType
10854             statistic;
10855
10856           statistic=UndefinedStatistic;
10857           if (attribute_flag[0] != 0)
10858             {
10859               flags=ParseGeometry(argument_list[0].string_reference,
10860                 &geometry_info);
10861               if ((flags & SigmaValue) == 0)
10862                 geometry_info.sigma=1.0;
10863             }
10864           if (attribute_flag[1] != 0)
10865             geometry_info.rho=argument_list[1].real_reference;
10866           if (attribute_flag[2] != 0)
10867             geometry_info.sigma=argument_list[2].real_reference;
10868           if (attribute_flag[3] != 0)
10869             channel=(ChannelType) argument_list[3].integer_reference;
10870           if (attribute_flag[4] != 0)
10871             statistic=(StatisticType) argument_list[4].integer_reference;
10872           channel_mask=SetImageChannelMask(image,channel);
10873           image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
10874             (size_t) geometry_info.sigma,exception);
10875           if (image != (Image *) NULL)
10876             (void) SetImageChannelMask(image,channel_mask);
10877           break;
10878         }
10879         case 135:  /* Perceptible */
10880         {
10881           double
10882             epsilon;
10883
10884           epsilon=MagickEpsilon;
10885           if (attribute_flag[0] != 0)
10886             epsilon=argument_list[0].real_reference;
10887           if (attribute_flag[1] != 0)
10888             channel=(ChannelType) argument_list[1].integer_reference;
10889           channel_mask=SetImageChannelMask(image,channel);
10890           (void) PerceptibleImage(image,epsilon,exception);
10891           (void) SetImageChannelMask(image,channel_mask);
10892           break;
10893         }
10894         case 136:  /* Poly */
10895         {
10896           AV
10897             *av;
10898
10899           double
10900             *terms;
10901
10902           size_t
10903             number_terms;
10904
10905           if (attribute_flag[0] == 0)
10906             break;
10907           if (attribute_flag[1] != 0)
10908             channel=(ChannelType) argument_list[1].integer_reference;
10909           av=(AV *) argument_list[0].array_reference;
10910           number_terms=(size_t) av_len(av);
10911           terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
10912           if (terms == (double *) NULL)
10913             {
10914               ThrowPerlException(exception,ResourceLimitFatalError,
10915                 "MemoryAllocationFailed",PackageName);
10916               goto PerlException;
10917             }
10918           for (j=0; j < av_len(av); j++)
10919             terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
10920           image=PolynomialImage(image,number_terms >> 1,terms,exception);
10921           terms=(double *) RelinquishMagickMemory(terms);
10922           break;
10923         }
10924       }
10925       if (next != (Image *) NULL)
10926         (void) CatchImageException(next);
10927       if (region_image != (Image *) NULL)
10928         {
10929           /*
10930             Composite region.
10931           */ 
10932           status=CompositeImage(region_image,image,CopyCompositeOp,MagickTrue,
10933             region_info.x,region_info.y,exception);
10934           (void) status;
10935           (void) CatchImageException(region_image);
10936           image=DestroyImage(image);
10937           image=region_image;
10938         }
10939       if (image != (Image *) NULL)
10940         {
10941           number_images++;
10942           if (next && (next != image))
10943             {
10944               image->next=next->next;
10945               if (image->next != (Image *) NULL)
10946                 image->next->previous=image;
10947               DeleteImageFromRegistry(*pv,next);
10948             }
10949           sv_setiv(*pv,PTR2IV(image));
10950           next=image;
10951         }
10952       if (*pv)
10953         pv++;
10954     }
10955
10956   PerlException:
10957     if (reference_vector)
10958       reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
10959     InheritPerlException(exception,perl_exception);
10960     exception=DestroyExceptionInfo(exception);
10961     sv_setiv(perl_exception,(IV) number_images);
10962     SvPOK_on(perl_exception);
10963     ST(0)=sv_2mortal(perl_exception);
10964     XSRETURN(1);
10965   }
10966 \f
10967 #
10968 ###############################################################################
10969 #                                                                             #
10970 #                                                                             #
10971 #                                                                             #
10972 #   M o n t a g e                                                             #
10973 #                                                                             #
10974 #                                                                             #
10975 #                                                                             #
10976 ###############################################################################
10977 #
10978 #
10979 void
10980 Montage(ref,...)
10981   Image::Magick::Q16HDRI ref=NO_INIT
10982   ALIAS:
10983     MontageImage  = 1
10984     montage       = 2
10985     montageimage  = 3
10986   PPCODE:
10987   {
10988     AV
10989       *av;
10990
10991     char
10992       *attribute;
10993
10994     ExceptionInfo
10995       *exception;
10996
10997     HV
10998       *hv;
10999
11000     Image
11001       *image,
11002       *next;
11003
11004     PixelInfo
11005       transparent_color;
11006
11007     MontageInfo
11008       *montage_info;
11009
11010     register ssize_t
11011       i;
11012
11013     ssize_t
11014       sp;
11015
11016     struct PackageInfo
11017       *info;
11018
11019     SV
11020       *av_reference,
11021       *perl_exception,
11022       *reference,
11023       *rv,
11024       *sv;
11025
11026     PERL_UNUSED_VAR(ref);
11027     PERL_UNUSED_VAR(ix);
11028     exception=AcquireExceptionInfo();
11029     perl_exception=newSVpv("",0);
11030     sv=NULL;
11031     attribute=NULL;
11032     if (sv_isobject(ST(0)) == 0)
11033       {
11034         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11035           PackageName);
11036         goto PerlException;
11037       }
11038     reference=SvRV(ST(0));
11039     hv=SvSTASH(reference);
11040     av=newAV();
11041     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11042     SvREFCNT_dec(av);
11043     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11044     if (image == (Image *) NULL)
11045       {
11046         ThrowPerlException(exception,OptionError,"NoImagesDefined",
11047           PackageName);
11048         goto PerlException;
11049       }
11050     /*
11051       Get options.
11052     */
11053     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11054     montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11055     (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11056       exception);
11057     for (i=2; i < items; i+=2)
11058     {
11059       attribute=(char *) SvPV(ST(i-1),na);
11060       switch (*attribute)
11061       {
11062         case 'B':
11063         case 'b':
11064         {
11065           if (LocaleCompare(attribute,"background") == 0)
11066             {
11067               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11068                 &montage_info->background_color,exception);
11069               for (next=image; next; next=next->next)
11070                 next->background_color=montage_info->background_color;
11071               break;
11072             }
11073           if (LocaleCompare(attribute,"border") == 0)
11074             {
11075               montage_info->border_width=SvIV(ST(i));
11076               break;
11077             }
11078           if (LocaleCompare(attribute,"bordercolor") == 0)
11079             {
11080               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11081                 &montage_info->border_color,exception);
11082               for (next=image; next; next=next->next)
11083                 next->border_color=montage_info->border_color;
11084               break;
11085             }
11086           if (LocaleCompare(attribute,"borderwidth") == 0)
11087             {
11088               montage_info->border_width=SvIV(ST(i));
11089               break;
11090             }
11091           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11092             attribute);
11093           break;
11094         }
11095         case 'C':
11096         case 'c':
11097         {
11098           if (LocaleCompare(attribute,"compose") == 0)
11099             {
11100               sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11101                 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11102               if (sp < 0)
11103                 {
11104                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
11105                     SvPV(ST(i),na));
11106                   break;
11107                 }
11108               for (next=image; next; next=next->next)
11109                 next->compose=(CompositeOperator) sp;
11110               break;
11111             }
11112           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11113             attribute);
11114           break;
11115         }
11116         case 'F':
11117         case 'f':
11118         {
11119           if (LocaleCompare(attribute,"fill") == 0)
11120             {
11121               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11122                 &montage_info->fill,exception);
11123               break;
11124             }
11125           if (LocaleCompare(attribute,"font") == 0)
11126             {
11127               (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11128               break;
11129             }
11130           if (LocaleCompare(attribute,"frame") == 0)
11131             {
11132               char
11133                 *p;
11134
11135               p=SvPV(ST(i),na);
11136               if (IsGeometry(p) == MagickFalse)
11137                 {
11138                   ThrowPerlException(exception,OptionError,"MissingGeometry",
11139                     p);
11140                   break;
11141                 }
11142               (void) CloneString(&montage_info->frame,p);
11143               if (*p == '\0')
11144                 montage_info->frame=(char *) NULL;
11145               break;
11146             }
11147           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11148             attribute);
11149           break;
11150         }
11151         case 'G':
11152         case 'g':
11153         {
11154           if (LocaleCompare(attribute,"geometry") == 0)
11155             {
11156               char
11157                 *p;
11158
11159               p=SvPV(ST(i),na);
11160               if (IsGeometry(p) == MagickFalse)
11161                 {
11162                   ThrowPerlException(exception,OptionError,"MissingGeometry",
11163                     p);
11164                   break;
11165                 }
11166              (void) CloneString(&montage_info->geometry,p);
11167              if (*p == '\0')
11168                montage_info->geometry=(char *) NULL;
11169              break;
11170            }
11171          if (LocaleCompare(attribute,"gravity") == 0)
11172            {
11173              ssize_t
11174                in;
11175
11176              in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11177                MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11178              if (in < 0)
11179                {
11180                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
11181                    SvPV(ST(i),na));
11182                  return;
11183                }
11184              montage_info->gravity=(GravityType) in;
11185              for (next=image; next; next=next->next)
11186                next->gravity=(GravityType) in;
11187              break;
11188            }
11189           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11190             attribute);
11191           break;
11192         }
11193         case 'L':
11194         case 'l':
11195         {
11196           if (LocaleCompare(attribute,"label") == 0)
11197             {
11198               for (next=image; next; next=next->next)
11199                 (void) SetImageProperty(next,"label",InterpretImageProperties(
11200                   info ? info->image_info : (ImageInfo *) NULL,next,
11201                   SvPV(ST(i),na),exception),exception);
11202               break;
11203             }
11204           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11205             attribute);
11206           break;
11207         }
11208         case 'M':
11209         case 'm':
11210         {
11211           if (LocaleCompare(attribute,"mattecolor") == 0)
11212             {
11213               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11214                 &montage_info->matte_color,exception);
11215               for (next=image; next; next=next->next)
11216                 next->matte_color=montage_info->matte_color;
11217               break;
11218             }
11219           if (LocaleCompare(attribute,"mode") == 0)
11220             {
11221               ssize_t
11222                 in;
11223
11224               in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11225                 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11226               switch (in)
11227               {
11228                 default:
11229                 {
11230                   ThrowPerlException(exception,OptionError,
11231                     "UnrecognizedModeType",SvPV(ST(i),na));
11232                   break;
11233                 }
11234                 case FrameMode:
11235                 {
11236                   (void) CloneString(&montage_info->frame,"15x15+3+3");
11237                   montage_info->shadow=MagickTrue;
11238                   break;
11239                 }
11240                 case UnframeMode:
11241                 {
11242                   montage_info->frame=(char *) NULL;
11243                   montage_info->shadow=MagickFalse;
11244                   montage_info->border_width=0;
11245                   break;
11246                 }
11247                 case ConcatenateMode:
11248                 {
11249                   montage_info->frame=(char *) NULL;
11250                   montage_info->shadow=MagickFalse;
11251                   (void) CloneString(&montage_info->geometry,"+0+0");
11252                   montage_info->border_width=0;
11253                 }
11254               }
11255               break;
11256             }
11257           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11258             attribute);
11259           break;
11260         }
11261         case 'P':
11262         case 'p':
11263         {
11264           if (LocaleCompare(attribute,"pointsize") == 0)
11265             {
11266               montage_info->pointsize=SvIV(ST(i));
11267               break;
11268             }
11269           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11270             attribute);
11271           break;
11272         }
11273         case 'S':
11274         case 's':
11275         {
11276           if (LocaleCompare(attribute,"shadow") == 0)
11277             {
11278               sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11279                 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11280               if (sp < 0)
11281                 {
11282                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
11283                     SvPV(ST(i),na));
11284                   break;
11285                 }
11286              montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11287              break;
11288             }
11289           if (LocaleCompare(attribute,"stroke") == 0)
11290             {
11291               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11292                 &montage_info->stroke,exception);
11293               break;
11294             }
11295           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11296             attribute);
11297           break;
11298         }
11299         case 'T':
11300         case 't':
11301         {
11302           if (LocaleCompare(attribute,"texture") == 0)
11303             {
11304               (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11305               break;
11306             }
11307           if (LocaleCompare(attribute,"tile") == 0)
11308             {
11309               char *p=SvPV(ST(i),na);
11310               if (IsGeometry(p) == MagickFalse)
11311                 {
11312                   ThrowPerlException(exception,OptionError,"MissingGeometry",
11313                     p);
11314                   break;
11315                 }
11316               (void) CloneString(&montage_info->tile,p);
11317               if (*p == '\0')
11318                 montage_info->tile=(char *) NULL;
11319               break;
11320             }
11321           if (LocaleCompare(attribute,"title") == 0)
11322             {
11323               (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11324               break;
11325             }
11326           if (LocaleCompare(attribute,"transparent") == 0)
11327             {
11328               PixelInfo
11329                 transparent_color;
11330
11331               QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11332                 &transparent_color,exception);
11333               for (next=image; next; next=next->next)
11334                 (void) TransparentPaintImage(next,&transparent_color,
11335                   TransparentAlpha,MagickFalse,exception);
11336               break;
11337             }
11338           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11339             attribute);
11340           break;
11341         }
11342         default:
11343         {
11344           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11345             attribute);
11346           break;
11347         }
11348       }
11349     }
11350     image=MontageImageList(info->image_info,montage_info,image,exception);
11351     montage_info=DestroyMontageInfo(montage_info);
11352     if (image == (Image *) NULL)
11353       goto PerlException;
11354     if (transparent_color.alpha != TransparentAlpha)
11355       for (next=image; next; next=next->next)
11356         (void) TransparentPaintImage(next,&transparent_color,
11357           TransparentAlpha,MagickFalse,exception);
11358     for (  ; image; image=image->next)
11359     {
11360       AddImageToRegistry(sv,image);
11361       rv=newRV(sv);
11362       av_push(av,sv_bless(rv,hv));
11363       SvREFCNT_dec(sv);
11364     }
11365     exception=DestroyExceptionInfo(exception);
11366     ST(0)=av_reference;
11367     SvREFCNT_dec(perl_exception);
11368     XSRETURN(1);
11369
11370   PerlException:
11371     InheritPerlException(exception,perl_exception);
11372     exception=DestroyExceptionInfo(exception);
11373     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11374     SvPOK_on(perl_exception);
11375     ST(0)=sv_2mortal(perl_exception);
11376     XSRETURN(1);
11377   }
11378 \f
11379 #
11380 ###############################################################################
11381 #                                                                             #
11382 #                                                                             #
11383 #                                                                             #
11384 #   M o r p h                                                                 #
11385 #                                                                             #
11386 #                                                                             #
11387 #                                                                             #
11388 ###############################################################################
11389 #
11390 #
11391 void
11392 Morph(ref,...)
11393   Image::Magick::Q16HDRI ref=NO_INIT
11394   ALIAS:
11395     MorphImage  = 1
11396     morph       = 2
11397     morphimage  = 3
11398   PPCODE:
11399   {
11400     AV
11401       *av;
11402
11403     char
11404       *attribute;
11405
11406     ExceptionInfo
11407       *exception;
11408
11409     HV
11410       *hv;
11411
11412     Image
11413       *image;
11414
11415     register ssize_t
11416       i;
11417
11418     ssize_t
11419       number_frames;
11420
11421     struct PackageInfo
11422       *info;
11423
11424     SV
11425       *av_reference,
11426       *perl_exception,
11427       *reference,
11428       *rv,
11429       *sv;
11430
11431     PERL_UNUSED_VAR(ref);
11432     PERL_UNUSED_VAR(ix);
11433     exception=AcquireExceptionInfo();
11434     perl_exception=newSVpv("",0);
11435     sv=NULL;
11436     av=NULL;
11437     attribute=NULL;
11438     if (sv_isobject(ST(0)) == 0)
11439       {
11440         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11441           PackageName);
11442         goto PerlException;
11443       }
11444     reference=SvRV(ST(0));
11445     hv=SvSTASH(reference);
11446     av=newAV();
11447     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11448     SvREFCNT_dec(av);
11449     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11450     if (image == (Image *) NULL)
11451       {
11452         ThrowPerlException(exception,OptionError,"NoImagesDefined",
11453           PackageName);
11454         goto PerlException;
11455       }
11456     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11457     /*
11458       Get attribute.
11459     */
11460     number_frames=30;
11461     for (i=2; i < items; i+=2)
11462     {
11463       attribute=(char *) SvPV(ST(i-1),na);
11464       switch (*attribute)
11465       {
11466         case 'F':
11467         case 'f':
11468         {
11469           if (LocaleCompare(attribute,"frames") == 0)
11470             {
11471               number_frames=SvIV(ST(i));
11472               break;
11473             }
11474           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11475             attribute);
11476           break;
11477         }
11478         default:
11479         {
11480           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11481             attribute);
11482           break;
11483         }
11484       }
11485     }
11486     image=MorphImages(image,number_frames,exception);
11487     if (image == (Image *) NULL)
11488       goto PerlException;
11489     for ( ; image; image=image->next)
11490     {
11491       AddImageToRegistry(sv,image);
11492       rv=newRV(sv);
11493       av_push(av,sv_bless(rv,hv));
11494       SvREFCNT_dec(sv);
11495     }
11496     exception=DestroyExceptionInfo(exception);
11497     ST(0)=av_reference;
11498     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
11499     XSRETURN(1);
11500
11501   PerlException:
11502     InheritPerlException(exception,perl_exception);
11503     exception=DestroyExceptionInfo(exception);
11504     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11505     SvPOK_on(perl_exception);
11506     ST(0)=sv_2mortal(perl_exception);
11507     XSRETURN(1);
11508   }
11509 \f
11510 #
11511 ###############################################################################
11512 #                                                                             #
11513 #                                                                             #
11514 #                                                                             #
11515 #   M o s a i c                                                               #
11516 #                                                                             #
11517 #                                                                             #
11518 #                                                                             #
11519 ###############################################################################
11520 #
11521 #
11522 void
11523 Mosaic(ref)
11524   Image::Magick::Q16HDRI ref=NO_INIT
11525   ALIAS:
11526     MosaicImage   = 1
11527     mosaic        = 2
11528     mosaicimage   = 3
11529   PPCODE:
11530   {
11531     AV
11532       *av;
11533
11534     ExceptionInfo
11535       *exception;
11536
11537     HV
11538       *hv;
11539
11540     Image
11541       *image;
11542
11543     struct PackageInfo
11544       *info;
11545
11546     SV
11547       *perl_exception,
11548       *reference,
11549       *rv,
11550       *sv;
11551
11552     PERL_UNUSED_VAR(ref);
11553     PERL_UNUSED_VAR(ix);
11554     exception=AcquireExceptionInfo();
11555     perl_exception=newSVpv("",0);
11556     sv=NULL;
11557     if (sv_isobject(ST(0)) == 0)
11558       {
11559         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11560           PackageName);
11561         goto PerlException;
11562       }
11563     reference=SvRV(ST(0));
11564     hv=SvSTASH(reference);
11565     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11566     if (image == (Image *) NULL)
11567       {
11568         ThrowPerlException(exception,OptionError,"NoImagesDefined",
11569           PackageName);
11570         goto PerlException;
11571       }
11572     image=MergeImageLayers(image,MosaicLayer,exception);
11573     /*
11574       Create blessed Perl array for the returned image.
11575     */
11576     av=newAV();
11577     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11578     SvREFCNT_dec(av);
11579     AddImageToRegistry(sv,image);
11580     rv=newRV(sv);
11581     av_push(av,sv_bless(rv,hv));
11582     SvREFCNT_dec(sv);
11583     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11584     (void) CopyMagickString(info->image_info->filename,image->filename,
11585       MaxTextExtent);
11586     SetImageInfo(info->image_info,0,exception);
11587     exception=DestroyExceptionInfo(exception);
11588     SvREFCNT_dec(perl_exception);
11589     XSRETURN(1);
11590
11591   PerlException:
11592     InheritPerlException(exception,perl_exception);
11593     exception=DestroyExceptionInfo(exception);
11594     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11595     SvPOK_on(perl_exception);  /* return messages in string context */
11596     ST(0)=sv_2mortal(perl_exception);
11597     XSRETURN(1);
11598   }
11599 \f
11600 #
11601 ###############################################################################
11602 #                                                                             #
11603 #                                                                             #
11604 #                                                                             #
11605 #   P i n g                                                                   #
11606 #                                                                             #
11607 #                                                                             #
11608 #                                                                             #
11609 ###############################################################################
11610 #
11611 #
11612 void
11613 Ping(ref,...)
11614   Image::Magick::Q16HDRI ref=NO_INIT
11615   ALIAS:
11616     PingImage  = 1
11617     ping       = 2
11618     pingimage  = 3
11619   PPCODE:
11620   {
11621     AV
11622       *av;
11623
11624     char
11625       **keep,
11626       **list;
11627
11628     ExceptionInfo
11629       *exception;
11630
11631     Image
11632       *image,
11633       *next;
11634
11635     int
11636       n;
11637
11638     MagickBooleanType
11639       status;
11640
11641     register char
11642       **p;
11643
11644     register ssize_t
11645       i;
11646
11647     ssize_t
11648       ac;
11649
11650     STRLEN
11651       *length;
11652
11653     struct PackageInfo
11654       *info,
11655       *package_info;
11656
11657     SV
11658       *perl_exception,
11659       *reference;
11660
11661     size_t
11662       count;
11663
11664     PERL_UNUSED_VAR(ref);
11665     PERL_UNUSED_VAR(ix);
11666     exception=AcquireExceptionInfo();
11667     perl_exception=newSVpv("",0);
11668     package_info=(struct PackageInfo *) NULL;
11669     ac=(items < 2) ? 1 : items-1;
11670     list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
11671     keep=list;
11672     length=(STRLEN *) NULL;
11673     if (list == (char **) NULL)
11674       {
11675         ThrowPerlException(exception,ResourceLimitError,
11676           "MemoryAllocationFailed",PackageName);
11677         goto PerlException;
11678       }
11679     keep=list;
11680     length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
11681     if (length == (STRLEN *) NULL)
11682       {
11683         ThrowPerlException(exception,ResourceLimitError,
11684           "MemoryAllocationFailed",PackageName);
11685         goto PerlException;
11686       }
11687     if (sv_isobject(ST(0)) == 0)
11688       {
11689         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11690           PackageName);
11691         goto PerlException;
11692       }
11693     reference=SvRV(ST(0));
11694     if (SvTYPE(reference) != SVt_PVAV)
11695       {
11696         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11697           PackageName);
11698         goto PerlException;
11699       }
11700     av=(AV *) reference;
11701     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
11702       exception);
11703     package_info=ClonePackageInfo(info,exception);
11704     n=1;
11705     if (items <= 1)
11706       *list=(char *) (*package_info->image_info->filename ?
11707         package_info->image_info->filename : "XC:black");
11708     else
11709       for (n=0, i=0; i < ac; i++)
11710       {
11711         list[n]=(char *) SvPV(ST(i+1),length[n]);
11712         if ((items >= 3) && strEQcase(list[n],"blob"))
11713           {
11714             void
11715               *blob;
11716
11717             i++;
11718             blob=(void *) (SvPV(ST(i+1),length[n]));
11719             SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
11720           }
11721         if ((items >= 3) && strEQcase(list[n],"filename"))
11722           continue;
11723         if ((items >= 3) && strEQcase(list[n],"file"))
11724           {
11725             FILE
11726               *file;
11727
11728             PerlIO
11729               *io_info;
11730
11731             i++;
11732             io_info=IoIFP(sv_2io(ST(i+1)));
11733             if (io_info == (PerlIO *) NULL)
11734               {
11735                 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
11736                   PackageName);
11737                 continue;
11738               }
11739             file=PerlIO_findFILE(io_info);
11740             if (file == (FILE *) NULL)
11741               {
11742                 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
11743                   PackageName);
11744                 continue;
11745               }
11746             SetImageInfoFile(package_info->image_info,file);
11747           }
11748         if ((items >= 3) && strEQcase(list[n],"magick"))
11749           continue;
11750         n++;
11751       }
11752     list[n]=(char *) NULL;
11753     keep=list;
11754     status=ExpandFilenames(&n,&list);
11755     if (status == MagickFalse)
11756       {
11757         ThrowPerlException(exception,ResourceLimitError,
11758           "MemoryAllocationFailed",PackageName);
11759         goto PerlException;
11760       }
11761     count=0;
11762     for (i=0; i < n; i++)
11763     {
11764       (void) CopyMagickString(package_info->image_info->filename,list[i],
11765         MaxTextExtent);
11766       image=PingImage(package_info->image_info,exception);
11767       if (image == (Image *) NULL)
11768         break;
11769       if ((package_info->image_info->file != (FILE *) NULL) ||
11770           (package_info->image_info->blob != (void *) NULL))
11771         DisassociateImageStream(image);
11772       count+=GetImageListLength(image);
11773       EXTEND(sp,4*count);
11774       for (next=image; next; next=next->next)
11775       {
11776         PUSHs(sv_2mortal(newSViv(next->columns)));
11777         PUSHs(sv_2mortal(newSViv(next->rows)));
11778         PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
11779         PUSHs(sv_2mortal(newSVpv(next->magick,0)));
11780       }
11781       image=DestroyImageList(image);
11782     }
11783     /*
11784       Free resources.
11785     */
11786     for (i=0; i < n; i++)
11787       if (list[i] != (char *) NULL)
11788         for (p=keep; list[i] != *p++; )
11789           if (*p == NULL)
11790             {
11791               list[i]=(char *) RelinquishMagickMemory(list[i]);
11792               break;
11793             }
11794
11795   PerlException:
11796     if (package_info != (struct PackageInfo *) NULL)
11797       DestroyPackageInfo(package_info);
11798     if (list && (list != keep))
11799       list=(char **) RelinquishMagickMemory(list);
11800     if (keep)
11801       keep=(char **) RelinquishMagickMemory(keep);
11802     if (length)
11803       length=(STRLEN *) RelinquishMagickMemory(length);
11804     InheritPerlException(exception,perl_exception);
11805     exception=DestroyExceptionInfo(exception);
11806     SvREFCNT_dec(perl_exception);  /* throw away all errors */
11807   }
11808 \f
11809 #
11810 ###############################################################################
11811 #                                                                             #
11812 #                                                                             #
11813 #                                                                             #
11814 #   P r e v i e w                                                             #
11815 #                                                                             #
11816 #                                                                             #
11817 #                                                                             #
11818 ###############################################################################
11819 #
11820 #
11821 void
11822 Preview(ref,...)
11823   Image::Magick::Q16HDRI ref=NO_INIT
11824   ALIAS:
11825     PreviewImage = 1
11826     preview      = 2
11827     previewimage = 3
11828   PPCODE:
11829   {
11830     AV
11831       *av;
11832
11833     ExceptionInfo
11834       *exception;
11835
11836     HV
11837       *hv;
11838
11839     Image
11840       *image,
11841       *preview_image;
11842
11843     PreviewType
11844       preview_type;
11845
11846     struct PackageInfo
11847       *info;
11848
11849     SV
11850       *av_reference,
11851       *perl_exception,
11852       *reference,
11853       *rv,
11854       *sv;
11855
11856     PERL_UNUSED_VAR(ref);
11857     PERL_UNUSED_VAR(ix);
11858     exception=AcquireExceptionInfo();
11859     perl_exception=newSVpv("",0);
11860     sv=NULL;
11861     av=NULL;
11862     if (sv_isobject(ST(0)) == 0)
11863       {
11864         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11865           PackageName);
11866         goto PerlException;
11867       }
11868     reference=SvRV(ST(0));
11869     hv=SvSTASH(reference);
11870     av=newAV();
11871     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11872     SvREFCNT_dec(av);
11873     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11874     if (image == (Image *) NULL)
11875       {
11876         ThrowPerlException(exception,OptionError,"NoImagesDefined",
11877           PackageName);
11878         goto PerlException;
11879       }
11880     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11881     preview_type=GammaPreview;
11882     if (items > 1)
11883       preview_type=(PreviewType)
11884         ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
11885     for ( ; image; image=image->next)
11886     {
11887       preview_image=PreviewImage(image,preview_type,exception);
11888       if (preview_image == (Image *) NULL)
11889         goto PerlException;
11890       AddImageToRegistry(sv,preview_image);
11891       rv=newRV(sv);
11892       av_push(av,sv_bless(rv,hv));
11893       SvREFCNT_dec(sv);
11894     }
11895     exception=DestroyExceptionInfo(exception);
11896     ST(0)=av_reference;
11897     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
11898     XSRETURN(1);
11899
11900   PerlException:
11901     InheritPerlException(exception,perl_exception);
11902     exception=DestroyExceptionInfo(exception);
11903     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11904     SvPOK_on(perl_exception);
11905     ST(0)=sv_2mortal(perl_exception);
11906     XSRETURN(1);
11907   }
11908 \f
11909 #
11910 ###############################################################################
11911 #                                                                             #
11912 #                                                                             #
11913 #                                                                             #
11914 #   Q u e r y C o l o r                                                       #
11915 #                                                                             #
11916 #                                                                             #
11917 #                                                                             #
11918 ###############################################################################
11919 #
11920 #
11921 void
11922 QueryColor(ref,...)
11923   Image::Magick::Q16HDRI ref=NO_INIT
11924   ALIAS:
11925     querycolor = 1
11926   PPCODE:
11927   {
11928     char
11929       *name;
11930
11931     ExceptionInfo
11932       *exception;
11933
11934     PixelInfo
11935       color;
11936
11937     register ssize_t
11938       i;
11939
11940     SV
11941       *perl_exception;
11942
11943     PERL_UNUSED_VAR(ref);
11944     PERL_UNUSED_VAR(ix);
11945     exception=AcquireExceptionInfo();
11946     perl_exception=newSVpv("",0);
11947     if (items == 1)
11948       {
11949         const ColorInfo
11950           **colorlist;
11951
11952         size_t
11953           colors;
11954
11955         colorlist=GetColorInfoList("*",&colors,exception);
11956         EXTEND(sp,colors);
11957         for (i=0; i < (ssize_t) colors; i++)
11958         {
11959           PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
11960         }
11961         colorlist=(const ColorInfo **)
11962           RelinquishMagickMemory((ColorInfo **) colorlist);
11963         goto PerlException;
11964       }
11965     EXTEND(sp,5*items);
11966     for (i=1; i < items; i++)
11967     {
11968       name=(char *) SvPV(ST(i),na);
11969       if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
11970         {
11971           PUSHs(&sv_undef);
11972           continue;
11973         }
11974       PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
11975       PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
11976       PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
11977       if (color.colorspace == CMYKColorspace)
11978         PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
11979       if (color.alpha_trait == BlendPixelTrait)
11980         PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
11981     }
11982
11983   PerlException:
11984     InheritPerlException(exception,perl_exception);
11985     exception=DestroyExceptionInfo(exception);
11986     SvREFCNT_dec(perl_exception);
11987   }
11988 \f
11989 #
11990 ###############################################################################
11991 #                                                                             #
11992 #                                                                             #
11993 #                                                                             #
11994 #   Q u e r y C o l o r N a m e                                               #
11995 #                                                                             #
11996 #                                                                             #
11997 #                                                                             #
11998 ###############################################################################
11999 #
12000 #
12001 void
12002 QueryColorname(ref,...)
12003   Image::Magick::Q16HDRI ref=NO_INIT
12004   ALIAS:
12005     querycolorname = 1
12006   PPCODE:
12007   {
12008     AV
12009       *av;
12010
12011     char
12012       message[MaxTextExtent];
12013
12014     ExceptionInfo
12015       *exception;
12016
12017     Image
12018       *image;
12019
12020     PixelInfo
12021       target_color;
12022
12023     register ssize_t
12024       i;
12025
12026     struct PackageInfo
12027       *info;
12028
12029     SV
12030       *perl_exception,
12031       *reference;  /* reference is the SV* of ref=SvIV(reference) */
12032
12033     PERL_UNUSED_VAR(ref);
12034     PERL_UNUSED_VAR(ix);
12035     exception=AcquireExceptionInfo();
12036     perl_exception=newSVpv("",0);
12037     reference=SvRV(ST(0));
12038     av=(AV *) reference;
12039     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12040       exception);
12041     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12042     if (image == (Image *) NULL)
12043       {
12044         ThrowPerlException(exception,OptionError,"NoImagesDefined",
12045           PackageName);
12046         goto PerlException;
12047       }
12048     EXTEND(sp,items);
12049     for (i=1; i < items; i++)
12050     {
12051       (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12052         exception);
12053       (void) QueryColorname(image,&target_color,SVGCompliance,message,
12054         exception);
12055       PUSHs(sv_2mortal(newSVpv(message,0)));
12056     }
12057
12058   PerlException:
12059     InheritPerlException(exception,perl_exception);
12060     exception=DestroyExceptionInfo(exception);
12061     SvREFCNT_dec(perl_exception);
12062   }
12063 \f
12064 #
12065 ###############################################################################
12066 #                                                                             #
12067 #                                                                             #
12068 #                                                                             #
12069 #   Q u e r y F o n t                                                         #
12070 #                                                                             #
12071 #                                                                             #
12072 #                                                                             #
12073 ###############################################################################
12074 #
12075 #
12076 void
12077 QueryFont(ref,...)
12078   Image::Magick::Q16HDRI ref=NO_INIT
12079   ALIAS:
12080     queryfont = 1
12081   PPCODE:
12082   {
12083     char
12084       *name,
12085       message[MaxTextExtent];
12086
12087     ExceptionInfo
12088       *exception;
12089
12090     register ssize_t
12091       i;
12092
12093     SV
12094       *perl_exception;
12095
12096     volatile const TypeInfo
12097       *type_info;
12098
12099     PERL_UNUSED_VAR(ref);
12100     PERL_UNUSED_VAR(ix);
12101     exception=AcquireExceptionInfo();
12102     perl_exception=newSVpv("",0);
12103     if (items == 1)
12104       {
12105         const TypeInfo
12106           **typelist;
12107
12108         size_t
12109           types;
12110
12111         typelist=GetTypeInfoList("*",&types,exception);
12112         EXTEND(sp,types);
12113         for (i=0; i < (ssize_t) types; i++)
12114         {
12115           PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12116         }
12117         typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12118           typelist);
12119         goto PerlException;
12120       }
12121     EXTEND(sp,10*items);
12122     for (i=1; i < items; i++)
12123     {
12124       name=(char *) SvPV(ST(i),na);
12125       type_info=GetTypeInfo(name,exception);
12126       if (type_info == (TypeInfo *) NULL)
12127         {
12128           PUSHs(&sv_undef);
12129           continue;
12130         }
12131       if (type_info->name == (char *) NULL)
12132         PUSHs(&sv_undef);
12133       else
12134         PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12135       if (type_info->description == (char *) NULL)
12136         PUSHs(&sv_undef);
12137       else
12138         PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12139       if (type_info->family == (char *) NULL)
12140         PUSHs(&sv_undef);
12141       else
12142         PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12143       if (type_info->style == UndefinedStyle)
12144         PUSHs(&sv_undef);
12145       else
12146         PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12147           type_info->style),0)));
12148       if (type_info->stretch == UndefinedStretch)
12149         PUSHs(&sv_undef);
12150       else
12151         PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12152           type_info->stretch),0)));
12153       (void) FormatLocaleString(message,MaxTextExtent,"%.20g",(double)
12154         type_info->weight);
12155       PUSHs(sv_2mortal(newSVpv(message,0)));
12156       if (type_info->encoding == (char *) NULL)
12157         PUSHs(&sv_undef);
12158       else
12159         PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12160       if (type_info->foundry == (char *) NULL)
12161         PUSHs(&sv_undef);
12162       else
12163         PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12164       if (type_info->format == (char *) NULL)
12165         PUSHs(&sv_undef);
12166       else
12167         PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12168       if (type_info->metrics == (char *) NULL)
12169         PUSHs(&sv_undef);
12170       else
12171         PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12172       if (type_info->glyphs == (char *) NULL)
12173         PUSHs(&sv_undef);
12174       else
12175         PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12176     }
12177
12178   PerlException:
12179     InheritPerlException(exception,perl_exception);
12180     exception=DestroyExceptionInfo(exception);
12181     SvREFCNT_dec(perl_exception);
12182   }
12183 \f
12184 #
12185 ###############################################################################
12186 #                                                                             #
12187 #                                                                             #
12188 #                                                                             #
12189 #   Q u e r y F o n t M e t r i c s                                           #
12190 #                                                                             #
12191 #                                                                             #
12192 #                                                                             #
12193 ###############################################################################
12194 #
12195 #
12196 void
12197 QueryFontMetrics(ref,...)
12198   Image::Magick::Q16HDRI ref=NO_INIT
12199   ALIAS:
12200     queryfontmetrics = 1
12201   PPCODE:
12202   {
12203     AffineMatrix
12204       affine,
12205       current;
12206
12207     AV
12208       *av;
12209
12210     char
12211       *attribute;
12212
12213     double
12214       x,
12215       y;
12216
12217     DrawInfo
12218       *draw_info;
12219
12220     ExceptionInfo
12221       *exception;
12222
12223     GeometryInfo
12224       geometry_info;
12225
12226     Image
12227       *image;
12228
12229     MagickBooleanType
12230       status;
12231
12232     MagickStatusType
12233       flags;
12234
12235     register ssize_t
12236       i;
12237
12238     ssize_t
12239       type;
12240
12241     struct PackageInfo
12242       *info,
12243       *package_info;
12244
12245     SV
12246       *perl_exception,
12247       *reference;  /* reference is the SV* of ref=SvIV(reference) */
12248
12249     TypeMetric
12250       metrics;
12251
12252     PERL_UNUSED_VAR(ref);
12253     PERL_UNUSED_VAR(ix);
12254     exception=AcquireExceptionInfo();
12255     package_info=(struct PackageInfo *) NULL;
12256     perl_exception=newSVpv("",0);
12257     reference=SvRV(ST(0));
12258     av=(AV *) reference;
12259     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12260       exception);
12261     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12262     if (image == (Image *) NULL)
12263       {
12264         ThrowPerlException(exception,OptionError,"NoImagesDefined",
12265           PackageName);
12266         goto PerlException;
12267       }
12268     package_info=ClonePackageInfo(info,exception);
12269     draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12270     CloneString(&draw_info->text,"");
12271     current=draw_info->affine;
12272     GetAffineMatrix(&affine);
12273     x=0.0;
12274     y=0.0;
12275     EXTEND(sp,7*items);
12276     for (i=2; i < items; i+=2)
12277     {
12278       attribute=(char *) SvPV(ST(i-1),na);
12279       switch (*attribute)
12280       {
12281         case 'A':
12282         case 'a':
12283         {
12284           if (LocaleCompare(attribute,"antialias") == 0)
12285             {
12286               type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12287                 SvPV(ST(i),na));
12288               if (type < 0)
12289                 {
12290                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
12291                     SvPV(ST(i),na));
12292                   break;
12293                 }
12294               draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12295               break;
12296             }
12297           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12298             attribute);
12299           break;
12300         }
12301         case 'd':
12302         case 'D':
12303         {
12304           if (LocaleCompare(attribute,"density") == 0)
12305             {
12306               CloneString(&draw_info->density,SvPV(ST(i),na));
12307               break;
12308             }
12309           if (LocaleCompare(attribute,"direction") == 0)
12310             {
12311               draw_info->direction=(DirectionType) ParseCommandOption(
12312                 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12313               break;
12314             }
12315           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12316             attribute);
12317           break;
12318         }
12319         case 'e':
12320         case 'E':
12321         {
12322           if (LocaleCompare(attribute,"encoding") == 0)
12323             {
12324               CloneString(&draw_info->encoding,SvPV(ST(i),na));
12325               break;
12326             }
12327           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12328             attribute);
12329           break;
12330         }
12331         case 'f':
12332         case 'F':
12333         {
12334           if (LocaleCompare(attribute,"family") == 0)
12335             {
12336               CloneString(&draw_info->family,SvPV(ST(i),na));
12337               break;
12338             }
12339           if (LocaleCompare(attribute,"fill") == 0)
12340             {
12341               if (info)
12342                 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12343                   &draw_info->fill,exception);
12344               break;
12345             }
12346           if (LocaleCompare(attribute,"font") == 0)
12347             {
12348               CloneString(&draw_info->font,SvPV(ST(i),na));
12349               break;
12350             }
12351           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12352             attribute);
12353           break;
12354         }
12355         case 'g':
12356         case 'G':
12357         {
12358           if (LocaleCompare(attribute,"geometry") == 0)
12359             {
12360               CloneString(&draw_info->geometry,SvPV(ST(i),na));
12361               break;
12362             }
12363           if (LocaleCompare(attribute,"gravity") == 0)
12364             {
12365               draw_info->gravity=(GravityType) ParseCommandOption(
12366                 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12367               break;
12368             }
12369           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12370             attribute);
12371           break;
12372         }
12373         case 'i':
12374         case 'I':
12375         {
12376           if (LocaleCompare(attribute,"interline-spacing") == 0)
12377             {
12378               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12379               draw_info->interline_spacing=geometry_info.rho;
12380               break;
12381             }
12382           if (LocaleCompare(attribute,"interword-spacing") == 0)
12383             {
12384               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12385               draw_info->interword_spacing=geometry_info.rho;
12386               break;
12387             }
12388           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12389             attribute);
12390           break;
12391         }
12392         case 'k':
12393         case 'K':
12394         {
12395           if (LocaleCompare(attribute,"kerning") == 0)
12396             {
12397               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12398               draw_info->kerning=geometry_info.rho;
12399               break;
12400             }
12401           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12402             attribute);
12403           break;
12404         }
12405         case 'p':
12406         case 'P':
12407         {
12408           if (LocaleCompare(attribute,"pointsize") == 0)
12409             {
12410               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12411               draw_info->pointsize=geometry_info.rho;
12412               break;
12413             }
12414           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12415             attribute);
12416           break;
12417         }
12418         case 'r':
12419         case 'R':
12420         {
12421           if (LocaleCompare(attribute,"rotate") == 0)
12422             {
12423               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12424               affine.rx=geometry_info.rho;
12425               affine.ry=geometry_info.sigma;
12426               if ((flags & SigmaValue) == 0)
12427                 affine.ry=affine.rx;
12428               break;
12429             }
12430           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12431             attribute);
12432           break;
12433         }
12434         case 's':
12435         case 'S':
12436         {
12437           if (LocaleCompare(attribute,"scale") == 0)
12438             {
12439               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12440               affine.sx=geometry_info.rho;
12441               affine.sy=geometry_info.sigma;
12442               if ((flags & SigmaValue) == 0)
12443                 affine.sy=affine.sx;
12444               break;
12445             }
12446           if (LocaleCompare(attribute,"skew") == 0)
12447             {
12448               double
12449                 x_angle,
12450                 y_angle;
12451
12452               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12453               x_angle=geometry_info.rho;
12454               y_angle=geometry_info.sigma;
12455               if ((flags & SigmaValue) == 0)
12456                 y_angle=x_angle;
12457               affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12458               affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12459               break;
12460             }
12461           if (LocaleCompare(attribute,"stroke") == 0)
12462             {
12463               if (info)
12464                 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12465                   &draw_info->stroke,exception);
12466               break;
12467             }
12468           if (LocaleCompare(attribute,"style") == 0)
12469             {
12470               type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12471                 SvPV(ST(i),na));
12472               if (type < 0)
12473                 {
12474                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
12475                     SvPV(ST(i),na));
12476                   break;
12477                 }
12478               draw_info->style=(StyleType) type;
12479               break;
12480             }
12481           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12482             attribute);
12483           break;
12484         }
12485         case 't':
12486         case 'T':
12487         {
12488           if (LocaleCompare(attribute,"text") == 0)
12489             {
12490               CloneString(&draw_info->text,SvPV(ST(i),na));
12491               break;
12492             }
12493           if (LocaleCompare(attribute,"translate") == 0)
12494             {
12495               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12496               affine.tx=geometry_info.rho;
12497               affine.ty=geometry_info.sigma;
12498               if ((flags & SigmaValue) == 0)
12499                 affine.ty=affine.tx;
12500               break;
12501             }
12502           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12503             attribute);
12504           break;
12505         }
12506         case 'w':
12507         case 'W':
12508         {
12509           if (LocaleCompare(attribute,"weight") == 0)
12510             {
12511               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12512               draw_info->weight=(size_t) geometry_info.rho;
12513               break;
12514             }
12515           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12516             attribute);
12517           break;
12518         }
12519         case 'x':
12520         case 'X':
12521         {
12522           if (LocaleCompare(attribute,"x") == 0)
12523             {
12524               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12525               x=geometry_info.rho;
12526               break;
12527             }
12528           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12529             attribute);
12530           break;
12531         }
12532         case 'y':
12533         case 'Y':
12534         {
12535           if (LocaleCompare(attribute,"y") == 0)
12536             {
12537               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12538               y=geometry_info.rho;
12539               break;
12540             }
12541           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12542             attribute);
12543           break;
12544         }
12545         default:
12546         {
12547           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12548             attribute);
12549           break;
12550         }
12551       }
12552     }
12553     draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
12554     draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
12555     draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
12556     draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
12557     draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
12558     draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
12559     if (draw_info->geometry == (char *) NULL)
12560       {
12561         draw_info->geometry=AcquireString((char *) NULL);
12562         (void) FormatLocaleString(draw_info->geometry,MaxTextExtent,
12563           "%.15g,%.15g",x,y);
12564       }
12565     status=GetTypeMetrics(image,draw_info,&metrics,exception);
12566     (void) CatchImageException(image);
12567     if (status == MagickFalse)
12568       PUSHs(&sv_undef);
12569     else
12570       {
12571         PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
12572         PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
12573         PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
12574         PUSHs(sv_2mortal(newSVnv(metrics.descent)));
12575         PUSHs(sv_2mortal(newSVnv(metrics.width)));
12576         PUSHs(sv_2mortal(newSVnv(metrics.height)));
12577         PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
12578         PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
12579         PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
12580         PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
12581         PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
12582         PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
12583         PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
12584       }
12585     draw_info=DestroyDrawInfo(draw_info);
12586
12587   PerlException:
12588     if (package_info != (struct PackageInfo *) NULL)
12589       DestroyPackageInfo(package_info);
12590     InheritPerlException(exception,perl_exception);
12591     exception=DestroyExceptionInfo(exception);
12592     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
12593   }
12594 \f
12595 #
12596 ###############################################################################
12597 #                                                                             #
12598 #                                                                             #
12599 #                                                                             #
12600 #   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                         #
12601 #                                                                             #
12602 #                                                                             #
12603 #                                                                             #
12604 ###############################################################################
12605 #
12606 #
12607 void
12608 QueryMultilineFontMetrics(ref,...)
12609   Image::Magick::Q16HDRI ref=NO_INIT
12610   ALIAS:
12611     querymultilinefontmetrics = 1
12612   PPCODE:
12613   {
12614     AffineMatrix
12615       affine,
12616       current;
12617
12618     AV
12619       *av;
12620
12621     char
12622       *attribute;
12623
12624     double
12625       x,
12626       y;
12627
12628     DrawInfo
12629       *draw_info;
12630
12631     ExceptionInfo
12632       *exception;
12633
12634     GeometryInfo
12635       geometry_info;
12636
12637     Image
12638       *image;
12639
12640     MagickBooleanType
12641       status;
12642
12643     MagickStatusType
12644       flags;
12645
12646     register ssize_t
12647       i;
12648
12649     ssize_t
12650       type;
12651
12652     struct PackageInfo
12653       *info,
12654       *package_info;
12655
12656     SV
12657       *perl_exception,
12658       *reference;  /* reference is the SV* of ref=SvIV(reference) */
12659
12660     TypeMetric
12661       metrics;
12662
12663     PERL_UNUSED_VAR(ref);
12664     PERL_UNUSED_VAR(ix);
12665     exception=AcquireExceptionInfo();
12666     package_info=(struct PackageInfo *) NULL;
12667     perl_exception=newSVpv("",0);
12668     reference=SvRV(ST(0));
12669     av=(AV *) reference;
12670     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12671       exception);
12672     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12673     if (image == (Image *) NULL)
12674       {
12675         ThrowPerlException(exception,OptionError,"NoImagesDefined",
12676           PackageName);
12677         goto PerlException;
12678       }
12679     package_info=ClonePackageInfo(info,exception);
12680     draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12681     CloneString(&draw_info->text,"");
12682     current=draw_info->affine;
12683     GetAffineMatrix(&affine);
12684     x=0.0;
12685     y=0.0;
12686     EXTEND(sp,7*items);
12687     for (i=2; i < items; i+=2)
12688     {
12689       attribute=(char *) SvPV(ST(i-1),na);
12690       switch (*attribute)
12691       {
12692         case 'A':
12693         case 'a':
12694         {
12695           if (LocaleCompare(attribute,"antialias") == 0)
12696             {
12697               type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12698                 SvPV(ST(i),na));
12699               if (type < 0)
12700                 {
12701                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
12702                     SvPV(ST(i),na));
12703                   break;
12704                 }
12705               draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12706               break;
12707             }
12708           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12709             attribute);
12710           break;
12711         }
12712         case 'd':
12713         case 'D':
12714         {
12715           if (LocaleCompare(attribute,"density") == 0)
12716             {
12717               CloneString(&draw_info->density,SvPV(ST(i),na));
12718               break;
12719             }
12720           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12721             attribute);
12722           break;
12723         }
12724         case 'e':
12725         case 'E':
12726         {
12727           if (LocaleCompare(attribute,"encoding") == 0)
12728             {
12729               CloneString(&draw_info->encoding,SvPV(ST(i),na));
12730               break;
12731             }
12732           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12733             attribute);
12734           break;
12735         }
12736         case 'f':
12737         case 'F':
12738         {
12739           if (LocaleCompare(attribute,"family") == 0)
12740             {
12741               CloneString(&draw_info->family,SvPV(ST(i),na));
12742               break;
12743             }
12744           if (LocaleCompare(attribute,"fill") == 0)
12745             {
12746               if (info)
12747                 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12748                   &draw_info->fill,exception);
12749               break;
12750             }
12751           if (LocaleCompare(attribute,"font") == 0)
12752             {
12753               CloneString(&draw_info->font,SvPV(ST(i),na));
12754               break;
12755             }
12756           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12757             attribute);
12758           break;
12759         }
12760         case 'g':
12761         case 'G':
12762         {
12763           if (LocaleCompare(attribute,"geometry") == 0)
12764             {
12765               CloneString(&draw_info->geometry,SvPV(ST(i),na));
12766               break;
12767             }
12768           if (LocaleCompare(attribute,"gravity") == 0)
12769             {
12770               draw_info->gravity=(GravityType) ParseCommandOption(
12771                 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12772               break;
12773             }
12774           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12775             attribute);
12776           break;
12777         }
12778         case 'p':
12779         case 'P':
12780         {
12781           if (LocaleCompare(attribute,"pointsize") == 0)
12782             {
12783               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12784               draw_info->pointsize=geometry_info.rho;
12785               break;
12786             }
12787           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12788             attribute);
12789           break;
12790         }
12791         case 'r':
12792         case 'R':
12793         {
12794           if (LocaleCompare(attribute,"rotate") == 0)
12795             {
12796               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12797               affine.rx=geometry_info.rho;
12798               affine.ry=geometry_info.sigma;
12799               if ((flags & SigmaValue) == 0)
12800                 affine.ry=affine.rx;
12801               break;
12802             }
12803           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12804             attribute);
12805           break;
12806         }
12807         case 's':
12808         case 'S':
12809         {
12810           if (LocaleCompare(attribute,"scale") == 0)
12811             {
12812               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12813               affine.sx=geometry_info.rho;
12814               affine.sy=geometry_info.sigma;
12815               if ((flags & SigmaValue) == 0)
12816                 affine.sy=affine.sx;
12817               break;
12818             }
12819           if (LocaleCompare(attribute,"skew") == 0)
12820             {
12821               double
12822                 x_angle,
12823                 y_angle;
12824
12825               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12826               x_angle=geometry_info.rho;
12827               y_angle=geometry_info.sigma;
12828               if ((flags & SigmaValue) == 0)
12829                 y_angle=x_angle;
12830               affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12831               affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12832               break;
12833             }
12834           if (LocaleCompare(attribute,"stroke") == 0)
12835             {
12836               if (info)
12837                 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12838                   &draw_info->stroke,exception);
12839               break;
12840             }
12841           if (LocaleCompare(attribute,"style") == 0)
12842             {
12843               type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12844                 SvPV(ST(i),na));
12845               if (type < 0)
12846                 {
12847                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
12848                     SvPV(ST(i),na));
12849                   break;
12850                 }
12851               draw_info->style=(StyleType) type;
12852               break;
12853             }
12854           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12855             attribute);
12856           break;
12857         }
12858         case 't':
12859         case 'T':
12860         {
12861           if (LocaleCompare(attribute,"text") == 0)
12862             {
12863               CloneString(&draw_info->text,SvPV(ST(i),na));
12864               break;
12865             }
12866           if (LocaleCompare(attribute,"translate") == 0)
12867             {
12868               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12869               affine.tx=geometry_info.rho;
12870               affine.ty=geometry_info.sigma;
12871               if ((flags & SigmaValue) == 0)
12872                 affine.ty=affine.tx;
12873               break;
12874             }
12875           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12876             attribute);
12877           break;
12878         }
12879         case 'w':
12880         case 'W':
12881         {
12882           if (LocaleCompare(attribute,"weight") == 0)
12883             {
12884               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12885               draw_info->weight=(size_t) geometry_info.rho;
12886               break;
12887             }
12888           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12889             attribute);
12890           break;
12891         }
12892         case 'x':
12893         case 'X':
12894         {
12895           if (LocaleCompare(attribute,"x") == 0)
12896             {
12897               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12898               x=geometry_info.rho;
12899               break;
12900             }
12901           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12902             attribute);
12903           break;
12904         }
12905         case 'y':
12906         case 'Y':
12907         {
12908           if (LocaleCompare(attribute,"y") == 0)
12909             {
12910               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12911               y=geometry_info.rho;
12912               break;
12913             }
12914           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12915             attribute);
12916           break;
12917         }
12918         default:
12919         {
12920           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12921             attribute);
12922           break;
12923         }
12924       }
12925     }
12926     draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
12927     draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
12928     draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
12929     draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
12930     draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
12931     draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
12932     if (draw_info->geometry == (char *) NULL)
12933       {
12934         draw_info->geometry=AcquireString((char *) NULL);
12935         (void) FormatLocaleString(draw_info->geometry,MaxTextExtent,
12936           "%.15g,%.15g",x,y);
12937       }
12938     status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
12939     (void) CatchException(exception);
12940     if (status == MagickFalse)
12941       PUSHs(&sv_undef);
12942     else
12943       {
12944         PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
12945         PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
12946         PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
12947         PUSHs(sv_2mortal(newSVnv(metrics.descent)));
12948         PUSHs(sv_2mortal(newSVnv(metrics.width)));
12949         PUSHs(sv_2mortal(newSVnv(metrics.height)));
12950         PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
12951         PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
12952         PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
12953         PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
12954         PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
12955         PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
12956         PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
12957       }
12958     draw_info=DestroyDrawInfo(draw_info);
12959
12960   PerlException:
12961     if (package_info != (struct PackageInfo *) NULL)
12962       DestroyPackageInfo(package_info);
12963     InheritPerlException(exception,perl_exception);
12964     exception=DestroyExceptionInfo(exception);
12965     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
12966   }
12967 \f
12968 #
12969 ###############################################################################
12970 #                                                                             #
12971 #                                                                             #
12972 #                                                                             #
12973 #   Q u e r y F o r m a t                                                     #
12974 #                                                                             #
12975 #                                                                             #
12976 #                                                                             #
12977 ###############################################################################
12978 #
12979 #
12980 void
12981 QueryFormat(ref,...)
12982   Image::Magick::Q16HDRI ref=NO_INIT
12983   ALIAS:
12984     queryformat = 1
12985   PPCODE:
12986   {
12987     char
12988       *name;
12989
12990     ExceptionInfo
12991       *exception;
12992
12993     register ssize_t
12994       i;
12995
12996     SV
12997       *perl_exception;
12998
12999     volatile const MagickInfo
13000       *magick_info;
13001
13002     PERL_UNUSED_VAR(ref);
13003     PERL_UNUSED_VAR(ix);
13004     exception=AcquireExceptionInfo();
13005     perl_exception=newSVpv("",0);
13006     if (items == 1)
13007       {
13008         char
13009           format[MaxTextExtent];
13010
13011         const MagickInfo
13012           **format_list;
13013
13014         size_t
13015           types;
13016
13017         format_list=GetMagickInfoList("*",&types,exception);
13018         EXTEND(sp,types);
13019         for (i=0; i < (ssize_t) types; i++)
13020         {
13021           (void) CopyMagickString(format,format_list[i]->name,MaxTextExtent);
13022           LocaleLower(format);
13023           PUSHs(sv_2mortal(newSVpv(format,0)));
13024         }
13025         format_list=(const MagickInfo **)
13026           RelinquishMagickMemory((MagickInfo *) format_list);
13027         goto PerlException;
13028       }
13029     EXTEND(sp,8*items);
13030     for (i=1; i < items; i++)
13031     {
13032       name=(char *) SvPV(ST(i),na);
13033       magick_info=GetMagickInfo(name,exception);
13034       if (magick_info == (const MagickInfo *) NULL)
13035         {
13036           PUSHs(&sv_undef);
13037           continue;
13038         }
13039       PUSHs(sv_2mortal(newSViv(magick_info->adjoin)));
13040       PUSHs(sv_2mortal(newSViv(magick_info->blob_support)));
13041       PUSHs(sv_2mortal(newSViv(magick_info->raw)));
13042       PUSHs(sv_2mortal(newSViv((long) magick_info->decoder)));
13043       PUSHs(sv_2mortal(newSViv((long) magick_info->encoder)));
13044       if (magick_info->description == (char *) NULL)
13045         PUSHs(&sv_undef);
13046       else
13047         PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13048       if (magick_info->module == (char *) NULL)
13049         PUSHs(&sv_undef);
13050       else
13051         PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
13052     }
13053
13054   PerlException:
13055     InheritPerlException(exception,perl_exception);
13056     exception=DestroyExceptionInfo(exception);
13057     SvREFCNT_dec(perl_exception);
13058   }
13059 \f
13060 #
13061 ###############################################################################
13062 #                                                                             #
13063 #                                                                             #
13064 #                                                                             #
13065 #   Q u e r y O p t i o n                                                     #
13066 #                                                                             #
13067 #                                                                             #
13068 #                                                                             #
13069 ###############################################################################
13070 #
13071 #
13072 void
13073 QueryOption(ref,...)
13074   Image::Magick::Q16HDRI ref=NO_INIT
13075   ALIAS:
13076     queryoption = 1
13077   PPCODE:
13078   {
13079     char
13080       **options;
13081
13082     ExceptionInfo
13083       *exception;
13084
13085     register ssize_t
13086       i;
13087
13088     ssize_t
13089       j,
13090       option;
13091
13092     SV
13093       *perl_exception;
13094
13095     PERL_UNUSED_VAR(ref);
13096     PERL_UNUSED_VAR(ix);
13097     exception=AcquireExceptionInfo();
13098     perl_exception=newSVpv("",0);
13099     EXTEND(sp,8*items);
13100     for (i=1; i < items; i++)
13101     {
13102       option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13103         SvPV(ST(i),na));
13104       options=GetCommandOptions((CommandOption) option);
13105       if (options == (char **) NULL)
13106         PUSHs(&sv_undef);
13107       else
13108         {
13109           for (j=0; options[j] != (char *) NULL; j++)
13110             PUSHs(sv_2mortal(newSVpv(options[j],0)));
13111           options=DestroyStringList(options);
13112         }
13113     }
13114
13115     InheritPerlException(exception,perl_exception);
13116     exception=DestroyExceptionInfo(exception);
13117     SvREFCNT_dec(perl_exception);
13118   }
13119 \f
13120 #
13121 ###############################################################################
13122 #                                                                             #
13123 #                                                                             #
13124 #                                                                             #
13125 #   R e a d                                                                   #
13126 #                                                                             #
13127 #                                                                             #
13128 #                                                                             #
13129 ###############################################################################
13130 #
13131 #
13132 void
13133 Read(ref,...)
13134   Image::Magick::Q16HDRI ref=NO_INIT
13135   ALIAS:
13136     ReadImage  = 1
13137     read       = 2
13138     readimage  = 3
13139   PPCODE:
13140   {
13141     AV
13142       *av;
13143
13144     char
13145       **keep,
13146       **list;
13147
13148     ExceptionInfo
13149       *exception;
13150
13151     HV
13152       *hv;
13153
13154     Image
13155       *image;
13156
13157     int
13158       n;
13159
13160     MagickBooleanType
13161       status;
13162
13163     register char
13164       **p;
13165
13166     register ssize_t
13167       i;
13168
13169     ssize_t
13170       ac,
13171       number_images;
13172
13173     STRLEN
13174       *length;
13175
13176     struct PackageInfo
13177       *info,
13178       *package_info;
13179
13180     SV
13181       *perl_exception,  /* Perl variable for storing messages */
13182       *reference,
13183       *rv,
13184       *sv;
13185
13186     PERL_UNUSED_VAR(ref);
13187     PERL_UNUSED_VAR(ix);
13188     exception=AcquireExceptionInfo();
13189     perl_exception=newSVpv("",0);
13190     sv=NULL;
13191     package_info=(struct PackageInfo *) NULL;
13192     number_images=0;
13193     ac=(items < 2) ? 1 : items-1;
13194     list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13195     keep=list;
13196     length=(STRLEN *) NULL;
13197     if (list == (char **) NULL)
13198       {
13199         ThrowPerlException(exception,ResourceLimitError,
13200           "MemoryAllocationFailed",PackageName);
13201         goto PerlException;
13202       }
13203     length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13204     if (length == (STRLEN *) NULL)
13205       {
13206         ThrowPerlException(exception,ResourceLimitError,
13207           "MemoryAllocationFailed",PackageName);
13208         goto PerlException;
13209       }
13210     if (sv_isobject(ST(0)) == 0)
13211       {
13212         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13213           PackageName);
13214         goto PerlException;
13215       }
13216     reference=SvRV(ST(0));
13217     hv=SvSTASH(reference);
13218     if (SvTYPE(reference) != SVt_PVAV)
13219       {
13220         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13221           PackageName);
13222         goto PerlException;
13223       }
13224     av=(AV *) reference;
13225     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13226       exception);
13227     package_info=ClonePackageInfo(info,exception);
13228     n=1;
13229     if (items <= 1)
13230       *list=(char *) (*package_info->image_info->filename ?
13231         package_info->image_info->filename : "XC:black");
13232     else
13233       for (n=0, i=0; i < ac; i++)
13234       {
13235         list[n]=(char *) SvPV(ST(i+1),length[n]);
13236         if ((items >= 3) && strEQcase(list[n],"blob"))
13237           {
13238             void
13239               *blob;
13240
13241             i++;
13242             blob=(void *) (SvPV(ST(i+1),length[n]));
13243             SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13244           }
13245         if ((items >= 3) && strEQcase(list[n],"filename"))
13246           continue;
13247         if ((items >= 3) && strEQcase(list[n],"file"))
13248           {
13249             FILE
13250               *file;
13251
13252             PerlIO
13253               *io_info;
13254
13255             i++;
13256             io_info=IoIFP(sv_2io(ST(i+1)));
13257             if (io_info == (PerlIO *) NULL)
13258               {
13259                 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13260                   PackageName);
13261                 continue;
13262               }
13263             file=PerlIO_findFILE(io_info);
13264             if (file == (FILE *) NULL)
13265               {
13266                 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13267                   PackageName);
13268                 continue;
13269               }
13270             SetImageInfoFile(package_info->image_info,file);
13271           }
13272         if ((items >= 3) && strEQcase(list[n],"magick"))
13273           continue;
13274         n++;
13275       }
13276     list[n]=(char *) NULL;
13277     keep=list;
13278     status=ExpandFilenames(&n,&list);
13279     if (status == MagickFalse)
13280       {
13281         ThrowPerlException(exception,ResourceLimitError,
13282           "MemoryAllocationFailed",PackageName);
13283         goto PerlException;
13284       }
13285     number_images=0;
13286     for (i=0; i < n; i++)
13287     {
13288       if ((package_info->image_info->file == (FILE *) NULL) &&
13289           (package_info->image_info->blob == (void *) NULL))
13290         image=ReadImages(package_info->image_info,list[i],exception);
13291       else
13292         {
13293           image=ReadImages(package_info->image_info,
13294             package_info->image_info->filename,exception);
13295           if (image != (Image *) NULL)
13296             DisassociateImageStream(image);
13297         }
13298       if (image == (Image *) NULL)
13299         break;
13300       for ( ; image; image=image->next)
13301       {
13302         AddImageToRegistry(sv,image);
13303         rv=newRV(sv);
13304         av_push(av,sv_bless(rv,hv));
13305         SvREFCNT_dec(sv);
13306         number_images++;
13307       }
13308     }
13309     /*
13310       Free resources.
13311     */
13312     for (i=0; i < n; i++)
13313       if (list[i] != (char *) NULL)
13314         for (p=keep; list[i] != *p++; )
13315           if (*p == (char *) NULL)
13316             {
13317               list[i]=(char *) RelinquishMagickMemory(list[i]);
13318               break;
13319             }
13320
13321   PerlException:
13322     if (package_info != (struct PackageInfo *) NULL)
13323       DestroyPackageInfo(package_info);
13324     if (list && (list != keep))
13325       list=(char **) RelinquishMagickMemory(list);
13326     if (keep)
13327       keep=(char **) RelinquishMagickMemory(keep);
13328     if (length)
13329       length=(STRLEN *) RelinquishMagickMemory(length);
13330     InheritPerlException(exception,perl_exception);
13331     exception=DestroyExceptionInfo(exception);
13332     sv_setiv(perl_exception,(IV) number_images);
13333     SvPOK_on(perl_exception);
13334     ST(0)=sv_2mortal(perl_exception);
13335     XSRETURN(1);
13336   }
13337 \f
13338 #
13339 ###############################################################################
13340 #                                                                             #
13341 #                                                                             #
13342 #                                                                             #
13343 #   R e m o t e                                                               #
13344 #                                                                             #
13345 #                                                                             #
13346 #                                                                             #
13347 ###############################################################################
13348 #
13349 #
13350 void
13351 Remote(ref,...)
13352   Image::Magick::Q16HDRI ref=NO_INIT
13353   ALIAS:
13354     RemoteCommand  = 1
13355     remote         = 2
13356     remoteCommand  = 3
13357   PPCODE:
13358   {
13359     AV
13360       *av;
13361
13362     ExceptionInfo
13363       *exception;
13364
13365     register ssize_t
13366       i;
13367
13368     SV
13369       *perl_exception,
13370       *reference;
13371
13372     struct PackageInfo
13373       *info;
13374
13375     PERL_UNUSED_VAR(ref);
13376     PERL_UNUSED_VAR(ix);
13377     exception=AcquireExceptionInfo();
13378     perl_exception=newSVpv("",0);
13379     reference=SvRV(ST(0));
13380     av=(AV *) reference;
13381     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13382       exception);
13383     for (i=1; i < items; i++)
13384       (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13385         SvPV(ST(i),na),exception);
13386     InheritPerlException(exception,perl_exception);
13387     exception=DestroyExceptionInfo(exception);
13388     SvREFCNT_dec(perl_exception);    /* throw away all errors */
13389   }
13390 \f
13391 #
13392 ###############################################################################
13393 #                                                                             #
13394 #                                                                             #
13395 #                                                                             #
13396 #   S e t                                                                     #
13397 #                                                                             #
13398 #                                                                             #
13399 #                                                                             #
13400 ###############################################################################
13401 #
13402 #
13403 void
13404 Set(ref,...)
13405   Image::Magick::Q16HDRI ref=NO_INIT
13406   ALIAS:
13407     SetAttributes  = 1
13408     SetAttribute   = 2
13409     set            = 3
13410     setattributes  = 4
13411     setattribute   = 5
13412   PPCODE:
13413   {
13414     ExceptionInfo
13415       *exception;
13416
13417     Image
13418       *image;
13419
13420     register ssize_t
13421       i;
13422
13423     struct PackageInfo
13424       *info;
13425
13426     SV
13427       *perl_exception,
13428       *reference;  /* reference is the SV* of ref=SvIV(reference) */
13429
13430     PERL_UNUSED_VAR(ref);
13431     PERL_UNUSED_VAR(ix);
13432     exception=AcquireExceptionInfo();
13433     perl_exception=newSVpv("",0);
13434     if (sv_isobject(ST(0)) == 0)
13435       {
13436         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13437           PackageName);
13438         goto PerlException;
13439       }
13440     reference=SvRV(ST(0));
13441     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13442     if (items == 2)
13443       SetAttribute(aTHX_ info,image,"size",ST(1),exception);
13444     else
13445       for (i=2; i < items; i+=2)
13446         SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
13447
13448   PerlException:
13449     InheritPerlException(exception,perl_exception);
13450     exception=DestroyExceptionInfo(exception);
13451     sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
13452     SvPOK_on(perl_exception);
13453     ST(0)=sv_2mortal(perl_exception);
13454     XSRETURN(1);
13455   }
13456 \f
13457 #
13458 ###############################################################################
13459 #                                                                             #
13460 #                                                                             #
13461 #                                                                             #
13462 #   S e t P i x e l                                                           #
13463 #                                                                             #
13464 #                                                                             #
13465 #                                                                             #
13466 ###############################################################################
13467 #
13468 #
13469 void
13470 SetPixel(ref,...)
13471   Image::Magick::Q16HDRI ref=NO_INIT
13472   ALIAS:
13473     setpixel = 1
13474     setPixel = 2
13475   PPCODE:
13476   {
13477     AV
13478       *av;
13479
13480     char
13481       *attribute;
13482
13483     ChannelType
13484       channel,
13485       channel_mask;
13486
13487     ExceptionInfo
13488       *exception;
13489
13490     Image
13491       *image;
13492
13493     MagickBooleanType
13494       normalize;
13495
13496     RectangleInfo
13497       region;
13498
13499     register ssize_t
13500       i;
13501
13502     register Quantum
13503       *q;
13504
13505     ssize_t
13506       option;
13507
13508     struct PackageInfo
13509       *info;
13510
13511     SV
13512       *perl_exception,
13513       *reference;  /* reference is the SV* of ref=SvIV(reference) */
13514
13515     PERL_UNUSED_VAR(ref);
13516     PERL_UNUSED_VAR(ix);
13517     exception=AcquireExceptionInfo();
13518     perl_exception=newSVpv("",0);
13519     reference=SvRV(ST(0));
13520     av=(AV *) reference;
13521     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13522       exception);
13523     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13524     if (image == (Image *) NULL)
13525       {
13526         ThrowPerlException(exception,OptionError,"NoImagesDefined",
13527           PackageName);
13528         goto PerlException;
13529       }
13530     av=(AV *) NULL;
13531     normalize=MagickTrue;
13532     region.x=0;
13533     region.y=0;
13534     region.width=image->columns;
13535     region.height=1;
13536     if (items == 1)
13537       (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
13538     channel=DefaultChannels;
13539     for (i=2; i < items; i+=2)
13540     {
13541       attribute=(char *) SvPV(ST(i-1),na);
13542       switch (*attribute)
13543       {
13544         case 'C':
13545         case 'c':
13546         {
13547           if (LocaleCompare(attribute,"channel") == 0)
13548             {
13549               ssize_t
13550                 option;
13551
13552               option=ParseChannelOption(SvPV(ST(i),na));
13553               if (option < 0)
13554                 {
13555                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
13556                     SvPV(ST(i),na));
13557                   return;
13558                 }
13559               channel=(ChannelType) option;
13560               break;
13561             }
13562           if (LocaleCompare(attribute,"color") == 0)
13563             {
13564               if (SvTYPE(ST(i)) != SVt_RV)
13565                 {
13566                   char
13567                     message[MaxTextExtent];
13568
13569                   (void) FormatLocaleString(message,MaxTextExtent,
13570                     "invalid %.60s value",attribute);
13571                   ThrowPerlException(exception,OptionError,message,
13572                     SvPV(ST(i),na));
13573                 }
13574               av=(AV *) SvRV(ST(i));
13575               break;
13576             }
13577           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13578             attribute);
13579           break;
13580         }
13581         case 'g':
13582         case 'G':
13583         {
13584           if (LocaleCompare(attribute,"geometry") == 0)
13585             {
13586               (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
13587               break;
13588             }
13589           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13590             attribute);
13591           break;
13592         }
13593         case 'N':
13594         case 'n':
13595         {
13596           if (LocaleCompare(attribute,"normalize") == 0)
13597             {
13598               option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13599                 SvPV(ST(i),na));
13600               if (option < 0)
13601                 {
13602                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
13603                     SvPV(ST(i),na));
13604                   break;
13605                 }
13606              normalize=option != 0 ? MagickTrue : MagickFalse;
13607              break;
13608             }
13609           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13610             attribute);
13611           break;
13612         }
13613         case 'x':
13614         case 'X':
13615         {
13616           if (LocaleCompare(attribute,"x") == 0)
13617             {
13618               region.x=SvIV(ST(i));
13619               break;
13620             }
13621           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13622             attribute);
13623           break;
13624         }
13625         case 'y':
13626         case 'Y':
13627         {
13628           if (LocaleCompare(attribute,"y") == 0)
13629             {
13630               region.y=SvIV(ST(i));
13631               break;
13632             }
13633           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13634             attribute);
13635           break;
13636         }
13637         default:
13638         {
13639           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13640             attribute);
13641           break;
13642         }
13643       }
13644     }
13645     (void) SetImageStorageClass(image,DirectClass,exception);
13646     channel_mask=SetImageChannelMask(image,channel);
13647     q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
13648     if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
13649         (SvTYPE(av) != SVt_PVAV))
13650       PUSHs(&sv_undef);
13651     else
13652       {
13653         double
13654           scale;
13655
13656         register ssize_t
13657           i;
13658
13659         i=0;
13660         scale=1.0;
13661         if (normalize != MagickFalse)
13662           scale=QuantumRange;
13663         if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
13664             (i <= av_len(av)))
13665           {
13666             SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
13667               av_fetch(av,i,0)))),q);
13668             i++;
13669           }
13670         if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
13671             (i <= av_len(av)))
13672           {
13673             SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
13674               av_fetch(av,i,0)))),q);
13675             i++;
13676           }
13677         if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
13678             (i <= av_len(av)))
13679           {
13680             SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
13681               av_fetch(av,i,0)))),q);
13682             i++;
13683           }
13684         if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
13685             (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
13686           {
13687             SetPixelBlack(image,ClampToQuantum(scale*
13688               SvNV(*(av_fetch(av,i,0)))),q);
13689             i++;
13690           }
13691         if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
13692             (i <= av_len(av)))
13693           {
13694             SetPixelAlpha(image,ClampToQuantum(scale*
13695               SvNV(*(av_fetch(av,i,0)))),q);
13696             i++;
13697           }
13698         (void) SyncAuthenticPixels(image,exception);
13699       }
13700     (void) SetImageChannelMask(image,channel_mask);
13701
13702   PerlException:
13703     InheritPerlException(exception,perl_exception);
13704     exception=DestroyExceptionInfo(exception);
13705     SvREFCNT_dec(perl_exception);
13706   }
13707 \f
13708 #
13709 ###############################################################################
13710 #                                                                             #
13711 #                                                                             #
13712 #                                                                             #
13713 #   S m u s h                                                                 #
13714 #                                                                             #
13715 #                                                                             #
13716 #                                                                             #
13717 ###############################################################################
13718 #
13719 #
13720 void
13721 Smush(ref,...)
13722   Image::Magick::Q16HDRI ref=NO_INIT
13723   ALIAS:
13724     SmushImage  = 1
13725     smush       = 2
13726     smushimage  = 3
13727   PPCODE:
13728   {
13729     AV
13730       *av;
13731
13732     char
13733       *attribute;
13734
13735     ExceptionInfo
13736       *exception;
13737
13738     HV
13739       *hv;
13740
13741     Image
13742       *image;
13743
13744     register ssize_t
13745       i;
13746
13747     ssize_t
13748       offset,
13749       stack;
13750
13751     struct PackageInfo
13752       *info;
13753
13754     SV
13755       *av_reference,
13756       *perl_exception,
13757       *reference,
13758       *rv,
13759       *sv;
13760
13761     PERL_UNUSED_VAR(ref);
13762     PERL_UNUSED_VAR(ix);
13763     exception=AcquireExceptionInfo();
13764     perl_exception=newSVpv("",0);
13765     sv=NULL;
13766     attribute=NULL;
13767     av=NULL;
13768     if (sv_isobject(ST(0)) == 0)
13769       {
13770         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13771           PackageName);
13772         goto PerlException;
13773       }
13774     reference=SvRV(ST(0));
13775     hv=SvSTASH(reference);
13776     av=newAV();
13777     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
13778     SvREFCNT_dec(av);
13779     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13780     if (image == (Image *) NULL)
13781       {
13782         ThrowPerlException(exception,OptionError,"NoImagesDefined",
13783           PackageName);
13784         goto PerlException;
13785       }
13786     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
13787     /*
13788       Get options.
13789     */
13790     offset=0;
13791     stack=MagickTrue;
13792     for (i=2; i < items; i+=2)
13793     {
13794       attribute=(char *) SvPV(ST(i-1),na);
13795       switch (*attribute)
13796       {
13797         case 'O':
13798         case 'o':
13799         {
13800           if (LocaleCompare(attribute,"offset") == 0)
13801             {
13802               offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
13803               break;
13804             }
13805           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13806             attribute);
13807           break;
13808         }
13809         case 'S':
13810         case 's':
13811         {
13812           if (LocaleCompare(attribute,"stack") == 0)
13813             {
13814               stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13815                 SvPV(ST(i),na));
13816               if (stack < 0)
13817                 {
13818                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
13819                     SvPV(ST(i),na));
13820                   return;
13821                 }
13822               break;
13823             }
13824           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13825             attribute);
13826           break;
13827         }
13828         default:
13829         {
13830           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13831             attribute);
13832           break;
13833         }
13834       }
13835     }
13836     image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
13837       exception);
13838     if (image == (Image *) NULL)
13839       goto PerlException;
13840     for ( ; image; image=image->next)
13841     {
13842       AddImageToRegistry(sv,image);
13843       rv=newRV(sv);
13844       av_push(av,sv_bless(rv,hv));
13845       SvREFCNT_dec(sv);
13846     }
13847     exception=DestroyExceptionInfo(exception);
13848     ST(0)=av_reference;
13849     SvREFCNT_dec(perl_exception);
13850     XSRETURN(1);
13851
13852   PerlException:
13853     InheritPerlException(exception,perl_exception);
13854     exception=DestroyExceptionInfo(exception);
13855     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
13856     SvPOK_on(perl_exception);
13857     ST(0)=sv_2mortal(perl_exception);
13858     XSRETURN(1);
13859   }
13860 \f
13861 #
13862 ###############################################################################
13863 #                                                                             #
13864 #                                                                             #
13865 #                                                                             #
13866 #   S t a t i s t i c s                                                       #
13867 #                                                                             #
13868 #                                                                             #
13869 #                                                                             #
13870 ###############################################################################
13871 #
13872 #
13873 void
13874 Statistics(ref,...)
13875   Image::Magick::Q16HDRI ref=NO_INIT
13876   ALIAS:
13877     StatisticsImage = 1
13878     statistics      = 2
13879     statisticsimage = 3
13880   PPCODE:
13881   {
13882 #define ChannelStatistics(channel) \
13883 { \
13884   (void) FormatLocaleString(message,MaxTextExtent,"%.20g", \
13885     (double) channel_statistics[channel].depth); \
13886   PUSHs(sv_2mortal(newSVpv(message,0))); \
13887   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
13888     channel_statistics[channel].minima/scale); \
13889   PUSHs(sv_2mortal(newSVpv(message,0))); \
13890   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
13891     channel_statistics[channel].maxima/scale); \
13892   PUSHs(sv_2mortal(newSVpv(message,0))); \
13893   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
13894     channel_statistics[channel].mean/scale); \
13895   PUSHs(sv_2mortal(newSVpv(message,0))); \
13896   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
13897     channel_statistics[channel].standard_deviation/scale); \
13898   PUSHs(sv_2mortal(newSVpv(message,0))); \
13899   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
13900     channel_statistics[channel].kurtosis); \
13901   PUSHs(sv_2mortal(newSVpv(message,0))); \
13902   (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
13903     channel_statistics[channel].skewness); \
13904   PUSHs(sv_2mortal(newSVpv(message,0))); \
13905 }
13906
13907     AV
13908       *av;
13909
13910     char
13911       message[MaxTextExtent];
13912
13913     ChannelStatistics
13914       *channel_statistics;
13915
13916     double
13917       scale;
13918
13919     ExceptionInfo
13920       *exception;
13921
13922     Image
13923       *image;
13924
13925     ssize_t
13926       count;
13927
13928     struct PackageInfo
13929       *info;
13930
13931     SV
13932       *perl_exception,
13933       *reference;
13934
13935     PERL_UNUSED_VAR(ref);
13936     PERL_UNUSED_VAR(ix);
13937     exception=AcquireExceptionInfo();
13938     perl_exception=newSVpv("",0);
13939     av=NULL;
13940     if (sv_isobject(ST(0)) == 0)
13941       {
13942         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13943           PackageName);
13944         goto PerlException;
13945       }
13946     reference=SvRV(ST(0));
13947     av=newAV();
13948     SvREFCNT_dec(av);
13949     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13950     if (image == (Image *) NULL)
13951       {
13952         ThrowPerlException(exception,OptionError,"NoImagesDefined",
13953           PackageName);
13954         goto PerlException;
13955       }
13956     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
13957     count=0;
13958     for ( ; image; image=image->next)
13959     {
13960       channel_statistics=GetImageStatistics(image,exception);
13961       if (channel_statistics == (ChannelStatistics *) NULL)
13962         continue;
13963       count++;
13964       EXTEND(sp,35*count);
13965       scale=(double) QuantumRange;
13966       ChannelStatistics(RedChannel);
13967       ChannelStatistics(GreenChannel);
13968       ChannelStatistics(BlueChannel);
13969       if (image->colorspace == CMYKColorspace)
13970         ChannelStatistics(BlackChannel);
13971       if (image->alpha_trait == BlendPixelTrait)
13972         ChannelStatistics(AlphaChannel);
13973       channel_statistics=(ChannelStatistics *)
13974         RelinquishMagickMemory(channel_statistics);
13975     }
13976
13977   PerlException:
13978     InheritPerlException(exception,perl_exception);
13979     exception=DestroyExceptionInfo(exception);
13980     SvREFCNT_dec(perl_exception);
13981   }
13982 \f
13983 #
13984 ###############################################################################
13985 #                                                                             #
13986 #                                                                             #
13987 #                                                                             #
13988 #   S y n c A u t h e n t i c P i x e l s                                     #
13989 #                                                                             #
13990 #                                                                             #
13991 #                                                                             #
13992 ###############################################################################
13993 #
13994 #
13995 void
13996 SyncAuthenticPixels(ref,...)
13997   Image::Magick::Q16HDRI ref = NO_INIT
13998   ALIAS:
13999     Syncauthenticpixels = 1
14000     SyncImagePixels = 2
14001     syncimagepixels = 3
14002   CODE:
14003   {
14004     ExceptionInfo
14005       *exception;
14006
14007     Image
14008       *image;
14009
14010     MagickBooleanType
14011       status;
14012
14013     struct PackageInfo
14014       *info;
14015
14016     SV
14017       *perl_exception,
14018       *reference;
14019
14020     PERL_UNUSED_VAR(ref);
14021     PERL_UNUSED_VAR(ix);
14022     exception=AcquireExceptionInfo();
14023     perl_exception=newSVpv("",0);
14024     if (sv_isobject(ST(0)) == 0)
14025       {
14026         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14027           PackageName);
14028         goto PerlException;
14029       }
14030
14031     reference=SvRV(ST(0));
14032     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14033     if (image == (Image *) NULL)
14034       {
14035         ThrowPerlException(exception,OptionError,"NoImagesDefined",
14036           PackageName);
14037         goto PerlException;
14038       }
14039
14040     status=SyncAuthenticPixels(image,exception);
14041     if (status != MagickFalse)
14042       return;
14043
14044   PerlException:
14045     InheritPerlException(exception,perl_exception);
14046     exception=DestroyExceptionInfo(exception);
14047     SvREFCNT_dec(perl_exception);  /* throw away all errors */
14048   }
14049 \f
14050 #
14051 ###############################################################################
14052 #                                                                             #
14053 #                                                                             #
14054 #                                                                             #
14055 #   T r a n s f o r m                                                         #
14056 #                                                                             #
14057 #                                                                             #
14058 #                                                                             #
14059 ###############################################################################
14060 #
14061 #
14062 void
14063 Transform(ref,...)
14064   Image::Magick::Q16HDRI ref=NO_INIT
14065   ALIAS:
14066     TransformImage = 1
14067     transform      = 2
14068     transformimage = 3
14069   PPCODE:
14070   {
14071     AV
14072       *av;
14073
14074     char
14075       *attribute,
14076       *crop_geometry,
14077       *geometry;
14078
14079     ExceptionInfo
14080       *exception;
14081
14082     HV
14083       *hv;
14084
14085     Image
14086       *clone,
14087       *image;
14088
14089     register ssize_t
14090       i;
14091
14092     struct PackageInfo
14093       *info;
14094
14095     SV
14096       *av_reference,
14097       *perl_exception,
14098       *reference,
14099       *rv,
14100       *sv;
14101
14102     PERL_UNUSED_VAR(ref);
14103     PERL_UNUSED_VAR(ix);
14104     exception=AcquireExceptionInfo();
14105     perl_exception=newSVpv("",0);
14106     sv=NULL;
14107     av=NULL;
14108     attribute=NULL;
14109     if (sv_isobject(ST(0)) == 0)
14110       {
14111         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14112           PackageName);
14113         goto PerlException;
14114       }
14115     reference=SvRV(ST(0));
14116     hv=SvSTASH(reference);
14117     av=newAV();
14118     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14119     SvREFCNT_dec(av);
14120     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14121     if (image == (Image *) NULL)
14122       {
14123         ThrowPerlException(exception,OptionError,"NoImagesDefined",
14124           PackageName);
14125         goto PerlException;
14126       }
14127     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14128     /*
14129       Get attribute.
14130     */
14131     crop_geometry=(char *) NULL;
14132     geometry=(char *) NULL;
14133     for (i=2; i < items; i+=2)
14134     {
14135       attribute=(char *) SvPV(ST(i-1),na);
14136       switch (*attribute)
14137       {
14138         case 'c':
14139         case 'C':
14140         {
14141           if (LocaleCompare(attribute,"crop") == 0)
14142             {
14143               crop_geometry=SvPV(ST(i),na);
14144               break;
14145             }
14146           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14147             attribute);
14148           break;
14149         }
14150         case 'g':
14151         case 'G':
14152         {
14153           if (LocaleCompare(attribute,"geometry") == 0)
14154             {
14155               geometry=SvPV(ST(i),na);
14156               break;
14157             }
14158           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14159             attribute);
14160           break;
14161         }
14162         default:
14163         {
14164           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14165             attribute);
14166           break;
14167         }
14168       }
14169     }
14170     for ( ; image; image=image->next)
14171     {
14172       clone=CloneImage(image,0,0,MagickTrue,exception);
14173       if (clone == (Image *) NULL)
14174         goto PerlException;
14175       TransformImage(&clone,crop_geometry,geometry,exception);
14176       for ( ; clone; clone=clone->next)
14177       {
14178         AddImageToRegistry(sv,clone);
14179         rv=newRV(sv);
14180         av_push(av,sv_bless(rv,hv));
14181         SvREFCNT_dec(sv);
14182       }
14183     }
14184     exception=DestroyExceptionInfo(exception);
14185     ST(0)=av_reference;
14186     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
14187     XSRETURN(1);
14188
14189   PerlException:
14190     InheritPerlException(exception,perl_exception);
14191     exception=DestroyExceptionInfo(exception);
14192     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14193     SvPOK_on(perl_exception);
14194     ST(0)=sv_2mortal(perl_exception);
14195     XSRETURN(1);
14196   }
14197 \f
14198 #
14199 ###############################################################################
14200 #                                                                             #
14201 #                                                                             #
14202 #                                                                             #
14203 #   W r i t e                                                                 #
14204 #                                                                             #
14205 #                                                                             #
14206 #                                                                             #
14207 ###############################################################################
14208 #
14209 #
14210 void
14211 Write(ref,...)
14212   Image::Magick::Q16HDRI ref=NO_INIT
14213   ALIAS:
14214     WriteImage    = 1
14215     write         = 2
14216     writeimage    = 3
14217   PPCODE:
14218   {
14219     char
14220       filename[MaxTextExtent];
14221
14222     ExceptionInfo
14223       *exception;
14224
14225     Image
14226       *image,
14227       *next;
14228
14229     register ssize_t
14230       i;
14231
14232     ssize_t
14233       number_images,
14234       scene;
14235
14236     struct PackageInfo
14237       *info,
14238       *package_info;
14239
14240     SV
14241       *perl_exception,
14242       *reference;
14243
14244     PERL_UNUSED_VAR(ref);
14245     PERL_UNUSED_VAR(ix);
14246     exception=AcquireExceptionInfo();
14247     perl_exception=newSVpv("",0);
14248     number_images=0;
14249     package_info=(struct PackageInfo *) NULL;
14250     if (sv_isobject(ST(0)) == 0)
14251       {
14252         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14253           PackageName);
14254         goto PerlException;
14255       }
14256     reference=SvRV(ST(0));
14257     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14258     if (image == (Image *) NULL)
14259       {
14260         ThrowPerlException(exception,OptionError,"NoImagesDefined",
14261           PackageName);
14262         goto PerlException;
14263       }
14264     package_info=ClonePackageInfo(info,exception);
14265     if (items == 2)
14266       SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14267     else
14268       if (items > 2)
14269         for (i=2; i < items; i+=2)
14270           SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14271             exception);
14272     (void) CopyMagickString(filename,package_info->image_info->filename,
14273       MaxTextExtent);
14274     scene=0;
14275     for (next=image; next; next=next->next)
14276     {
14277       (void) CopyMagickString(next->filename,filename,MaxTextExtent);
14278       next->scene=scene++;
14279     }
14280     SetImageInfo(package_info->image_info,(unsigned int)
14281       GetImageListLength(image),exception);
14282     for (next=image; next; next=next->next)
14283     {
14284       (void) WriteImage(package_info->image_info,next,exception);
14285       number_images++;
14286       if (package_info->image_info->adjoin)
14287         break;
14288     }
14289
14290   PerlException:
14291     if (package_info != (struct PackageInfo *) NULL)
14292       DestroyPackageInfo(package_info);
14293     InheritPerlException(exception,perl_exception);
14294     exception=DestroyExceptionInfo(exception);
14295     sv_setiv(perl_exception,(IV) number_images);
14296     SvPOK_on(perl_exception);
14297     ST(0)=sv_2mortal(perl_exception);
14298     XSRETURN(1);
14299   }