• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                         PPPP   EEEEE  RRRR   L                              %
6 %                         P   P  E      R   R  L                              %
7 %                         PPPP   EEE    RRRR   L                              %
8 %                         P      E      R  R   L                              %
9 %                         P      EEEEE  R   R  LLLLL                          %
10 %                                                                             %
11 %                  M   M   AAA    GGGG  IIIII   CCCC  K   K                   %
12 %                  MM MM  A   A  G        I    C      K  K                    %
13 %                  M M M  AAAAA  G GGG    I    C      KKK                     %
14 %                  M   M  A   A  G   G    I    C      K  K                    %
15 %                  M   M  A   A   GGGG  IIIII   CCCC  K   K                   %
16 %                                                                             %
17 %                                                                             %
18 %                Object-oriented Perl interface to ImageMagick                %
19 %                                                                             %
20 %                            Software Design                                  %
21 %                              Kyle Shorter                                   %
22 %                                 Cristy                                      %
23 %                             February 1997                                   %
24 %                                                                             %
25 %                                                                             %
26 %  Copyright 1999-2016 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 
48 /*
49   Include declarations.
50 */
51 #if defined(__cplusplus) || defined(c_plusplus)
52 extern "C" {
53 #endif
54 
55 #define PERL_NO_GET_CONTEXT
56 #include <MagickCore/MagickCore.h>
57 #include "EXTERN.h"
58 #include "perl.h"
59 #include "XSUB.h"
60 #include <math.h>
61 #undef tainted
62 
63 #if defined(__cplusplus) || defined(c_plusplus)
64 }
65 #endif
66 
67 /*
68   Define declarations.
69 */
70 #ifndef aTHX_
71 #define aTHX_
72 #define pTHX_
73 #define dTHX
74 #endif
75 #define DegreesToRadians(x)  (MagickPI*(x)/180.0)
76 #define EndOf(array)  (&array[NumberOf(array)])
77 #define MagickPI  3.14159265358979323846264338327950288419716939937510
78 #define MaxArguments  33
79 #ifndef na
80 #define na  PL_na
81 #endif
82 #define NumberOf(array)  (sizeof(array)/sizeof(*array))
83 #define PackageName   "Image::Magick"
84 #if PERL_VERSION <= 6
85 #define PerlIO  FILE
86 #define PerlIO_importFILE(f, fl)  (f)
87 #define PerlIO_findFILE(f)  NULL
88 #endif
89 #ifndef sv_undef
90 #define sv_undef  PL_sv_undef
91 #endif
92 
93 #define AddImageToRegistry(sv,image) \
94 { \
95   if (magick_registry != (SplayTreeInfo *) NULL) \
96     { \
97       (void) AddValueToSplayTree(magick_registry,image,image); \
98       (sv)=newSViv(PTR2IV(image)); \
99     } \
100 }
101 
102 #define DeleteImageFromRegistry(reference,image) \
103 { \
104   if (magick_registry != (SplayTreeInfo *) NULL) \
105     { \
106       if (GetImageReferenceCount(image) == 1) \
107        (void) DeleteNodeByValueFromSplayTree(magick_registry,image); \
108       image=DestroyImage(image); \
109       sv_setiv(reference,0); \
110     } \
111 }
112 
113 #define InheritPerlException(exception,perl_exception) \
114 { \
115   char \
116     message[MagickPathExtent]; \
117  \
118   if ((exception)->severity != UndefinedException) \
119     { \
120       (void) FormatLocaleString(message,MagickPathExtent,"Exception %d: %s%s%s%s",\
121         (exception)->severity, (exception)->reason ? \
122         GetLocaleExceptionMessage((exception)->severity,(exception)->reason) : \
123         "Unknown", (exception)->description ? " (" : "", \
124         (exception)->description ? GetLocaleExceptionMessage( \
125         (exception)->severity,(exception)->description) : "", \
126         (exception)->description ? ")" : ""); \
127       if ((perl_exception) != (SV *) NULL) \
128         { \
129           if (SvCUR(perl_exception)) \
130             sv_catpv(perl_exception,"\n"); \
131           sv_catpv(perl_exception,message); \
132         } \
133     } \
134 }
135 
136 #define ThrowPerlException(exception,severity,tag,reason) \
137   (void) ThrowMagickException(exception,GetMagickModule(),severity, \
138     tag,"`%s'",reason); \
139 
140 /*
141   Typedef and structure declarations.
142 */
143 typedef enum
144 {
145   ArrayReference = (~0),
146   RealReference = (~0)-1,
147   FileReference = (~0)-2,
148   ImageReference = (~0)-3,
149   IntegerReference = (~0)-4,
150   StringReference = (~0)-5
151 } MagickReference;
152 
153 typedef struct _Arguments
154 {
155   const char
156     *method;
157 
158   ssize_t
159     type;
160 } Arguments;
161 
162 struct ArgumentList
163 {
164   ssize_t
165     integer_reference;
166 
167   double
168     real_reference;
169 
170   const char
171     *string_reference;
172 
173   Image
174     *image_reference;
175 
176   SV
177     *array_reference;
178 
179   FILE
180     *file_reference;
181 
182   size_t
183     length;
184 };
185 
186 struct PackageInfo
187 {
188   ImageInfo
189     *image_info;
190 };
191 
192 typedef void
193   *Image__Magick;  /* data type for the Image::Magick package */
194 
195 /*
196   Static declarations.
197 */
198 static struct
199   Methods
200   {
201     const char
202       *name;
203 
204     Arguments
205       arguments[MaxArguments];
206   } Methods[] =
207   {
208     { "Comment", { {"comment", StringReference} } },
209     { "Label", { {"label", StringReference} } },
210     { "AddNoise", { {"noise", MagickNoiseOptions}, {"attenuate", RealReference},
211       {"channel", MagickChannelOptions} } },
212     { "Colorize", { {"fill", StringReference}, {"blend", StringReference} } },
213     { "Border", { {"geometry", StringReference}, {"width", IntegerReference},
214       {"height", IntegerReference}, {"fill", StringReference},
215       {"bordercolor", StringReference}, {"color", StringReference},
216       {"compose", MagickComposeOptions} } },
217     { "Blur", { {"geometry", StringReference}, {"radius", RealReference},
218       {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
219     { "Chop", { {"geometry", StringReference}, {"width", IntegerReference},
220       {"height", IntegerReference}, {"x", IntegerReference},
221       {"y", IntegerReference}, {"gravity", MagickGravityOptions} } },
222     { "Crop", { {"geometry", StringReference}, {"width", IntegerReference},
223       {"height", IntegerReference}, {"x", IntegerReference},
224       {"y", IntegerReference}, {"fuzz", StringReference},
225       {"gravity", MagickGravityOptions} } },
226     { "Despeckle", },
227     { "Edge", { {"radius", RealReference} } },
228     { "Emboss", { {"geometry", StringReference}, {"radius", RealReference},
229       {"sigma", RealReference} } },
230     { "Enhance", },
231     { "Flip", },
232     { "Flop", },
233     { "Frame", { {"geometry", StringReference}, {"width", IntegerReference},
234       {"height", IntegerReference}, {"inner", IntegerReference},
235       {"outer", IntegerReference}, {"fill", StringReference},
236       {"color", StringReference}, {"compose", MagickComposeOptions} } },
237     { "Implode", { {"amount", RealReference},
238       {"interpolate", MagickInterpolateOptions} } },
239     { "Magnify", },
240     { "MedianFilter", { {"geometry", StringReference},
241       {"width", IntegerReference}, {"height", IntegerReference},
242       {"channel", MagickChannelOptions} } },
243     { "Minify", },
244     { "OilPaint", { {"radius", RealReference}, {"sigma", RealReference} } },
245     { "ReduceNoise", { {"geometry", StringReference},
246       {"width", IntegerReference},{"height", IntegerReference},
247       {"channel", MagickChannelOptions} } },
248     { "Roll", { {"geometry", StringReference}, {"x", IntegerReference},
249       {"y", IntegerReference} } },
250     { "Rotate", { {"degrees", RealReference},
251       {"background", StringReference} } },
252     { "Sample", { {"geometry", StringReference}, {"width", IntegerReference},
253       {"height", IntegerReference} } },
254     { "Scale", { {"geometry", StringReference}, {"width", IntegerReference},
255       {"height", IntegerReference} } },
256     { "Shade", { {"geometry", StringReference}, {"azimuth", RealReference},
257       {"elevation", RealReference}, {"gray", MagickBooleanOptions} } },
258     { "Sharpen", { {"geometry", StringReference}, {"radius", RealReference},
259       {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
260     { "Shear", { {"geometry", StringReference}, {"x", RealReference},
261       {"y", RealReference}, { "fill", StringReference},
262       {"color", StringReference} } },
263     { "Spread", { {"radius", RealReference},
264       {"interpolate", MagickInterpolateOptions} } },
265     { "Swirl", { {"degrees", RealReference},
266       {"interpolate", MagickInterpolateOptions} } },
267     { "Resize", { {"geometry", StringReference}, {"width", IntegerReference},
268       {"height", IntegerReference}, {"filter", MagickFilterOptions},
269       {"support", StringReference } } },
270     { "Zoom", { {"geometry", StringReference}, {"width", IntegerReference},
271       {"height", IntegerReference}, {"filter", MagickFilterOptions},
272       {"support", RealReference } } },
273     { "Annotate", { {"text", StringReference}, {"font", StringReference},
274       {"pointsize", RealReference}, {"density", StringReference},
275       {"undercolor", StringReference}, {"stroke", StringReference},
276       {"fill", StringReference}, {"geometry", StringReference},
277       {"sans", StringReference}, {"x", RealReference},
278       {"y", RealReference}, {"gravity", MagickGravityOptions},
279       {"translate", StringReference}, {"scale", StringReference},
280       {"rotate", RealReference}, {"skewX", RealReference},
281       {"skewY", RealReference}, {"strokewidth", RealReference},
282       {"antialias", MagickBooleanOptions}, {"family", StringReference},
283       {"style", MagickStyleOptions}, {"stretch", MagickStretchOptions},
284       {"weight", IntegerReference}, {"align", MagickAlignOptions},
285       {"encoding", StringReference}, {"affine", ArrayReference},
286       {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
287       {"tile", ImageReference}, {"kerning", RealReference},
288       {"interline-spacing", RealReference},
289       {"interword-spacing", RealReference},
290       {"direction", MagickDirectionOptions} } },
291     { "ColorFloodfill", { {"geometry", StringReference},
292       {"x", IntegerReference}, {"y", IntegerReference},
293       {"fill", StringReference}, {"bordercolor", StringReference},
294       {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
295     { "Composite", { {"image", ImageReference},
296       {"compose", MagickComposeOptions}, {"geometry", StringReference},
297       {"x", IntegerReference}, {"y", IntegerReference},
298       {"gravity", MagickGravityOptions}, {"opacity", StringReference},
299       {"tile", MagickBooleanOptions}, {"rotate", RealReference},
300       {"color", StringReference}, {"mask", ImageReference},
301       {"channel", MagickChannelOptions},
302       {"interpolate", MagickInterpolateOptions}, {"args", StringReference},
303       {"blend", StringReference}, {"crop-to-self", MagickBooleanOptions} } },
304     { "Contrast", { {"sharpen", MagickBooleanOptions} } },
305     { "CycleColormap", { {"display", IntegerReference} } },
306     { "Draw", { {"primitive", MagickPrimitiveOptions},
307       {"points", StringReference}, {"method", MagickMethodOptions},
308       {"stroke", StringReference}, {"fill", StringReference},
309       {"strokewidth", RealReference}, {"font", StringReference},
310       {"bordercolor", StringReference}, {"x", RealReference},
311       {"y", RealReference}, {"translate", StringReference},
312       {"scale", StringReference}, {"rotate", RealReference},
313       {"skewX", RealReference}, {"skewY", RealReference},
314       {"tile", ImageReference}, {"pointsize", RealReference},
315       {"antialias", MagickBooleanOptions}, {"density", StringReference},
316       {"linewidth", RealReference}, {"affine", ArrayReference},
317       {"stroke-dashoffset", RealReference},
318       {"stroke-dasharray", ArrayReference},
319       {"interpolate", MagickInterpolateOptions},
320       {"origin", StringReference}, {"text", StringReference},
321       {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
322       {"vector-graphics", StringReference}, {"kerning", RealReference},
323       {"interline-spacing", RealReference},
324       {"interword-spacing", RealReference},
325       {"direction", MagickDirectionOptions} } },
326     { "Equalize", { {"channel", MagickChannelOptions} } },
327     { "Gamma", { {"gamma", StringReference}, {"channel", MagickChannelOptions},
328       {"red", RealReference}, {"green", RealReference},
329       {"blue", RealReference} } },
330     { "Map", { {"image", ImageReference},
331       {"dither-method", MagickDitherOptions} } },
332     { "MatteFloodfill", { {"geometry", StringReference},
333       {"x", IntegerReference}, {"y", IntegerReference},
334       {"opacity", StringReference}, {"bordercolor", StringReference},
335       {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
336     { "Modulate", { {"factor", StringReference}, {"hue", RealReference},
337       {"saturation", RealReference}, {"whiteness", RealReference},
338       {"brightness", RealReference}, {"lightness", RealReference},
339       {"blackness", RealReference} } },
340     { "Negate", { {"gray", MagickBooleanOptions},
341       {"channel", MagickChannelOptions} } },
342     { "Normalize", { {"channel", MagickChannelOptions} } },
343     { "NumberColors", },
344     { "Opaque", { {"color", StringReference}, {"fill", StringReference},
345       {"fuzz", StringReference}, {"channel", MagickChannelOptions},
346       {"invert", MagickBooleanOptions} } },
347     { "Quantize", { {"colors", IntegerReference},
348       {"treedepth", IntegerReference}, {"colorspace", MagickColorspaceOptions},
349       {"dither", MagickDitherOptions}, {"measure", MagickBooleanOptions},
350       {"global", MagickBooleanOptions}, {"transparent-color", StringReference},
351       {"dither-method", MagickDitherOptions} } },
352     { "Raise", { {"geometry", StringReference}, {"width", IntegerReference},
353       {"height", IntegerReference}, {"raise", MagickBooleanOptions} } },
354     { "Segment", { {"geometry", StringReference},
355       {"cluster-threshold", RealReference},
356       {"smoothing-threshold", RealReference},
357       {"colorspace", MagickColorspaceOptions},
358       {"verbose", MagickBooleanOptions} } },
359     { "Signature", },
360     { "Solarize", { {"geometry", StringReference},
361       {"threshold", StringReference} } },
362     { "Sync", },
363     { "Texture", { {"texture", ImageReference} } },
364     { "Evaluate", { {"value", RealReference},
365       {"operator", MagickEvaluateOptions},
366       {"channel", MagickChannelOptions} } },
367     { "Transparent", { {"color", StringReference}, {"opacity", StringReference},
368       {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
369     { "Threshold", { {"threshold", StringReference},
370       {"channel", MagickChannelOptions} } },
371     { "Charcoal", { {"geometry", StringReference}, {"radius", RealReference},
372       {"sigma", RealReference} } },
373     { "Trim", { {"fuzz", StringReference} } },
374     { "Wave", { {"geometry", StringReference}, {"amplitude", RealReference},
375       {"wavelength", RealReference},
376       {"interpolate", MagickInterpolateOptions} } },
377     { "Separate", { {"channel", MagickChannelOptions} } },
378     { "Condense", },
379     { "Stereo", { {"image", ImageReference}, {"x", IntegerReference},
380       {"y", IntegerReference} } },
381     { "Stegano", { {"image", ImageReference}, {"offset", IntegerReference} } },
382     { "Deconstruct", },
383     { "GaussianBlur", { {"geometry", StringReference},
384       {"radius", RealReference}, {"sigma", RealReference},
385       {"channel", MagickChannelOptions} } },
386     { "Convolve", { {"coefficients", ArrayReference},
387       {"channel", MagickChannelOptions}, {"bias", StringReference},
388       {"kernel", StringReference} } },
389     { "Profile", { {"name", StringReference}, {"profile", StringReference},
390       { "rendering-intent", MagickIntentOptions},
391       { "black-point-compensation", MagickBooleanOptions} } },
392     { "UnsharpMask", { {"geometry", StringReference},
393       {"radius", RealReference}, {"sigma", RealReference},
394       {"gain", RealReference}, {"threshold", RealReference},
395       {"channel", MagickChannelOptions} } },
396     { "MotionBlur", { {"geometry", StringReference},
397       {"radius", RealReference}, {"sigma", RealReference},
398       {"angle", RealReference}, {"channel", MagickChannelOptions} } },
399     { "OrderedDither", { {"threshold", StringReference},
400       {"channel", MagickChannelOptions} } },
401     { "Shave", { {"geometry", StringReference}, {"width", IntegerReference},
402       {"height", IntegerReference} } },
403     { "Level", { {"levels", StringReference}, {"black-point", RealReference},
404       {"white-point", RealReference}, {"gamma", RealReference},
405       {"channel", MagickChannelOptions}, {"level", StringReference} } },
406     { "Clip", { {"id", StringReference}, {"inside", MagickBooleanOptions} } },
407     { "AffineTransform", { {"affine", ArrayReference},
408       {"translate", StringReference}, {"scale", StringReference},
409       {"rotate", RealReference}, {"skewX", RealReference},
410       {"skewY", RealReference}, {"interpolate", MagickInterpolateOptions},
411       {"background", StringReference} } },
412     { "Difference", { {"image", ImageReference}, {"fuzz", StringReference} } },
413     { "AdaptiveThreshold", { {"geometry", StringReference},
414       {"width", IntegerReference}, {"height", IntegerReference} } },
415     { "Resample", { {"density", StringReference}, {"x", RealReference},
416       {"y", RealReference}, {"filter", MagickFilterOptions},
417       {"support", RealReference } } },
418     { "Describe", { {"file", FileReference} } },
419     { "BlackThreshold", { {"threshold", StringReference},
420       {"channel", MagickChannelOptions} } },
421     { "WhiteThreshold", { {"threshold", StringReference},
422       {"channel", MagickChannelOptions} } },
423     { "RotationalBlur", { {"geometry", StringReference},
424       {"angle", RealReference}, {"channel", MagickChannelOptions} } },
425     { "Thumbnail", { {"geometry", StringReference}, {"width", IntegerReference},
426       {"height", IntegerReference} } },
427     { "Strip", },
428     { "Tint", { {"fill", StringReference}, {"blend", StringReference} } },
429     { "Channel", { {"channel", MagickChannelOptions} } },
430     { "Splice", { {"geometry", StringReference}, {"width", IntegerReference},
431       {"height", IntegerReference}, {"x", IntegerReference},
432       {"y", IntegerReference}, {"fuzz", StringReference},
433       {"background", StringReference}, {"gravity", MagickGravityOptions} } },
434     { "Posterize", { {"levels", IntegerReference},
435       {"dither", MagickBooleanOptions} } },
436     { "Shadow", { {"geometry", StringReference}, {"alpha", RealReference},
437       {"sigma", RealReference}, {"x", IntegerReference},
438       {"y", IntegerReference} } },
439     { "Identify", { {"file", FileReference}, {"features", StringReference},
440       {"unique", MagickBooleanOptions} } },
441     { "SepiaTone", { {"threshold", RealReference} } },
442     { "SigmoidalContrast", { {"geometry", StringReference},
443       {"contrast", RealReference}, {"mid-point", RealReference},
444       {"channel", MagickChannelOptions}, {"sharpen", MagickBooleanOptions} } },
445     { "Extent", { {"geometry", StringReference}, {"width", IntegerReference},
446       {"height", IntegerReference}, {"x", IntegerReference},
447       {"y", IntegerReference}, {"fuzz", StringReference},
448       {"background", StringReference}, {"gravity", MagickGravityOptions} } },
449     { "Vignette", { {"geometry", StringReference}, {"radius", RealReference},
450       {"sigma", RealReference}, {"x", IntegerReference},
451       {"y", IntegerReference}, {"background", StringReference} } },
452     { "ContrastStretch", { {"levels", StringReference},
453       {"black-point", RealReference},{"white-point", RealReference},
454       {"channel", MagickChannelOptions} } },
455     { "Sans0", },
456     { "Sans1", },
457     { "AdaptiveSharpen", { {"geometry", StringReference},
458       {"radius", RealReference}, {"sigma", RealReference},
459       {"bias", RealReference}, {"channel", MagickChannelOptions} } },
460     { "Transpose", },
461     { "Transverse", },
462     { "AutoOrient", },
463     { "AdaptiveBlur", { {"geometry", StringReference},
464       {"radius", RealReference}, {"sigma", RealReference},
465       {"channel", MagickChannelOptions} } },
466     { "Sketch", { {"geometry", StringReference},
467       {"radius", RealReference}, {"sigma", RealReference},
468       {"angle", RealReference} } },
469     { "UniqueColors", },
470     { "AdaptiveResize", { {"geometry", StringReference},
471       {"width", IntegerReference}, {"height", IntegerReference},
472       {"filter", MagickFilterOptions}, {"support", StringReference },
473       {"blur", RealReference } } },
474     { "ClipMask", { {"mask", ImageReference} } },
475     { "LinearStretch", { {"levels", StringReference},
476       {"black-point", RealReference},{"white-point", RealReference} } },
477     { "ColorMatrix", { {"matrix", ArrayReference} } },
478     { "Mask", { {"mask", ImageReference} } },
479     { "Polaroid", { {"caption", StringReference}, {"angle", RealReference},
480       {"font", StringReference}, {"stroke", StringReference},
481       {"fill", StringReference}, {"strokewidth", RealReference},
482       {"pointsize", RealReference}, {"gravity", MagickGravityOptions},
483       {"background", StringReference},
484       {"interpolate", MagickInterpolateOptions} } },
485     { "FloodfillPaint", { {"geometry", StringReference},
486       {"x", IntegerReference}, {"y", IntegerReference},
487       {"fill", StringReference}, {"bordercolor", StringReference},
488       {"fuzz", StringReference}, {"channel", MagickChannelOptions},
489       {"invert", MagickBooleanOptions} } },
490     { "Distort", { {"points", ArrayReference}, {"method", MagickDistortOptions},
491       {"virtual-pixel", MagickVirtualPixelOptions},
492       {"best-fit", MagickBooleanOptions} } },
493     { "Clut", { {"image", ImageReference},
494       {"interpolate", MagickInterpolateOptions},
495       {"channel", MagickChannelOptions} } },
496     { "LiquidRescale", { {"geometry", StringReference},
497       {"width", IntegerReference}, {"height", IntegerReference},
498       {"delta-x", RealReference}, {"rigidity", RealReference } } },
499     { "Encipher", { {"passphrase", StringReference} } },
500     { "Decipher", { {"passphrase", StringReference} } },
501     { "Deskew", { {"geometry", StringReference},
502       {"threshold", StringReference} } },
503     { "Remap", { {"image", ImageReference},
504       {"dither-method", MagickDitherOptions} } },
505     { "SparseColor", { {"points", ArrayReference},
506       {"method", MagickSparseColorOptions},
507       {"virtual-pixel", MagickVirtualPixelOptions},
508       {"channel", MagickChannelOptions} } },
509     { "Function", { {"parameters", ArrayReference},
510       {"function", MagickFunctionOptions},
511       {"virtual-pixel", MagickVirtualPixelOptions} } },
512     { "SelectiveBlur", { {"geometry", StringReference},
513       {"radius", RealReference}, {"sigma", RealReference},
514       {"threshold", RealReference}, {"channel", MagickChannelOptions} } },
515     { "HaldClut", { {"image", ImageReference},
516       {"channel", MagickChannelOptions} } },
517     { "BlueShift", { {"factor", StringReference} } },
518     { "ForwardFourierTransform", { {"magnitude", MagickBooleanOptions} } },
519     { "InverseFourierTransform", { {"magnitude", MagickBooleanOptions} } },
520     { "ColorDecisionList", {
521       {"color-correction-collection", StringReference} } },
522     { "AutoGamma", { {"channel", MagickChannelOptions} } },
523     { "AutoLevel", { {"channel", MagickChannelOptions} } },
524     { "LevelColors", { {"invert", MagickBooleanOptions},
525       {"black-point", StringReference}, {"white-point", StringReference},
526       {"channel", MagickChannelOptions}, {"invert", MagickBooleanOptions} } },
527     { "Clamp", { {"channel", MagickChannelOptions} } },
528     { "BrightnessContrast", { {"levels", StringReference},
529       {"brightness", RealReference},{"contrast", RealReference},
530       {"channel", MagickChannelOptions} } },
531     { "Morphology", { {"kernel", StringReference},
532       {"channel", MagickChannelOptions}, {"method", MagickMorphologyOptions},
533       {"iterations", IntegerReference} } },
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     { "Grayscale", { {"method", MagickNoiseOptions} } },
545     { "CannyEdge", { {"geometry", StringReference},
546       {"radius", RealReference}, {"sigma", RealReference},
547       {"lower-percent", RealReference}, {"upper-percent", RealReference} } },
548     { "HoughLine", { {"geometry", StringReference},
549       {"width", IntegerReference}, {"height", IntegerReference},
550       {"threshold", IntegerReference} } },
551     { "MeanShift", { {"geometry", StringReference},
552       {"width", IntegerReference}, {"height", IntegerReference},
553       {"distance", RealReference} } },
554     { "Kuwahara", { {"geometry", StringReference}, {"radius", RealReference},
555       {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
556     { "ConnectedComponents", { {"connectivity", IntegerReference} } },
557     { "CopyPixels", { {"image", ImageReference}, {"geometry", StringReference},
558       {"width", IntegerReference}, {"height", IntegerReference},
559       {"x", IntegerReference}, {"y", IntegerReference},
560       {"gravity", MagickGravityOptions}, {"offset", StringReference},
561       {"dx", IntegerReference}, {"dy", IntegerReference} } },
562     { "Color", { {"color", StringReference} } },
563     { "WaveletDenoise", {  {"geometry", StringReference},
564       {"threshold", RealReference}, {"softness", RealReference},
565       {"channel", MagickChannelOptions} } },
566   };
567 
568 static SplayTreeInfo
569   *magick_registry = (SplayTreeInfo *) NULL;
570 
571 /*
572   Forward declarations.
573 */
574 static Image
575   *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
576 
577 static ssize_t
578   strEQcase(const char *,const char *);
579 
580 /*
581 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
582 %                                                                             %
583 %                                                                             %
584 %                                                                             %
585 %   C l o n e P a c k a g e I n f o                                           %
586 %                                                                             %
587 %                                                                             %
588 %                                                                             %
589 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
590 %
591 %  ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
592 %  a new one.
593 %
594 %  The format of the ClonePackageInfo routine is:
595 %
596 %      struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
597 %        exception)
598 %
599 %  A description of each parameter follows:
600 %
601 %    o info: a structure of type info.
602 %
603 %    o exception: Return any errors or warnings in this structure.
604 %
605 */
ClonePackageInfo(struct PackageInfo * info,ExceptionInfo * exception)606 static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
607   ExceptionInfo *exception)
608 {
609   struct PackageInfo
610     *clone_info;
611 
612   clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
613   if (clone_info == (struct PackageInfo *) NULL)
614     {
615       ThrowPerlException(exception,ResourceLimitError,
616         "UnableToClonePackageInfo",PackageName);
617       return((struct PackageInfo *) NULL);
618     }
619   if (info == (struct PackageInfo *) NULL)
620     {
621       clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
622       return(clone_info);
623     }
624   *clone_info=(*info);
625   clone_info->image_info=CloneImageInfo(info->image_info);
626   return(clone_info);
627 }
628 
629 /*
630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
631 %                                                                             %
632 %                                                                             %
633 %                                                                             %
634 %   c o n s t a n t                                                           %
635 %                                                                             %
636 %                                                                             %
637 %                                                                             %
638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
639 %
640 %  constant() returns a double value for the specified name.
641 %
642 %  The format of the constant routine is:
643 %
644 %      double constant(char *name,ssize_t sans)
645 %
646 %  A description of each parameter follows:
647 %
648 %    o value: Method constant returns a double value for the specified name.
649 %
650 %    o name: The name of the constant.
651 %
652 %    o sans: This integer value is not used.
653 %
654 */
constant(char * name,ssize_t sans)655 static double constant(char *name,ssize_t sans)
656 {
657   (void) sans;
658   errno=0;
659   switch (*name)
660   {
661     case 'B':
662     {
663       if (strEQ(name,"BlobError"))
664         return(BlobError);
665       if (strEQ(name,"BlobWarning"))
666         return(BlobWarning);
667       break;
668     }
669     case 'C':
670     {
671       if (strEQ(name,"CacheError"))
672         return(CacheError);
673       if (strEQ(name,"CacheWarning"))
674         return(CacheWarning);
675       if (strEQ(name,"CoderError"))
676         return(CoderError);
677       if (strEQ(name,"CoderWarning"))
678         return(CoderWarning);
679       if (strEQ(name,"ConfigureError"))
680         return(ConfigureError);
681       if (strEQ(name,"ConfigureWarning"))
682         return(ConfigureWarning);
683       if (strEQ(name,"CorruptImageError"))
684         return(CorruptImageError);
685       if (strEQ(name,"CorruptImageWarning"))
686         return(CorruptImageWarning);
687       break;
688     }
689     case 'D':
690     {
691       if (strEQ(name,"DelegateError"))
692         return(DelegateError);
693       if (strEQ(name,"DelegateWarning"))
694         return(DelegateWarning);
695       if (strEQ(name,"DrawError"))
696         return(DrawError);
697       if (strEQ(name,"DrawWarning"))
698         return(DrawWarning);
699       break;
700     }
701     case 'E':
702     {
703       if (strEQ(name,"ErrorException"))
704         return(ErrorException);
705       if (strEQ(name,"ExceptionError"))
706         return(CoderError);
707       if (strEQ(name,"ExceptionWarning"))
708         return(CoderWarning);
709       break;
710     }
711     case 'F':
712     {
713       if (strEQ(name,"FatalErrorException"))
714         return(FatalErrorException);
715       if (strEQ(name,"FileOpenError"))
716         return(FileOpenError);
717       if (strEQ(name,"FileOpenWarning"))
718         return(FileOpenWarning);
719       break;
720     }
721     case 'I':
722     {
723       if (strEQ(name,"ImageError"))
724         return(ImageError);
725       if (strEQ(name,"ImageWarning"))
726         return(ImageWarning);
727       break;
728     }
729     case 'M':
730     {
731       if (strEQ(name,"MaxRGB"))
732         return(QuantumRange);
733       if (strEQ(name,"MissingDelegateError"))
734         return(MissingDelegateError);
735       if (strEQ(name,"MissingDelegateWarning"))
736         return(MissingDelegateWarning);
737       if (strEQ(name,"ModuleError"))
738         return(ModuleError);
739       if (strEQ(name,"ModuleWarning"))
740         return(ModuleWarning);
741       break;
742     }
743     case 'O':
744     {
745       if (strEQ(name,"Opaque"))
746         return(OpaqueAlpha);
747       if (strEQ(name,"OptionError"))
748         return(OptionError);
749       if (strEQ(name,"OptionWarning"))
750         return(OptionWarning);
751       break;
752     }
753     case 'Q':
754     {
755       if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
756         return(MAGICKCORE_QUANTUM_DEPTH);
757       if (strEQ(name,"QuantumDepth"))
758         return(MAGICKCORE_QUANTUM_DEPTH);
759       if (strEQ(name,"QuantumRange"))
760         return(QuantumRange);
761       break;
762     }
763     case 'R':
764     {
765       if (strEQ(name,"ResourceLimitError"))
766         return(ResourceLimitError);
767       if (strEQ(name,"ResourceLimitWarning"))
768         return(ResourceLimitWarning);
769       if (strEQ(name,"RegistryError"))
770         return(RegistryError);
771       if (strEQ(name,"RegistryWarning"))
772         return(RegistryWarning);
773       break;
774     }
775     case 'S':
776     {
777       if (strEQ(name,"StreamError"))
778         return(StreamError);
779       if (strEQ(name,"StreamWarning"))
780         return(StreamWarning);
781       if (strEQ(name,"Success"))
782         return(0);
783       break;
784     }
785     case 'T':
786     {
787       if (strEQ(name,"Transparent"))
788         return(TransparentAlpha);
789       if (strEQ(name,"TypeError"))
790         return(TypeError);
791       if (strEQ(name,"TypeWarning"))
792         return(TypeWarning);
793       break;
794     }
795     case 'W':
796     {
797       if (strEQ(name,"WarningException"))
798         return(WarningException);
799       break;
800     }
801     case 'X':
802     {
803       if (strEQ(name,"XServerError"))
804         return(XServerError);
805       if (strEQ(name,"XServerWarning"))
806         return(XServerWarning);
807       break;
808     }
809   }
810   errno=EINVAL;
811   return(0);
812 }
813 
814 /*
815 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
816 %                                                                             %
817 %                                                                             %
818 %                                                                             %
819 %   D e s t r o y P a c k a g e I n f o                                       %
820 %                                                                             %
821 %                                                                             %
822 %                                                                             %
823 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
824 %
825 %  Method DestroyPackageInfo frees a previously created info structure.
826 %
827 %  The format of the DestroyPackageInfo routine is:
828 %
829 %      DestroyPackageInfo(struct PackageInfo *info)
830 %
831 %  A description of each parameter follows:
832 %
833 %    o info: a structure of type info.
834 %
835 */
DestroyPackageInfo(struct PackageInfo * info)836 static void DestroyPackageInfo(struct PackageInfo *info)
837 {
838   info->image_info=DestroyImageInfo(info->image_info);
839   info=(struct PackageInfo *) RelinquishMagickMemory(info);
840 }
841 
842 /*
843 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
844 %                                                                             %
845 %                                                                             %
846 %                                                                             %
847 %   G e t L i s t                                                             %
848 %                                                                             %
849 %                                                                             %
850 %                                                                             %
851 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
852 %
853 %  Method GetList is recursively called by SetupList to traverse the
854 %  Image__Magick reference.  If building an reference_vector (see SetupList),
855 %  *current is the current position in *reference_vector and *last is the final
856 %  entry in *reference_vector.
857 %
858 %  The format of the GetList routine is:
859 %
860 %      GetList(info)
861 %
862 %  A description of each parameter follows:
863 %
864 %    o info: a structure of type info.
865 %
866 */
GetList(pTHX_ SV * reference,SV *** reference_vector,ssize_t * current,ssize_t * last,ExceptionInfo * exception)867 static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
868   ssize_t *current,ssize_t *last,ExceptionInfo *exception)
869 {
870   Image
871     *image;
872 
873   if (reference == (SV *) NULL)
874     return(NULL);
875   switch (SvTYPE(reference))
876   {
877     case SVt_PVAV:
878     {
879       AV
880         *av;
881 
882       Image
883         *head,
884         *previous;
885 
886       register ssize_t
887         i;
888 
889       ssize_t
890         n;
891 
892       /*
893         Array of images.
894       */
895       previous=(Image *) NULL;
896       head=(Image *) NULL;
897       av=(AV *) reference;
898       n=av_len(av);
899       for (i=0; i <= n; i++)
900       {
901         SV
902           **rv;
903 
904         rv=av_fetch(av,i,0);
905         if (rv && *rv && sv_isobject(*rv))
906           {
907             image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
908               exception);
909             if (image == (Image *) NULL)
910               continue;
911             if (image == previous)
912               {
913                 image=CloneImage(image,0,0,MagickTrue,exception);
914                 if (image == (Image *) NULL)
915                   return(NULL);
916               }
917             image->previous=previous;
918             *(previous ? &previous->next : &head)=image;
919             for (previous=image; previous->next; previous=previous->next) ;
920           }
921       }
922       return(head);
923     }
924     case SVt_PVMG:
925     {
926       /*
927         Blessed scalar, one image.
928       */
929       image=INT2PTR(Image *,SvIV(reference));
930       if (image == (Image *) NULL)
931         return(NULL);
932       image->previous=(Image *) NULL;
933       image->next=(Image *) NULL;
934       if (reference_vector)
935         {
936           if (*current == *last)
937             {
938               *last+=256;
939               if (*reference_vector == (SV **) NULL)
940                 *reference_vector=(SV **) AcquireQuantumMemory(*last,
941                   sizeof(*reference_vector));
942               else
943                 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
944                   *last,sizeof(*reference_vector));
945             }
946           if (*reference_vector == (SV **) NULL)
947             {
948               ThrowPerlException(exception,ResourceLimitError,
949                 "MemoryAllocationFailed",PackageName);
950               return((Image *) NULL);
951             }
952           (*reference_vector)[*current]=reference;
953           (*reference_vector)[++(*current)]=NULL;
954         }
955       return(image);
956     }
957     default:
958       break;
959   }
960   (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
961     (double) SvTYPE(reference));
962   return((Image *) NULL);
963 }
964 
965 /*
966 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
967 %                                                                             %
968 %                                                                             %
969 %                                                                             %
970 %   G e t P a c k a g e I n f o                                               %
971 %                                                                             %
972 %                                                                             %
973 %                                                                             %
974 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
975 %
976 %  Method GetPackageInfo looks up or creates an info structure for the given
977 %  Image__Magick reference.  If it does create a new one, the information in
978 %  package_info is used to initialize it.
979 %
980 %  The format of the GetPackageInfo routine is:
981 %
982 %      struct PackageInfo *GetPackageInfo(void *reference,
983 %        struct PackageInfo *package_info,ExceptionInfo *exception)
984 %
985 %  A description of each parameter follows:
986 %
987 %    o info: a structure of type info.
988 %
989 %    o exception: Return any errors or warnings in this structure.
990 %
991 */
GetPackageInfo(pTHX_ void * reference,struct PackageInfo * package_info,ExceptionInfo * exception)992 static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
993   struct PackageInfo *package_info,ExceptionInfo *exception)
994 {
995   char
996     message[MagickPathExtent];
997 
998   struct PackageInfo
999     *clone_info;
1000 
1001   SV
1002     *sv;
1003 
1004   (void) FormatLocaleString(message,MagickPathExtent,"%s::package%s%p",
1005     PackageName,XS_VERSION,reference);
1006   sv=perl_get_sv(message,(TRUE | 0x02));
1007   if (sv == (SV *) NULL)
1008     {
1009       ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
1010         message);
1011       return(package_info);
1012     }
1013   if (SvREFCNT(sv) == 0)
1014     (void) SvREFCNT_inc(sv);
1015   if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
1016     return(clone_info);
1017   clone_info=ClonePackageInfo(package_info,exception);
1018   sv_setiv(sv,PTR2IV(clone_info));
1019   return(clone_info);
1020 }
1021 
1022 /*
1023 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1024 %                                                                             %
1025 %                                                                             %
1026 %                                                                             %
1027 %   S e t A t t r i b u t e                                                   %
1028 %                                                                             %
1029 %                                                                             %
1030 %                                                                             %
1031 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1032 %
1033 %  SetAttribute() sets the attribute to the value in sval.  This can change
1034 %  either or both of image or info.
1035 %
1036 %  The format of the SetAttribute routine is:
1037 %
1038 %      SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1039 %        SV *sval,ExceptionInfo *exception)
1040 %
1041 %  A description of each parameter follows:
1042 %
1043 %    o list: a list of strings.
1044 %
1045 %    o string: a character string.
1046 %
1047 */
1048 
SiPrefixToDoubleInterval(const char * string,const double interval)1049 static double SiPrefixToDoubleInterval(const char *string,const double interval)
1050 {
1051   char
1052     *q;
1053 
1054   double
1055     value;
1056 
1057   value=InterpretSiPrefixValue(string,&q);
1058   if (*q == '%')
1059     value*=interval/100.0;
1060   return(value);
1061 }
1062 
StringToDouble(const char * string,char ** sentinal)1063 static inline double StringToDouble(const char *string,char **sentinal)
1064 {
1065   return(InterpretLocaleValue(string,sentinal));
1066 }
1067 
StringToDoubleInterval(const char * string,const double interval)1068 static double StringToDoubleInterval(const char *string,const double interval)
1069 {
1070   char
1071     *q;
1072 
1073   double
1074     value;
1075 
1076   value=InterpretLocaleValue(string,&q);
1077   if (*q == '%')
1078     value*=interval/100.0;
1079   return(value);
1080 }
1081 
StringToLong(const char * value)1082 static inline ssize_t StringToLong(const char *value)
1083 {
1084   return(strtol(value,(char **) NULL,10));
1085 }
1086 
SetAttribute(pTHX_ struct PackageInfo * info,Image * image,const char * attribute,SV * sval,ExceptionInfo * exception)1087 static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1088   const char *attribute,SV *sval,ExceptionInfo *exception)
1089 {
1090   GeometryInfo
1091     geometry_info;
1092 
1093   long
1094     x,
1095     y;
1096 
1097   PixelInfo
1098     pixel;
1099 
1100   MagickStatusType
1101     flags;
1102 
1103   PixelInfo
1104     *color,
1105     target_color;
1106 
1107   ssize_t
1108     sp;
1109 
1110   switch (*attribute)
1111   {
1112     case 'A':
1113     case 'a':
1114     {
1115       if (LocaleCompare(attribute,"adjoin") == 0)
1116         {
1117           sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1118             SvPV(sval,na)) : SvIV(sval);
1119           if (sp < 0)
1120             {
1121               ThrowPerlException(exception,OptionError,"UnrecognizedType",
1122                 SvPV(sval,na));
1123               break;
1124             }
1125           if (info)
1126             info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1127           break;
1128         }
1129       if (LocaleCompare(attribute,"alpha") == 0)
1130         {
1131           sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1132             MagickFalse,SvPV(sval,na)) : SvIV(sval);
1133           if (sp < 0)
1134             {
1135               ThrowPerlException(exception,OptionError,"UnrecognizedType",
1136                 SvPV(sval,na));
1137               break;
1138             }
1139           for ( ; image; image=image->next)
1140             (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1141               exception);
1142           break;
1143         }
1144       if (LocaleCompare(attribute,"antialias") == 0)
1145         {
1146           sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1147             SvPV(sval,na)) : SvIV(sval);
1148           if (sp < 0)
1149             {
1150               ThrowPerlException(exception,OptionError,"UnrecognizedType",
1151                 SvPV(sval,na));
1152               break;
1153             }
1154           if (info)
1155             info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1156           break;
1157         }
1158       if (LocaleCompare(attribute,"area-limit") == 0)
1159         {
1160           MagickSizeType
1161             limit;
1162 
1163           limit=MagickResourceInfinity;
1164           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1165             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1166               100.0);
1167           (void) SetMagickResourceLimit(AreaResource,limit);
1168           break;
1169         }
1170       if (LocaleCompare(attribute,"attenuate") == 0)
1171         {
1172           if (info)
1173             (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1174           break;
1175         }
1176       if (LocaleCompare(attribute,"authenticate") == 0)
1177         {
1178           if (info)
1179             SetImageOption(info->image_info,attribute,SvPV(sval,na));
1180           break;
1181         }
1182       if (info)
1183         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1184       for ( ; image; image=image->next)
1185         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1186       break;
1187     }
1188     case 'B':
1189     case 'b':
1190     {
1191       if (LocaleCompare(attribute,"background") == 0)
1192         {
1193           (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1194             exception);
1195           if (info)
1196             info->image_info->background_color=target_color;
1197           for ( ; image; image=image->next)
1198             image->background_color=target_color;
1199           break;
1200         }
1201       if (LocaleCompare(attribute,"blue-primary") == 0)
1202         {
1203           for ( ; image; image=image->next)
1204           {
1205             flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1206             image->chromaticity.blue_primary.x=geometry_info.rho;
1207             image->chromaticity.blue_primary.y=geometry_info.sigma;
1208             if ((flags & SigmaValue) == 0)
1209               image->chromaticity.blue_primary.y=
1210                 image->chromaticity.blue_primary.x;
1211           }
1212           break;
1213         }
1214       if (LocaleCompare(attribute,"bordercolor") == 0)
1215         {
1216           (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1217             exception);
1218           if (info)
1219             info->image_info->border_color=target_color;
1220           for ( ; image; image=image->next)
1221             image->border_color=target_color;
1222           break;
1223         }
1224       if (info)
1225         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1226       for ( ; image; image=image->next)
1227         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1228       break;
1229     }
1230     case 'C':
1231     case 'c':
1232     {
1233       if (LocaleCompare(attribute,"cache-threshold") == 0)
1234         {
1235           (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1236             SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1237           (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1238             (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1239           break;
1240         }
1241       if (LocaleCompare(attribute,"clip-mask") == 0)
1242         {
1243           Image
1244             *clip_mask;
1245 
1246           clip_mask=(Image *) NULL;
1247           if (SvPOK(sval))
1248             clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1249           for ( ; image; image=image->next)
1250             SetImageMask(image,ReadPixelMask,clip_mask,exception);
1251           break;
1252         }
1253       if (LocaleNCompare(attribute,"colormap",8) == 0)
1254         {
1255           for ( ; image; image=image->next)
1256           {
1257             int
1258               items;
1259 
1260             long
1261               i;
1262 
1263             if (image->storage_class == DirectClass)
1264               continue;
1265             i=0;
1266             items=sscanf(attribute,"%*[^[][%ld",&i);
1267             (void) items;
1268             if (i > (ssize_t) image->colors)
1269               i%=image->colors;
1270             if ((strchr(SvPV(sval,na),',') == 0) ||
1271                 (strchr(SvPV(sval,na),')') != 0))
1272               QueryColorCompliance(SvPV(sval,na),AllCompliance,
1273                 image->colormap+i,exception);
1274             else
1275               {
1276                 color=image->colormap+i;
1277                 pixel.red=color->red;
1278                 pixel.green=color->green;
1279                 pixel.blue=color->blue;
1280                 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1281                 pixel.red=geometry_info.rho;
1282                 pixel.green=geometry_info.sigma;
1283                 pixel.blue=geometry_info.xi;
1284                 color->red=ClampToQuantum(pixel.red);
1285                 color->green=ClampToQuantum(pixel.green);
1286                 color->blue=ClampToQuantum(pixel.blue);
1287               }
1288           }
1289           break;
1290         }
1291       if (LocaleCompare(attribute,"colorspace") == 0)
1292         {
1293           sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1294             MagickFalse,SvPV(sval,na)) : SvIV(sval);
1295           if (sp < 0)
1296             {
1297               ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1298                 SvPV(sval,na));
1299               break;
1300             }
1301           for ( ; image; image=image->next)
1302             (void) TransformImageColorspace(image,(ColorspaceType) sp,
1303               exception);
1304           break;
1305         }
1306       if (LocaleCompare(attribute,"comment") == 0)
1307         {
1308           for ( ; image; image=image->next)
1309             (void) SetImageProperty(image,"Comment",InterpretImageProperties(
1310               info ? info->image_info : (ImageInfo *) NULL,image,
1311               SvPV(sval,na),exception),exception);
1312           break;
1313         }
1314       if (LocaleCompare(attribute,"compression") == 0)
1315         {
1316           sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1317             MagickFalse,SvPV(sval,na)) : SvIV(sval);
1318           if (sp < 0)
1319             {
1320               ThrowPerlException(exception,OptionError,
1321                 "UnrecognizedImageCompression",SvPV(sval,na));
1322               break;
1323             }
1324           if (info)
1325             info->image_info->compression=(CompressionType) sp;
1326           for ( ; image; image=image->next)
1327             image->compression=(CompressionType) sp;
1328           break;
1329         }
1330       if (info)
1331         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1332       for ( ; image; image=image->next)
1333         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1334       break;
1335     }
1336     case 'D':
1337     case 'd':
1338     {
1339       if (LocaleCompare(attribute,"debug") == 0)
1340         {
1341           SetLogEventMask(SvPV(sval,na));
1342           break;
1343         }
1344       if (LocaleCompare(attribute,"delay") == 0)
1345         {
1346           flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1347           for ( ; image; image=image->next)
1348           {
1349             image->delay=(size_t) floor(geometry_info.rho+0.5);
1350             if ((flags & SigmaValue) != 0)
1351               image->ticks_per_second=(ssize_t)
1352                 floor(geometry_info.sigma+0.5);
1353           }
1354           break;
1355         }
1356       if (LocaleCompare(attribute,"disk-limit") == 0)
1357         {
1358           MagickSizeType
1359             limit;
1360 
1361           limit=MagickResourceInfinity;
1362           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1363             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1364               100.0);
1365           (void) SetMagickResourceLimit(DiskResource,limit);
1366           break;
1367         }
1368       if (LocaleCompare(attribute,"density") == 0)
1369         {
1370           if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1371             {
1372               ThrowPerlException(exception,OptionError,"MissingGeometry",
1373                 SvPV(sval,na));
1374               break;
1375             }
1376           if (info)
1377             (void) CloneString(&info->image_info->density,SvPV(sval,na));
1378           for ( ; image; image=image->next)
1379           {
1380             flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1381             image->resolution.x=geometry_info.rho;
1382             image->resolution.y=geometry_info.sigma;
1383             if ((flags & SigmaValue) == 0)
1384               image->resolution.y=image->resolution.x;
1385           }
1386           break;
1387         }
1388       if (LocaleCompare(attribute,"depth") == 0)
1389         {
1390           if (info)
1391             info->image_info->depth=SvIV(sval);
1392           for ( ; image; image=image->next)
1393             (void) SetImageDepth(image,SvIV(sval),exception);
1394           break;
1395         }
1396       if (LocaleCompare(attribute,"dispose") == 0)
1397         {
1398           sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1399             SvPV(sval,na)) : SvIV(sval);
1400           if (sp < 0)
1401             {
1402               ThrowPerlException(exception,OptionError,
1403                 "UnrecognizedDisposeMethod",SvPV(sval,na));
1404               break;
1405             }
1406           for ( ; image; image=image->next)
1407             image->dispose=(DisposeType) sp;
1408           break;
1409         }
1410       if (LocaleCompare(attribute,"dither") == 0)
1411         {
1412           if (info)
1413             {
1414               sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1415                 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1416               if (sp < 0)
1417                 {
1418                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
1419                     SvPV(sval,na));
1420                   break;
1421                 }
1422               info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1423             }
1424           break;
1425         }
1426       if (LocaleCompare(attribute,"display") == 0)
1427         {
1428           display:
1429           if (info)
1430             (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1431           break;
1432         }
1433       if (info)
1434         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1435       for ( ; image; image=image->next)
1436         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1437       break;
1438     }
1439     case 'E':
1440     case 'e':
1441     {
1442       if (LocaleCompare(attribute,"endian") == 0)
1443         {
1444           sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1445             SvPV(sval,na)) : SvIV(sval);
1446           if (sp < 0)
1447             {
1448               ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1449                 SvPV(sval,na));
1450               break;
1451             }
1452           if (info)
1453             info->image_info->endian=(EndianType) sp;
1454           for ( ; image; image=image->next)
1455             image->endian=(EndianType) sp;
1456           break;
1457         }
1458       if (LocaleCompare(attribute,"extract") == 0)
1459         {
1460           /*
1461             Set image extract geometry.
1462           */
1463           (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1464           break;
1465         }
1466       if (info)
1467         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1468       for ( ; image; image=image->next)
1469         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1470       break;
1471     }
1472     case 'F':
1473     case 'f':
1474     {
1475       if (LocaleCompare(attribute,"filename") == 0)
1476         {
1477           if (info)
1478             (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
1479               MagickPathExtent);
1480           for ( ; image; image=image->next)
1481             (void) CopyMagickString(image->filename,SvPV(sval,na),
1482               MagickPathExtent);
1483           break;
1484         }
1485       if (LocaleCompare(attribute,"file") == 0)
1486         {
1487           FILE
1488             *file;
1489 
1490           PerlIO
1491             *io_info;
1492 
1493           if (info == (struct PackageInfo *) NULL)
1494             break;
1495           io_info=IoIFP(sv_2io(sval));
1496           if (io_info == (PerlIO *) NULL)
1497             {
1498               ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1499                 PackageName);
1500               break;
1501             }
1502           file=PerlIO_findFILE(io_info);
1503           if (file == (FILE *) NULL)
1504             {
1505               ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1506                 PackageName);
1507               break;
1508             }
1509           SetImageInfoFile(info->image_info,file);
1510           break;
1511         }
1512       if (LocaleCompare(attribute,"fill") == 0)
1513         {
1514           if (info)
1515             (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1516           break;
1517         }
1518       if (LocaleCompare(attribute,"font") == 0)
1519         {
1520           if (info)
1521             (void) CloneString(&info->image_info->font,SvPV(sval,na));
1522           break;
1523         }
1524       if (LocaleCompare(attribute,"foreground") == 0)
1525         break;
1526       if (LocaleCompare(attribute,"fuzz") == 0)
1527         {
1528           if (info)
1529             info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1530               QuantumRange+1.0);
1531           for ( ; image; image=image->next)
1532             image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1533               QuantumRange+1.0);
1534           break;
1535         }
1536       if (info)
1537         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1538       for ( ; image; image=image->next)
1539         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1540       break;
1541     }
1542     case 'G':
1543     case 'g':
1544     {
1545       if (LocaleCompare(attribute,"gamma") == 0)
1546         {
1547           for ( ; image; image=image->next)
1548             image->gamma=SvNV(sval);
1549           break;
1550         }
1551       if (LocaleCompare(attribute,"gravity") == 0)
1552         {
1553           sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1554             SvPV(sval,na)) : SvIV(sval);
1555           if (sp < 0)
1556             {
1557               ThrowPerlException(exception,OptionError,
1558                 "UnrecognizedGravityType",SvPV(sval,na));
1559               break;
1560             }
1561           if (info)
1562             SetImageOption(info->image_info,attribute,SvPV(sval,na));
1563           for ( ; image; image=image->next)
1564             image->gravity=(GravityType) sp;
1565           break;
1566         }
1567       if (LocaleCompare(attribute,"green-primary") == 0)
1568         {
1569           for ( ; image; image=image->next)
1570           {
1571             flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1572             image->chromaticity.green_primary.x=geometry_info.rho;
1573             image->chromaticity.green_primary.y=geometry_info.sigma;
1574             if ((flags & SigmaValue) == 0)
1575               image->chromaticity.green_primary.y=
1576                 image->chromaticity.green_primary.x;
1577           }
1578           break;
1579         }
1580       if (info)
1581         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1582       for ( ; image; image=image->next)
1583         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1584       break;
1585     }
1586     case 'I':
1587     case 'i':
1588     {
1589       if (LocaleNCompare(attribute,"index",5) == 0)
1590         {
1591           int
1592             items;
1593 
1594           long
1595             index;
1596 
1597           register Quantum
1598             *q;
1599 
1600           CacheView
1601             *image_view;
1602 
1603           for ( ; image; image=image->next)
1604           {
1605             if (image->storage_class != PseudoClass)
1606               continue;
1607             x=0;
1608             y=0;
1609             items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1610             (void) items;
1611             image_view=AcquireAuthenticCacheView(image,exception);
1612             q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1613             if (q != (Quantum *) NULL)
1614               {
1615                 items=sscanf(SvPV(sval,na),"%ld",&index);
1616                 if ((index >= 0) && (index < (ssize_t) image->colors))
1617                   SetPixelIndex(image,index,q);
1618                 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1619               }
1620             image_view=DestroyCacheView(image_view);
1621           }
1622           break;
1623         }
1624       if (LocaleCompare(attribute,"iterations") == 0)
1625         {
1626   iterations:
1627           for ( ; image; image=image->next)
1628             image->iterations=SvIV(sval);
1629           break;
1630         }
1631       if (LocaleCompare(attribute,"interlace") == 0)
1632         {
1633           sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1634             MagickFalse,SvPV(sval,na)) : SvIV(sval);
1635           if (sp < 0)
1636             {
1637               ThrowPerlException(exception,OptionError,
1638                 "UnrecognizedInterlaceType",SvPV(sval,na));
1639               break;
1640             }
1641           if (info)
1642             info->image_info->interlace=(InterlaceType) sp;
1643           for ( ; image; image=image->next)
1644             image->interlace=(InterlaceType) sp;
1645           break;
1646         }
1647       if (info)
1648         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1649       for ( ; image; image=image->next)
1650         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1651       break;
1652     }
1653     case 'L':
1654     case 'l':
1655     {
1656       if (LocaleCompare(attribute,"label") == 0)
1657         {
1658           for ( ; image; image=image->next)
1659             (void) SetImageProperty(image,"label",InterpretImageProperties(
1660               info ? info->image_info : (ImageInfo *) NULL,image,
1661               SvPV(sval,na),exception),exception);
1662           break;
1663         }
1664       if (LocaleCompare(attribute,"loop") == 0)
1665         goto iterations;
1666       if (info)
1667         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1668       for ( ; image; image=image->next)
1669         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1670       break;
1671     }
1672     case 'M':
1673     case 'm':
1674     {
1675       if (LocaleCompare(attribute,"magick") == 0)
1676         {
1677           if (info)
1678             (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
1679               "%s:",SvPV(sval,na));
1680           for ( ; image; image=image->next)
1681             (void) CopyMagickString(image->magick,SvPV(sval,na),MagickPathExtent);
1682           break;
1683         }
1684       if (LocaleCompare(attribute,"map-limit") == 0)
1685         {
1686           MagickSizeType
1687             limit;
1688 
1689           limit=MagickResourceInfinity;
1690           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1691             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1692               100.0);
1693           (void) SetMagickResourceLimit(MapResource,limit);
1694           break;
1695         }
1696       if (LocaleCompare(attribute,"mask") == 0)
1697         {
1698           Image
1699             *mask;
1700 
1701           mask=(Image *) NULL;
1702           if (SvPOK(sval))
1703             mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1704           for ( ; image; image=image->next)
1705             SetImageMask(image,ReadPixelMask,mask,exception);
1706           break;
1707         }
1708       if (LocaleCompare(attribute,"mattecolor") == 0)
1709         {
1710           (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1711             exception);
1712           if (info)
1713             info->image_info->alpha_color=target_color;
1714           for ( ; image; image=image->next)
1715             image->alpha_color=target_color;
1716           break;
1717         }
1718       if (LocaleCompare(attribute,"matte") == 0)
1719         {
1720           sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1721             SvPV(sval,na)) : SvIV(sval);
1722           if (sp < 0)
1723             {
1724               ThrowPerlException(exception,OptionError,"UnrecognizedType",
1725                 SvPV(sval,na));
1726               break;
1727             }
1728           for ( ; image; image=image->next)
1729             image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1730           break;
1731         }
1732       if (LocaleCompare(attribute,"memory-limit") == 0)
1733         {
1734           MagickSizeType
1735             limit;
1736 
1737           limit=MagickResourceInfinity;
1738           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1739             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1740               100.0);
1741           (void) SetMagickResourceLimit(MemoryResource,limit);
1742           break;
1743         }
1744       if (LocaleCompare(attribute,"monochrome") == 0)
1745         {
1746           sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1747             SvPV(sval,na)) : SvIV(sval);
1748           if (sp < 0)
1749             {
1750               ThrowPerlException(exception,OptionError,"UnrecognizedType",
1751                 SvPV(sval,na));
1752               break;
1753             }
1754           if (info)
1755             info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1756           for ( ; image; image=image->next)
1757             (void) SetImageType(image,BilevelType,exception);
1758           break;
1759         }
1760       if (info)
1761         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1762       for ( ; image; image=image->next)
1763         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1764       break;
1765     }
1766     case 'O':
1767     case 'o':
1768     {
1769       if (LocaleCompare(attribute,"option") == 0)
1770         {
1771           if (info)
1772             DefineImageOption(info->image_info,SvPV(sval,na));
1773           break;
1774         }
1775       if (LocaleCompare(attribute,"orientation") == 0)
1776         {
1777           sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1778             MagickFalse,SvPV(sval,na)) : SvIV(sval);
1779           if (sp < 0)
1780             {
1781               ThrowPerlException(exception,OptionError,
1782                 "UnrecognizedOrientationType",SvPV(sval,na));
1783               break;
1784             }
1785           if (info)
1786             info->image_info->orientation=(OrientationType) sp;
1787           for ( ; image; image=image->next)
1788             image->orientation=(OrientationType) sp;
1789           break;
1790         }
1791       if (info)
1792         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1793       for ( ; image; image=image->next)
1794         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1795       break;
1796     }
1797     case 'P':
1798     case 'p':
1799     {
1800       if (LocaleCompare(attribute,"page") == 0)
1801         {
1802           char
1803             *geometry;
1804 
1805           geometry=GetPageGeometry(SvPV(sval,na));
1806           if (info)
1807             (void) CloneString(&info->image_info->page,geometry);
1808           for ( ; image; image=image->next)
1809             (void) ParsePageGeometry(image,geometry,&image->page,exception);
1810           geometry=(char *) RelinquishMagickMemory(geometry);
1811           break;
1812         }
1813       if (LocaleNCompare(attribute,"pixel",5) == 0)
1814         {
1815           int
1816             items;
1817 
1818           PixelInfo
1819             pixel;
1820 
1821           register Quantum
1822             *q;
1823 
1824           CacheView
1825             *image_view;
1826 
1827           for ( ; image; image=image->next)
1828           {
1829             if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1830               break;
1831             x=0;
1832             y=0;
1833             items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1834             (void) items;
1835             image_view=AcquireVirtualCacheView(image,exception);
1836             q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1837             if (q != (Quantum *) NULL)
1838               {
1839                 if ((strchr(SvPV(sval,na),',') == 0) ||
1840                     (strchr(SvPV(sval,na),')') != 0))
1841                   QueryColorCompliance(SvPV(sval,na),AllCompliance,
1842                     &pixel,exception);
1843                 else
1844                   {
1845                     GetPixelInfo(image,&pixel);
1846                     flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1847                     pixel.red=geometry_info.rho;
1848                     if ((flags & SigmaValue) != 0)
1849                       pixel.green=geometry_info.sigma;
1850                     if ((flags & XiValue) != 0)
1851                       pixel.blue=geometry_info.xi;
1852                     if ((flags & PsiValue) != 0)
1853                       pixel.alpha=geometry_info.psi;
1854                     if ((flags & ChiValue) != 0)
1855                       pixel.black=geometry_info.chi;
1856                   }
1857                 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1858                 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1859                 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1860                 if (image->colorspace == CMYKColorspace)
1861                   SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1862                 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1863                 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1864               }
1865             image_view=DestroyCacheView(image_view);
1866           }
1867           break;
1868         }
1869       if (LocaleCompare(attribute,"pointsize") == 0)
1870         {
1871           if (info)
1872             {
1873               (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1874               info->image_info->pointsize=geometry_info.rho;
1875             }
1876           break;
1877         }
1878       if (info)
1879         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1880       for ( ; image; image=image->next)
1881         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1882       break;
1883     }
1884     case 'Q':
1885     case 'q':
1886     {
1887       if (LocaleCompare(attribute,"quality") == 0)
1888         {
1889           if (info)
1890             info->image_info->quality=SvIV(sval);
1891           for ( ; image; image=image->next)
1892             image->quality=SvIV(sval);
1893           break;
1894         }
1895       if (info)
1896         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1897       for ( ; image; image=image->next)
1898         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1899       break;
1900     }
1901     case 'R':
1902     case 'r':
1903     {
1904       if (LocaleCompare(attribute,"read-mask") == 0)
1905         {
1906           Image
1907             *mask;
1908 
1909           mask=(Image *) NULL;
1910           if (SvPOK(sval))
1911             mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1912           for ( ; image; image=image->next)
1913             SetImageMask(image,ReadPixelMask,mask,exception);
1914           break;
1915         }
1916       if (LocaleCompare(attribute,"red-primary") == 0)
1917         {
1918           for ( ; image; image=image->next)
1919           {
1920             flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1921             image->chromaticity.red_primary.x=geometry_info.rho;
1922             image->chromaticity.red_primary.y=geometry_info.sigma;
1923             if ((flags & SigmaValue) == 0)
1924               image->chromaticity.red_primary.y=
1925                 image->chromaticity.red_primary.x;
1926           }
1927           break;
1928         }
1929       if (LocaleCompare(attribute,"render") == 0)
1930         {
1931           sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1932             SvPV(sval,na)) : SvIV(sval);
1933           if (sp < 0)
1934             {
1935               ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1936                 SvPV(sval,na));
1937               break;
1938             }
1939          for ( ; image; image=image->next)
1940            image->rendering_intent=(RenderingIntent) sp;
1941          break;
1942        }
1943       if (LocaleCompare(attribute,"repage") == 0)
1944         {
1945           RectangleInfo
1946             geometry;
1947 
1948           for ( ; image; image=image->next)
1949           {
1950             flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
1951             if ((flags & WidthValue) != 0)
1952               {
1953                 if ((flags & HeightValue) == 0)
1954                   geometry.height=geometry.width;
1955                 image->page.width=geometry.width;
1956                 image->page.height=geometry.height;
1957               }
1958             if ((flags & AspectValue) != 0)
1959               {
1960                 if ((flags & XValue) != 0)
1961                   image->page.x+=geometry.x;
1962                 if ((flags & YValue) != 0)
1963                   image->page.y+=geometry.y;
1964               }
1965             else
1966               {
1967                 if ((flags & XValue) != 0)
1968                   {
1969                     image->page.x=geometry.x;
1970                     if (((flags & WidthValue) != 0) && (geometry.x > 0))
1971                       image->page.width=image->columns+geometry.x;
1972                   }
1973                 if ((flags & YValue) != 0)
1974                   {
1975                     image->page.y=geometry.y;
1976                     if (((flags & HeightValue) != 0) && (geometry.y > 0))
1977                       image->page.height=image->rows+geometry.y;
1978                   }
1979               }
1980           }
1981           break;
1982         }
1983       if (info)
1984         SetImageOption(info->image_info,attribute,SvPV(sval,na));
1985       for ( ; image; image=image->next)
1986         SetImageProperty(image,attribute,SvPV(sval,na),exception);
1987       break;
1988     }
1989     case 'S':
1990     case 's':
1991     {
1992       if (LocaleCompare(attribute,"sampling-factor") == 0)
1993         {
1994           if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1995             {
1996               ThrowPerlException(exception,OptionError,"MissingGeometry",
1997                 SvPV(sval,na));
1998               break;
1999             }
2000           if (info)
2001             (void) CloneString(&info->image_info->sampling_factor,
2002               SvPV(sval,na));
2003           break;
2004         }
2005       if (LocaleCompare(attribute,"scene") == 0)
2006         {
2007           for ( ; image; image=image->next)
2008             image->scene=SvIV(sval);
2009           break;
2010         }
2011       if (LocaleCompare(attribute,"server") == 0)
2012         goto display;
2013       if (LocaleCompare(attribute,"size") == 0)
2014         {
2015           if (info)
2016             {
2017               if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2018                 {
2019                   ThrowPerlException(exception,OptionError,"MissingGeometry",
2020                     SvPV(sval,na));
2021                   break;
2022                 }
2023               (void) CloneString(&info->image_info->size,SvPV(sval,na));
2024             }
2025           break;
2026         }
2027       if (LocaleCompare(attribute,"stroke") == 0)
2028         {
2029           if (info)
2030             (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2031           break;
2032         }
2033       if (info)
2034         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2035       for ( ; image; image=image->next)
2036         SetImageProperty(image,attribute,SvPV(sval,na),exception);
2037       break;
2038     }
2039     case 'T':
2040     case 't':
2041     {
2042       if (LocaleCompare(attribute,"texture") == 0)
2043         {
2044           if (info)
2045             (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2046           break;
2047         }
2048       if (LocaleCompare(attribute,"thread-limit") == 0)
2049         {
2050           MagickSizeType
2051             limit;
2052 
2053           limit=MagickResourceInfinity;
2054           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2055             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2056               100.0);
2057           (void) SetMagickResourceLimit(ThreadResource,limit);
2058           break;
2059         }
2060       if (LocaleCompare(attribute,"tile-offset") == 0)
2061         {
2062           char
2063             *geometry;
2064 
2065           geometry=GetPageGeometry(SvPV(sval,na));
2066           if (info)
2067             (void) CloneString(&info->image_info->page,geometry);
2068           for ( ; image; image=image->next)
2069             (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2070               exception);
2071           geometry=(char *) RelinquishMagickMemory(geometry);
2072           break;
2073         }
2074       if (LocaleCompare(attribute,"time-limit") == 0)
2075         {
2076           MagickSizeType
2077             limit;
2078 
2079           limit=MagickResourceInfinity;
2080           if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2081             limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2082               100.0);
2083           (void) SetMagickResourceLimit(TimeResource,limit);
2084           break;
2085         }
2086       if (LocaleCompare(attribute,"transparent-color") == 0)
2087         {
2088           (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2089             exception);
2090           if (info)
2091             info->image_info->transparent_color=target_color;
2092           for ( ; image; image=image->next)
2093             image->transparent_color=target_color;
2094           break;
2095         }
2096       if (LocaleCompare(attribute,"type") == 0)
2097         {
2098           sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2099             SvPV(sval,na)) : SvIV(sval);
2100           if (sp < 0)
2101             {
2102               ThrowPerlException(exception,OptionError,"UnrecognizedType",
2103                 SvPV(sval,na));
2104               break;
2105             }
2106           if (info)
2107             info->image_info->type=(ImageType) sp;
2108           for ( ; image; image=image->next)
2109             SetImageType(image,(ImageType) sp,exception);
2110           break;
2111         }
2112       if (info)
2113         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2114       for ( ; image; image=image->next)
2115         SetImageProperty(image,attribute,SvPV(sval,na),exception);
2116       break;
2117     }
2118     case 'U':
2119     case 'u':
2120     {
2121       if (LocaleCompare(attribute,"units") == 0)
2122         {
2123           sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2124             MagickFalse,SvPV(sval,na)) : SvIV(sval);
2125           if (sp < 0)
2126             {
2127               ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2128                 SvPV(sval,na));
2129               break;
2130             }
2131           if (info)
2132             info->image_info->units=(ResolutionType) sp;
2133           for ( ; image; image=image->next)
2134           {
2135             ResolutionType
2136               units;
2137 
2138             units=(ResolutionType) sp;
2139             if (image->units != units)
2140               switch (image->units)
2141               {
2142                 case UndefinedResolution:
2143                 case PixelsPerInchResolution:
2144                 {
2145                   if (units == PixelsPerCentimeterResolution)
2146                     {
2147                       image->resolution.x*=2.54;
2148                       image->resolution.y*=2.54;
2149                     }
2150                   break;
2151                 }
2152                 case PixelsPerCentimeterResolution:
2153                 {
2154                   if (units == PixelsPerInchResolution)
2155                     {
2156                       image->resolution.x/=2.54;
2157                       image->resolution.y/=2.54;
2158                     }
2159                   break;
2160                 }
2161               }
2162             image->units=units;
2163           }
2164           break;
2165         }
2166       if (info)
2167         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2168       for ( ; image; image=image->next)
2169         SetImageProperty(image,attribute,SvPV(sval,na),exception);
2170       break;
2171     }
2172     case 'V':
2173     case 'v':
2174     {
2175       if (LocaleCompare(attribute,"verbose") == 0)
2176         {
2177           sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2178             SvPV(sval,na)) : SvIV(sval);
2179           if (sp < 0)
2180             {
2181               ThrowPerlException(exception,OptionError,"UnrecognizedType",
2182                 SvPV(sval,na));
2183               break;
2184             }
2185           if (info)
2186             info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2187           break;
2188         }
2189       if (LocaleCompare(attribute,"virtual-pixel") == 0)
2190         {
2191           sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2192             MagickFalse,SvPV(sval,na)) : SvIV(sval);
2193           if (sp < 0)
2194             {
2195               ThrowPerlException(exception,OptionError,
2196                 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2197               break;
2198             }
2199           for ( ; image; image=image->next)
2200             SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2201           break;
2202         }
2203       if (info)
2204         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2205       for ( ; image; image=image->next)
2206         SetImageProperty(image,attribute,SvPV(sval,na),exception);
2207       break;
2208     }
2209     case 'W':
2210     case 'w':
2211     {
2212       if (LocaleCompare(attribute,"white-point") == 0)
2213         {
2214           for ( ; image; image=image->next)
2215           {
2216             flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2217             image->chromaticity.white_point.x=geometry_info.rho;
2218             image->chromaticity.white_point.y=geometry_info.sigma;
2219             if ((flags & SigmaValue) == 0)
2220               image->chromaticity.white_point.y=
2221                 image->chromaticity.white_point.x;
2222           }
2223           break;
2224         }
2225       if (LocaleCompare(attribute,"write-mask") == 0)
2226         {
2227           Image
2228             *mask;
2229 
2230           mask=(Image *) NULL;
2231           if (SvPOK(sval))
2232             mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
2233           for ( ; image; image=image->next)
2234             SetImageMask(image,WritePixelMask,mask,exception);
2235           break;
2236         }
2237       if (info)
2238         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2239       for ( ; image; image=image->next)
2240         SetImageProperty(image,attribute,SvPV(sval,na),exception);
2241       break;
2242     }
2243     default:
2244     {
2245       if (info)
2246         SetImageOption(info->image_info,attribute,SvPV(sval,na));
2247       for ( ; image; image=image->next)
2248         SetImageProperty(image,attribute,SvPV(sval,na),exception);
2249       break;
2250     }
2251   }
2252 }
2253 
2254 /*
2255 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2256 %                                                                             %
2257 %                                                                             %
2258 %                                                                             %
2259 %   S e t u p L i s t                                                         %
2260 %                                                                             %
2261 %                                                                             %
2262 %                                                                             %
2263 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2264 %
2265 %  Method SetupList returns the list of all the images linked by their
2266 %  image->next and image->previous link lists for use with ImageMagick.  If
2267 %  info is non-NULL, an info structure is returned in *info.  If
2268 %  reference_vector is non-NULL,an array of SV* are returned in
2269 %  *reference_vector.  Reference_vector is used when the images are going to be
2270 %  replaced with new Image*'s.
2271 %
2272 %  The format of the SetupList routine is:
2273 %
2274 %      Image *SetupList(SV *reference,struct PackageInfo **info,
2275 %        SV ***reference_vector,ExceptionInfo *exception)
2276 %
2277 %  A description of each parameter follows:
2278 %
2279 %    o list: a list of strings.
2280 %
2281 %    o string: a character string.
2282 %
2283 %    o exception: Return any errors or warnings in this structure.
2284 %
2285 */
SetupList(pTHX_ SV * reference,struct PackageInfo ** info,SV *** reference_vector,ExceptionInfo * exception)2286 static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2287   SV ***reference_vector,ExceptionInfo *exception)
2288 {
2289   Image
2290     *image;
2291 
2292   ssize_t
2293     current,
2294     last;
2295 
2296   if (reference_vector)
2297     *reference_vector=NULL;
2298   if (info)
2299     *info=NULL;
2300   current=0;
2301   last=0;
2302   image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2303   if (info && (SvTYPE(reference) == SVt_PVAV))
2304     *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2305       exception);
2306   return(image);
2307 }
2308 
2309 /*
2310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2311 %                                                                             %
2312 %                                                                             %
2313 %                                                                             %
2314 %   s t r E Q c a s e                                                         %
2315 %                                                                             %
2316 %                                                                             %
2317 %                                                                             %
2318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2319 %
2320 %  strEQcase() compares two strings and returns 0 if they are the
2321 %  same or if the second string runs out first.  The comparison is case
2322 %  insensitive.
2323 %
2324 %  The format of the strEQcase routine is:
2325 %
2326 %      ssize_t strEQcase(const char *p,const char *q)
2327 %
2328 %  A description of each parameter follows:
2329 %
2330 %    o p: a character string.
2331 %
2332 %    o q: a character string.
2333 %
2334 %
2335 */
strEQcase(const char * p,const char * q)2336 static ssize_t strEQcase(const char *p,const char *q)
2337 {
2338   char
2339     c;
2340 
2341   register ssize_t
2342     i;
2343 
2344   for (i=0 ; (c=(*q)) != 0; i++)
2345   {
2346     if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2347         (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2348       return(0);
2349     p++;
2350     q++;
2351   }
2352   return(((*q == 0) && (*p == 0)) ? i : 0);
2353 }
2354 
2355 /*
2356 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2357 %                                                                             %
2358 %                                                                             %
2359 %                                                                             %
2360 %   I m a g e : : M a g i c k                                                 %
2361 %                                                                             %
2362 %                                                                             %
2363 %                                                                             %
2364 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2365 %
2366 %
2367 */
2368 MODULE = Image::Magick PACKAGE = Image::Magick
2369 
2370 PROTOTYPES: ENABLE
2371 
2372 BOOT:
2373   MagickCoreGenesis("PerlMagick",MagickFalse);
2374   SetWarningHandler(NULL);
2375   SetErrorHandler(NULL);
2376   magick_registry=NewSplayTree((int (*)(const void *,const void *))
2377     NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2378 
2379 void
UNLOAD()2380 UNLOAD()
2381   PPCODE:
2382   {
2383     if (magick_registry != (SplayTreeInfo *) NULL)
2384       magick_registry=DestroySplayTree(magick_registry);
2385     MagickCoreTerminus();
2386   }
2387 
2388 double
constant(name,argument)2389 constant(name,argument)
2390   char *name
2391   ssize_t argument
2392 
2393 #
2394 ###############################################################################
2395 #                                                                             #
2396 #                                                                             #
2397 #                                                                             #
2398 #   A n i m a t e                                                             #
2399 #                                                                             #
2400 #                                                                             #
2401 #                                                                             #
2402 ###############################################################################
2403 #
2404 #
2405 void
2406 Animate(ref,...)
2407   Image::Magick ref=NO_INIT
2408   ALIAS:
2409     AnimateImage  = 1
2410     animate       = 2
2411     animateimage  = 3
2412   PPCODE:
2413   {
2414     ExceptionInfo
2415       *exception;
2416 
2417     Image
2418       *image;
2419 
2420     register ssize_t
2421       i;
2422 
2423     struct PackageInfo
2424       *info,
2425       *package_info;
2426 
2427     SV
2428       *perl_exception,
2429       *reference;
2430 
2431     PERL_UNUSED_VAR(ref);
2432     PERL_UNUSED_VAR(ix);
2433     exception=AcquireExceptionInfo();
2434     perl_exception=newSVpv("",0);
2435     package_info=(struct PackageInfo *) NULL;
2436     if (sv_isobject(ST(0)) == 0)
2437       {
2438         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2439           PackageName);
2440         goto PerlException;
2441       }
2442     reference=SvRV(ST(0));
2443     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2444     if (image == (Image *) NULL)
2445       {
2446         ThrowPerlException(exception,OptionError,"NoImagesDefined",
2447           PackageName);
2448         goto PerlException;
2449       }
2450     package_info=ClonePackageInfo(info,exception);
2451     if (items == 2)
2452       SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2453     else
2454       if (items > 2)
2455         for (i=2; i < items; i+=2)
2456           SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2457             exception);
2458     (void) AnimateImages(package_info->image_info,image,exception);
2459     (void) CatchImageException(image);
2460 
2461   PerlException:
2462     if (package_info != (struct PackageInfo *) NULL)
2463       DestroyPackageInfo(package_info);
2464     InheritPerlException(exception,perl_exception);
2465     exception=DestroyExceptionInfo(exception);
2466     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2467     SvPOK_on(perl_exception);
2468     ST(0)=sv_2mortal(perl_exception);
2469     XSRETURN(1);
2470   }
2471 
2472 #
2473 ###############################################################################
2474 #                                                                             #
2475 #                                                                             #
2476 #                                                                             #
2477 #   A p p e n d                                                               #
2478 #                                                                             #
2479 #                                                                             #
2480 #                                                                             #
2481 ###############################################################################
2482 #
2483 #
2484 void
Append(ref,...)2485 Append(ref,...)
2486   Image::Magick ref=NO_INIT
2487   ALIAS:
2488     AppendImage  = 1
2489     append       = 2
2490     appendimage  = 3
2491   PPCODE:
2492   {
2493     AV
2494       *av;
2495 
2496     char
2497       *attribute;
2498 
2499     ExceptionInfo
2500       *exception;
2501 
2502     HV
2503       *hv;
2504 
2505     Image
2506       *image;
2507 
2508     register ssize_t
2509       i;
2510 
2511     ssize_t
2512       stack;
2513 
2514     struct PackageInfo
2515       *info;
2516 
2517     SV
2518       *av_reference,
2519       *perl_exception,
2520       *reference,
2521       *rv,
2522       *sv;
2523 
2524     PERL_UNUSED_VAR(ref);
2525     PERL_UNUSED_VAR(ix);
2526     exception=AcquireExceptionInfo();
2527     perl_exception=newSVpv("",0);
2528     sv=NULL;
2529     attribute=NULL;
2530     av=NULL;
2531     if (sv_isobject(ST(0)) == 0)
2532       {
2533         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2534           PackageName);
2535         goto PerlException;
2536       }
2537     reference=SvRV(ST(0));
2538     hv=SvSTASH(reference);
2539     av=newAV();
2540     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2541     SvREFCNT_dec(av);
2542     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2543     if (image == (Image *) NULL)
2544       {
2545         ThrowPerlException(exception,OptionError,"NoImagesDefined",
2546           PackageName);
2547         goto PerlException;
2548       }
2549     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2550     /*
2551       Get options.
2552     */
2553     stack=MagickTrue;
2554     for (i=2; i < items; i+=2)
2555     {
2556       attribute=(char *) SvPV(ST(i-1),na);
2557       switch (*attribute)
2558       {
2559         case 'S':
2560         case 's':
2561         {
2562           if (LocaleCompare(attribute,"stack") == 0)
2563             {
2564               stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2565                 SvPV(ST(i),na));
2566               if (stack < 0)
2567                 {
2568                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
2569                     SvPV(ST(i),na));
2570                   return;
2571                 }
2572               break;
2573             }
2574           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2575             attribute);
2576           break;
2577         }
2578         default:
2579         {
2580           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2581             attribute);
2582           break;
2583         }
2584       }
2585     }
2586     image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2587     if (image == (Image *) NULL)
2588       goto PerlException;
2589     for ( ; image; image=image->next)
2590     {
2591       AddImageToRegistry(sv,image);
2592       rv=newRV(sv);
2593       av_push(av,sv_bless(rv,hv));
2594       SvREFCNT_dec(sv);
2595     }
2596     exception=DestroyExceptionInfo(exception);
2597     ST(0)=av_reference;
2598     SvREFCNT_dec(perl_exception);
2599     XSRETURN(1);
2600 
2601   PerlException:
2602     InheritPerlException(exception,perl_exception);
2603     exception=DestroyExceptionInfo(exception);
2604     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2605     SvPOK_on(perl_exception);
2606     ST(0)=sv_2mortal(perl_exception);
2607     XSRETURN(1);
2608   }
2609 
2610 #
2611 ###############################################################################
2612 #                                                                             #
2613 #                                                                             #
2614 #                                                                             #
2615 #   A v e r a g e                                                             #
2616 #                                                                             #
2617 #                                                                             #
2618 #                                                                             #
2619 ###############################################################################
2620 #
2621 #
2622 void
Average(ref)2623 Average(ref)
2624   Image::Magick ref=NO_INIT
2625   ALIAS:
2626     AverageImage   = 1
2627     average        = 2
2628     averageimage   = 3
2629   PPCODE:
2630   {
2631     AV
2632       *av;
2633 
2634     char
2635       *p;
2636 
2637     ExceptionInfo
2638       *exception;
2639 
2640     HV
2641       *hv;
2642 
2643     Image
2644       *image;
2645 
2646     struct PackageInfo
2647       *info;
2648 
2649     SV
2650       *perl_exception,
2651       *reference,
2652       *rv,
2653       *sv;
2654 
2655     PERL_UNUSED_VAR(ref);
2656     PERL_UNUSED_VAR(ix);
2657     exception=AcquireExceptionInfo();
2658     perl_exception=newSVpv("",0);
2659     sv=NULL;
2660     if (sv_isobject(ST(0)) == 0)
2661       {
2662         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2663           PackageName);
2664         goto PerlException;
2665       }
2666     reference=SvRV(ST(0));
2667     hv=SvSTASH(reference);
2668     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2669     if (image == (Image *) NULL)
2670       {
2671         ThrowPerlException(exception,OptionError,"NoImagesDefined",
2672           PackageName);
2673         goto PerlException;
2674       }
2675     image=EvaluateImages(image,MeanEvaluateOperator,exception);
2676     if (image == (Image *) NULL)
2677       goto PerlException;
2678     /*
2679       Create blessed Perl array for the returned image.
2680     */
2681     av=newAV();
2682     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2683     SvREFCNT_dec(av);
2684     AddImageToRegistry(sv,image);
2685     rv=newRV(sv);
2686     av_push(av,sv_bless(rv,hv));
2687     SvREFCNT_dec(sv);
2688     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2689     (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
2690       "average-%.*s",(int) (MagickPathExtent-9),
2691       ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2692     (void) CopyMagickString(image->filename,info->image_info->filename,
2693       MagickPathExtent);
2694     SetImageInfo(info->image_info,0,exception);
2695     exception=DestroyExceptionInfo(exception);
2696     SvREFCNT_dec(perl_exception);
2697     XSRETURN(1);
2698 
2699   PerlException:
2700     InheritPerlException(exception,perl_exception);
2701     exception=DestroyExceptionInfo(exception);
2702     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2703     SvPOK_on(perl_exception);
2704     ST(0)=sv_2mortal(perl_exception);
2705     XSRETURN(1);
2706   }
2707 
2708 #
2709 ###############################################################################
2710 #                                                                             #
2711 #                                                                             #
2712 #                                                                             #
2713 #   B l o b T o I m a g e                                                     #
2714 #                                                                             #
2715 #                                                                             #
2716 #                                                                             #
2717 ###############################################################################
2718 #
2719 #
2720 void
BlobToImage(ref,...)2721 BlobToImage(ref,...)
2722   Image::Magick ref=NO_INIT
2723   ALIAS:
2724     BlobToImage  = 1
2725     blobtoimage  = 2
2726     blobto       = 3
2727   PPCODE:
2728   {
2729     AV
2730       *av;
2731 
2732     char
2733       **keep,
2734       **list;
2735 
2736     ExceptionInfo
2737       *exception;
2738 
2739     HV
2740       *hv;
2741 
2742     Image
2743       *image;
2744 
2745     register char
2746       **p;
2747 
2748     register ssize_t
2749       i;
2750 
2751     ssize_t
2752       ac,
2753       n,
2754       number_images;
2755 
2756     STRLEN
2757       *length;
2758 
2759     struct PackageInfo
2760       *info;
2761 
2762     SV
2763       *perl_exception,
2764       *reference,
2765       *rv,
2766       *sv;
2767 
2768     PERL_UNUSED_VAR(ref);
2769     PERL_UNUSED_VAR(ix);
2770     exception=AcquireExceptionInfo();
2771     perl_exception=newSVpv("",0);
2772     sv=NULL;
2773     number_images=0;
2774     ac=(items < 2) ? 1 : items-1;
2775     length=(STRLEN *) NULL;
2776     list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2777     if (list == (char **) NULL)
2778       {
2779         ThrowPerlException(exception,ResourceLimitError,
2780           "MemoryAllocationFailed",PackageName);
2781         goto PerlException;
2782       }
2783     length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2784     if (length == (STRLEN *) NULL)
2785       {
2786         ThrowPerlException(exception,ResourceLimitError,
2787           "MemoryAllocationFailed",PackageName);
2788         goto PerlException;
2789       }
2790     if (sv_isobject(ST(0)) == 0)
2791       {
2792         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2793           PackageName);
2794         goto PerlException;
2795       }
2796     reference=SvRV(ST(0));
2797     hv=SvSTASH(reference);
2798     if (SvTYPE(reference) != SVt_PVAV)
2799       {
2800         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2801           PackageName);
2802         goto PerlException;
2803       }
2804     av=(AV *) reference;
2805     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2806       exception);
2807     n=1;
2808     if (items <= 1)
2809       {
2810         ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2811         goto PerlException;
2812       }
2813     for (n=0, i=0; i < ac; i++)
2814     {
2815       list[n]=(char *) (SvPV(ST(i+1),length[n]));
2816       if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2817         {
2818           list[n]=(char *) (SvPV(ST(i+2),length[n]));
2819           continue;
2820         }
2821       n++;
2822     }
2823     list[n]=(char *) NULL;
2824     keep=list;
2825     for (i=number_images=0; i < n; i++)
2826     {
2827       image=BlobToImage(info->image_info,list[i],length[i],exception);
2828       if (image == (Image *) NULL)
2829         break;
2830       for ( ; image; image=image->next)
2831       {
2832         AddImageToRegistry(sv,image);
2833         rv=newRV(sv);
2834         av_push(av,sv_bless(rv,hv));
2835         SvREFCNT_dec(sv);
2836         number_images++;
2837       }
2838     }
2839     /*
2840       Free resources.
2841     */
2842     for (i=0; i < n; i++)
2843       if (list[i] != (char *) NULL)
2844         for (p=keep; list[i] != *p++; )
2845           if (*p == (char *) NULL)
2846             {
2847               list[i]=(char *) RelinquishMagickMemory(list[i]);
2848               break;
2849             }
2850 
2851   PerlException:
2852     if (list)
2853       list=(char **) RelinquishMagickMemory(list);
2854     if (length)
2855       length=(STRLEN *) RelinquishMagickMemory(length);
2856     InheritPerlException(exception,perl_exception);
2857     exception=DestroyExceptionInfo(exception);
2858     sv_setiv(perl_exception,(IV) number_images);
2859     SvPOK_on(perl_exception);
2860     ST(0)=sv_2mortal(perl_exception);
2861     XSRETURN(1);
2862   }
2863 
2864 #
2865 ###############################################################################
2866 #                                                                             #
2867 #                                                                             #
2868 #                                                                             #
2869 #   C h a n n e l F x                                                         #
2870 #                                                                             #
2871 #                                                                             #
2872 #                                                                             #
2873 ###############################################################################
2874 #
2875 #
2876 void
ChannelFx(ref,...)2877 ChannelFx(ref,...)
2878   Image::Magick ref=NO_INIT
2879   ALIAS:
2880     ChannelFxImage  = 1
2881     channelfx       = 2
2882     channelfximage  = 3
2883   PPCODE:
2884   {
2885     AV
2886       *av;
2887 
2888     char
2889       *attribute,
2890       expression[MagickPathExtent];
2891 
2892     ChannelType
2893       channel,
2894       channel_mask;
2895 
2896     ExceptionInfo
2897       *exception;
2898 
2899     HV
2900       *hv;
2901 
2902     Image
2903       *image;
2904 
2905     register ssize_t
2906       i;
2907 
2908     struct PackageInfo
2909       *info;
2910 
2911     SV
2912       *av_reference,
2913       *perl_exception,
2914       *reference,
2915       *rv,
2916       *sv;
2917 
2918     PERL_UNUSED_VAR(ref);
2919     PERL_UNUSED_VAR(ix);
2920     exception=AcquireExceptionInfo();
2921     perl_exception=newSVpv("",0);
2922     sv=NULL;
2923     attribute=NULL;
2924     av=NULL;
2925     if (sv_isobject(ST(0)) == 0)
2926       {
2927         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2928           PackageName);
2929         goto PerlException;
2930       }
2931     reference=SvRV(ST(0));
2932     hv=SvSTASH(reference);
2933     av=newAV();
2934     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2935     SvREFCNT_dec(av);
2936     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2937     if (image == (Image *) NULL)
2938       {
2939         ThrowPerlException(exception,OptionError,"NoImagesDefined",
2940           PackageName);
2941         goto PerlException;
2942       }
2943     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2944     /*
2945       Get options.
2946     */
2947     channel=DefaultChannels;
2948     (void) CopyMagickString(expression,"u",MagickPathExtent);
2949     if (items == 2)
2950       (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
2951     else
2952       for (i=2; i < items; i+=2)
2953       {
2954         attribute=(char *) SvPV(ST(i-1),na);
2955         switch (*attribute)
2956         {
2957           case 'C':
2958           case 'c':
2959           {
2960             if (LocaleCompare(attribute,"channel") == 0)
2961               {
2962                 ssize_t
2963                   option;
2964 
2965                 option=ParseChannelOption(SvPV(ST(i),na));
2966                 if (option < 0)
2967                   {
2968                     ThrowPerlException(exception,OptionError,
2969                       "UnrecognizedType",SvPV(ST(i),na));
2970                     return;
2971                   }
2972                 channel=(ChannelType) option;
2973                 break;
2974               }
2975             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2976               attribute);
2977             break;
2978           }
2979           case 'E':
2980           case 'e':
2981           {
2982             if (LocaleCompare(attribute,"expression") == 0)
2983               {
2984                 (void) CopyMagickString(expression,SvPV(ST(i),na),
2985                   MagickPathExtent);
2986                 break;
2987               }
2988             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2989               attribute);
2990             break;
2991           }
2992           default:
2993           {
2994             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2995               attribute);
2996             break;
2997           }
2998         }
2999       }
3000     channel_mask=SetImageChannelMask(image,channel);
3001     image=ChannelFxImage(image,expression,exception);
3002     if (image != (Image *) NULL)
3003       (void) SetImageChannelMask(image,channel_mask);
3004     if (image == (Image *) NULL)
3005       goto PerlException;
3006     for ( ; image; image=image->next)
3007     {
3008       AddImageToRegistry(sv,image);
3009       rv=newRV(sv);
3010       av_push(av,sv_bless(rv,hv));
3011       SvREFCNT_dec(sv);
3012     }
3013     exception=DestroyExceptionInfo(exception);
3014     ST(0)=av_reference;
3015     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
3016     XSRETURN(1);
3017 
3018   PerlException:
3019     InheritPerlException(exception,perl_exception);
3020     exception=DestroyExceptionInfo(exception);
3021     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3022     SvPOK_on(perl_exception);
3023     ST(0)=sv_2mortal(perl_exception);
3024     XSRETURN(1);
3025   }
3026 
3027 #
3028 ###############################################################################
3029 #                                                                             #
3030 #                                                                             #
3031 #                                                                             #
3032 #   C l o n e                                                                 #
3033 #                                                                             #
3034 #                                                                             #
3035 #                                                                             #
3036 ###############################################################################
3037 #
3038 #
3039 void
Clone(ref)3040 Clone(ref)
3041   Image::Magick ref=NO_INIT
3042   ALIAS:
3043     CopyImage   = 1
3044     copy        = 2
3045     copyimage   = 3
3046     CloneImage  = 4
3047     clone       = 5
3048     cloneimage  = 6
3049     Clone       = 7
3050   PPCODE:
3051   {
3052     AV
3053       *av;
3054 
3055     ExceptionInfo
3056       *exception;
3057 
3058     HV
3059       *hv;
3060 
3061     Image
3062       *clone,
3063       *image;
3064 
3065     struct PackageInfo
3066       *info;
3067 
3068     SV
3069       *perl_exception,
3070       *reference,
3071       *rv,
3072       *sv;
3073 
3074     PERL_UNUSED_VAR(ref);
3075     PERL_UNUSED_VAR(ix);
3076     exception=AcquireExceptionInfo();
3077     perl_exception=newSVpv("",0);
3078     sv=NULL;
3079     if (sv_isobject(ST(0)) == 0)
3080       {
3081         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3082           PackageName);
3083         goto PerlException;
3084       }
3085     reference=SvRV(ST(0));
3086     hv=SvSTASH(reference);
3087     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3088     if (image == (Image *) NULL)
3089       {
3090         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3091           PackageName);
3092         goto PerlException;
3093       }
3094     /*
3095       Create blessed Perl array for the returned image.
3096     */
3097     av=newAV();
3098     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3099     SvREFCNT_dec(av);
3100     for ( ; image; image=image->next)
3101     {
3102       clone=CloneImage(image,0,0,MagickTrue,exception);
3103       if (clone == (Image *) NULL)
3104         break;
3105       AddImageToRegistry(sv,clone);
3106       rv=newRV(sv);
3107       av_push(av,sv_bless(rv,hv));
3108       SvREFCNT_dec(sv);
3109     }
3110     exception=DestroyExceptionInfo(exception);
3111     SvREFCNT_dec(perl_exception);
3112     XSRETURN(1);
3113 
3114   PerlException:
3115     InheritPerlException(exception,perl_exception);
3116     exception=DestroyExceptionInfo(exception);
3117     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3118     SvPOK_on(perl_exception);
3119     ST(0)=sv_2mortal(perl_exception);
3120     XSRETURN(1);
3121   }
3122 
3123 #
3124 ###############################################################################
3125 #                                                                             #
3126 #                                                                             #
3127 #                                                                             #
3128 #   C L O N E                                                                 #
3129 #                                                                             #
3130 #                                                                             #
3131 #                                                                             #
3132 ###############################################################################
3133 #
3134 #
3135 void
CLONE(ref,...)3136 CLONE(ref,...)
3137   SV *ref;
3138   CODE:
3139   {
3140     PERL_UNUSED_VAR(ref);
3141     if (magick_registry != (SplayTreeInfo *) NULL)
3142       {
3143         register Image
3144           *p;
3145 
3146         ResetSplayTreeIterator(magick_registry);
3147         p=(Image *) GetNextKeyInSplayTree(magick_registry);
3148         while (p != (Image *) NULL)
3149         {
3150           ReferenceImage(p);
3151           p=(Image *) GetNextKeyInSplayTree(magick_registry);
3152         }
3153       }
3154   }
3155 
3156 #
3157 ###############################################################################
3158 #                                                                             #
3159 #                                                                             #
3160 #                                                                             #
3161 #   C o a l e s c e                                                           #
3162 #                                                                             #
3163 #                                                                             #
3164 #                                                                             #
3165 ###############################################################################
3166 #
3167 #
3168 void
Coalesce(ref)3169 Coalesce(ref)
3170   Image::Magick ref=NO_INIT
3171   ALIAS:
3172     CoalesceImage   = 1
3173     coalesce        = 2
3174     coalesceimage   = 3
3175   PPCODE:
3176   {
3177     AV
3178       *av;
3179 
3180     ExceptionInfo
3181       *exception;
3182 
3183     HV
3184       *hv;
3185 
3186     Image
3187       *image;
3188 
3189     struct PackageInfo
3190       *info;
3191 
3192     SV
3193       *av_reference,
3194       *perl_exception,
3195       *reference,
3196       *rv,
3197       *sv;
3198 
3199     PERL_UNUSED_VAR(ref);
3200     PERL_UNUSED_VAR(ix);
3201     exception=AcquireExceptionInfo();
3202     perl_exception=newSVpv("",0);
3203     sv=NULL;
3204     if (sv_isobject(ST(0)) == 0)
3205       {
3206         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3207           PackageName);
3208         goto PerlException;
3209       }
3210     reference=SvRV(ST(0));
3211     hv=SvSTASH(reference);
3212     av=newAV();
3213     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3214     SvREFCNT_dec(av);
3215     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3216     if (image == (Image *) NULL)
3217       {
3218         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3219           PackageName);
3220         goto PerlException;
3221       }
3222     image=CoalesceImages(image,exception);
3223     if (image == (Image *) NULL)
3224       goto PerlException;
3225     for ( ; image; image=image->next)
3226     {
3227       AddImageToRegistry(sv,image);
3228       rv=newRV(sv);
3229       av_push(av,sv_bless(rv,hv));
3230       SvREFCNT_dec(sv);
3231     }
3232     exception=DestroyExceptionInfo(exception);
3233     ST(0)=av_reference;
3234     SvREFCNT_dec(perl_exception);
3235     XSRETURN(1);
3236 
3237   PerlException:
3238     InheritPerlException(exception,perl_exception);
3239     exception=DestroyExceptionInfo(exception);
3240     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3241     SvPOK_on(perl_exception);
3242     ST(0)=sv_2mortal(perl_exception);
3243     XSRETURN(1);
3244   }
3245 
3246 #
3247 ###############################################################################
3248 #                                                                             #
3249 #                                                                             #
3250 #                                                                             #
3251 #   C o m p a r e                                                             #
3252 #                                                                             #
3253 #                                                                             #
3254 #                                                                             #
3255 ###############################################################################
3256 #
3257 #
3258 void
Compare(ref,...)3259 Compare(ref,...)
3260   Image::Magick ref=NO_INIT
3261   ALIAS:
3262     CompareImages = 1
3263     compare      = 2
3264     compareimage = 3
3265   PPCODE:
3266   {
3267     AV
3268       *av;
3269 
3270     char
3271       *attribute;
3272 
3273     double
3274       distortion;
3275 
3276     ExceptionInfo
3277       *exception;
3278 
3279     HV
3280       *hv;
3281 
3282     Image
3283       *difference_image,
3284       *image,
3285       *reconstruct_image;
3286 
3287     MetricType
3288       metric;
3289 
3290     register ssize_t
3291       i;
3292 
3293     ssize_t
3294       option;
3295 
3296     struct PackageInfo
3297       *info;
3298 
3299     SV
3300       *av_reference,
3301       *perl_exception,
3302       *reference,
3303       *rv,
3304       *sv;
3305 
3306     PERL_UNUSED_VAR(ref);
3307     PERL_UNUSED_VAR(ix);
3308     exception=AcquireExceptionInfo();
3309     perl_exception=newSVpv("",0);
3310     sv=NULL;
3311     av=NULL;
3312     attribute=NULL;
3313     if (sv_isobject(ST(0)) == 0)
3314       {
3315         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3316           PackageName);
3317         goto PerlException;
3318       }
3319     reference=SvRV(ST(0));
3320     hv=SvSTASH(reference);
3321     av=newAV();
3322     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3323     SvREFCNT_dec(av);
3324     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3325     if (image == (Image *) NULL)
3326       {
3327         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3328           PackageName);
3329         goto PerlException;
3330       }
3331     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3332     /*
3333       Get attribute.
3334     */
3335     reconstruct_image=image;
3336     metric=RootMeanSquaredErrorMetric;
3337     for (i=2; i < items; i+=2)
3338     {
3339       attribute=(char *) SvPV(ST(i-1),na);
3340       switch (*attribute)
3341       {
3342         case 'C':
3343         case 'c':
3344         {
3345           if (LocaleCompare(attribute,"channel") == 0)
3346             {
3347               ssize_t
3348                 option;
3349 
3350               option=ParseChannelOption(SvPV(ST(i),na));
3351               if (option < 0)
3352                 {
3353                   ThrowPerlException(exception,OptionError,
3354                     "UnrecognizedType",SvPV(ST(i),na));
3355                   return;
3356                 }
3357               (void) SetPixelChannelMask(image,(ChannelType) option);
3358               break;
3359             }
3360           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3361             attribute);
3362           break;
3363         }
3364         case 'F':
3365         case 'f':
3366         {
3367           if (LocaleCompare(attribute,"fuzz") == 0)
3368             {
3369               image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3370               break;
3371             }
3372           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3373             attribute);
3374           break;
3375         }
3376         case 'I':
3377         case 'i':
3378         {
3379           if (LocaleCompare(attribute,"image") == 0)
3380             {
3381               reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3382                 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3383               break;
3384             }
3385           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3386             attribute);
3387           break;
3388         }
3389         case 'M':
3390         case 'm':
3391         {
3392           if (LocaleCompare(attribute,"metric") == 0)
3393             {
3394               option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3395                 SvPV(ST(i),na));
3396               if (option < 0)
3397                 {
3398                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
3399                     SvPV(ST(i),na));
3400                   break;
3401                 }
3402               metric=(MetricType) option;
3403               break;
3404             }
3405           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3406             attribute);
3407           break;
3408         }
3409         default:
3410         {
3411           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3412             attribute);
3413           break;
3414         }
3415       }
3416     }
3417     difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3418       exception);
3419     if (difference_image != (Image *) NULL)
3420       {
3421         difference_image->error.mean_error_per_pixel=distortion;
3422         AddImageToRegistry(sv,difference_image);
3423         rv=newRV(sv);
3424         av_push(av,sv_bless(rv,hv));
3425         SvREFCNT_dec(sv);
3426       }
3427     exception=DestroyExceptionInfo(exception);
3428     ST(0)=av_reference;
3429     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
3430     XSRETURN(1);
3431 
3432   PerlException:
3433     InheritPerlException(exception,perl_exception);
3434     exception=DestroyExceptionInfo(exception);
3435     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3436     SvPOK_on(perl_exception);
3437     ST(0)=sv_2mortal(perl_exception);
3438     XSRETURN(1);
3439   }
3440 
3441 #
3442 ###############################################################################
3443 #                                                                             #
3444 #                                                                             #
3445 #                                                                             #
3446 #   C o m p l e x I m a g e s                                                 #
3447 #                                                                             #
3448 #                                                                             #
3449 #                                                                             #
3450 ###############################################################################
3451 #
3452 #
3453 void
ComplexImages(ref)3454 ComplexImages(ref)
3455   Image::Magick ref=NO_INIT
3456   ALIAS:
3457     ComplexImages   = 1
3458     compleximages   = 2
3459   PPCODE:
3460   {
3461     AV
3462       *av;
3463 
3464     char
3465       *attribute,
3466       *p;
3467 
3468     ComplexOperator
3469       op;
3470 
3471     ExceptionInfo
3472       *exception;
3473 
3474     HV
3475       *hv;
3476 
3477     Image
3478       *image;
3479 
3480     register ssize_t
3481       i;
3482 
3483     struct PackageInfo
3484       *info;
3485 
3486     SV
3487       *perl_exception,
3488       *reference,
3489       *rv,
3490       *sv;
3491 
3492     PERL_UNUSED_VAR(ref);
3493     PERL_UNUSED_VAR(ix);
3494     exception=AcquireExceptionInfo();
3495     perl_exception=newSVpv("",0);
3496     sv=NULL;
3497     if (sv_isobject(ST(0)) == 0)
3498       {
3499         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3500           PackageName);
3501         goto PerlException;
3502       }
3503     reference=SvRV(ST(0));
3504     hv=SvSTASH(reference);
3505     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3506     if (image == (Image *) NULL)
3507       {
3508         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3509           PackageName);
3510         goto PerlException;
3511       }
3512     op=UndefinedComplexOperator;
3513     if (items == 2)
3514       {
3515         ssize_t
3516           in;
3517 
3518         in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *)
3519           SvPV(ST(1),na));
3520         if (in < 0)
3521           {
3522             ThrowPerlException(exception,OptionError,"UnrecognizedType",
3523               SvPV(ST(1),na));
3524             return;
3525           }
3526         op=(ComplexOperator) in;
3527       }
3528     else
3529       for (i=2; i < items; i+=2)
3530       {
3531         attribute=(char *) SvPV(ST(i-1),na);
3532         switch (*attribute)
3533         {
3534           case 'O':
3535           case 'o':
3536           {
3537             if (LocaleCompare(attribute,"operator") == 0)
3538               {
3539                 ssize_t
3540                   in;
3541 
3542                 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3543                   MagickComplexOptions,MagickFalse,SvPV(ST(i),na));
3544                 if (in < 0)
3545                   {
3546                     ThrowPerlException(exception,OptionError,"UnrecognizedType",
3547                       SvPV(ST(i),na));
3548                     return;
3549                   }
3550                 op=(ComplexOperator) in;
3551                 break;
3552               }
3553             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3554               attribute);
3555             break;
3556           }
3557           default:
3558           {
3559             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3560               attribute);
3561             break;
3562           }
3563         }
3564       }
3565     image=ComplexImages(image,op,exception);
3566     if (image == (Image *) NULL)
3567       goto PerlException;
3568     /*
3569       Create blessed Perl array for the returned image.
3570     */
3571     av=newAV();
3572     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3573     SvREFCNT_dec(av);
3574     AddImageToRegistry(sv,image);
3575     rv=newRV(sv);
3576     av_push(av,sv_bless(rv,hv));
3577     SvREFCNT_dec(sv);
3578     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3579     (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
3580       "complex-%.*s",(int) (MagickPathExtent-9),
3581       ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3582     (void) CopyMagickString(image->filename,info->image_info->filename,
3583       MagickPathExtent);
3584     SetImageInfo(info->image_info,0,exception);
3585     exception=DestroyExceptionInfo(exception);
3586     SvREFCNT_dec(perl_exception);
3587     XSRETURN(1);
3588 
3589   PerlException:
3590     InheritPerlException(exception,perl_exception);
3591     exception=DestroyExceptionInfo(exception);
3592     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3593     SvPOK_on(perl_exception);
3594     ST(0)=sv_2mortal(perl_exception);
3595     XSRETURN(1);
3596   }
3597 
3598 #
3599 ###############################################################################
3600 #                                                                             #
3601 #                                                                             #
3602 #                                                                             #
3603 #   C o m p a r e L a y e r s                                                 #
3604 #                                                                             #
3605 #                                                                             #
3606 #                                                                             #
3607 ###############################################################################
3608 #
3609 #
3610 void
CompareLayers(ref)3611 CompareLayers(ref)
3612   Image::Magick ref=NO_INIT
3613   ALIAS:
3614     CompareImagesLayers   = 1
3615     comparelayers        = 2
3616     compareimagelayers   = 3
3617   PPCODE:
3618   {
3619     AV
3620       *av;
3621 
3622     char
3623       *attribute;
3624 
3625     ExceptionInfo
3626       *exception;
3627 
3628     HV
3629       *hv;
3630 
3631     Image
3632       *image;
3633 
3634     LayerMethod
3635       method;
3636 
3637     register ssize_t
3638       i;
3639 
3640     ssize_t
3641       option;
3642 
3643     struct PackageInfo
3644       *info;
3645 
3646     SV
3647       *av_reference,
3648       *perl_exception,
3649       *reference,
3650       *rv,
3651       *sv;
3652 
3653     PERL_UNUSED_VAR(ref);
3654     PERL_UNUSED_VAR(ix);
3655     exception=AcquireExceptionInfo();
3656     perl_exception=newSVpv("",0);
3657     sv=NULL;
3658     if (sv_isobject(ST(0)) == 0)
3659       {
3660         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3661           PackageName);
3662         goto PerlException;
3663       }
3664     reference=SvRV(ST(0));
3665     hv=SvSTASH(reference);
3666     av=newAV();
3667     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3668     SvREFCNT_dec(av);
3669     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3670     if (image == (Image *) NULL)
3671       {
3672         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3673           PackageName);
3674         goto PerlException;
3675       }
3676     method=CompareAnyLayer;
3677     for (i=2; i < items; i+=2)
3678     {
3679       attribute=(char *) SvPV(ST(i-1),na);
3680       switch (*attribute)
3681       {
3682         case 'M':
3683         case 'm':
3684         {
3685           if (LocaleCompare(attribute,"method") == 0)
3686             {
3687               option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3688                 SvPV(ST(i),na));
3689               if (option < 0)
3690                 {
3691                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
3692                     SvPV(ST(i),na));
3693                   break;
3694                 }
3695                method=(LayerMethod) option;
3696               break;
3697             }
3698           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3699             attribute);
3700           break;
3701         }
3702         default:
3703         {
3704           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3705             attribute);
3706           break;
3707         }
3708       }
3709     }
3710     image=CompareImagesLayers(image,method,exception);
3711     if (image == (Image *) NULL)
3712       goto PerlException;
3713     for ( ; image; image=image->next)
3714     {
3715       AddImageToRegistry(sv,image);
3716       rv=newRV(sv);
3717       av_push(av,sv_bless(rv,hv));
3718       SvREFCNT_dec(sv);
3719     }
3720     exception=DestroyExceptionInfo(exception);
3721     ST(0)=av_reference;
3722     SvREFCNT_dec(perl_exception);
3723     XSRETURN(1);
3724 
3725   PerlException:
3726     InheritPerlException(exception,perl_exception);
3727     exception=DestroyExceptionInfo(exception);
3728     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3729     SvPOK_on(perl_exception);
3730     ST(0)=sv_2mortal(perl_exception);
3731     XSRETURN(1);
3732   }
3733 
3734 #
3735 ###############################################################################
3736 #                                                                             #
3737 #                                                                             #
3738 #                                                                             #
3739 #   D e s t r o y                                                             #
3740 #                                                                             #
3741 #                                                                             #
3742 #                                                                             #
3743 ###############################################################################
3744 #
3745 #
3746 void
DESTROY(ref)3747 DESTROY(ref)
3748   Image::Magick ref=NO_INIT
3749   PPCODE:
3750   {
3751     SV
3752       *reference;
3753 
3754     PERL_UNUSED_VAR(ref);
3755     if (sv_isobject(ST(0)) == 0)
3756       croak("ReferenceIsNotMyType");
3757     reference=SvRV(ST(0));
3758     switch (SvTYPE(reference))
3759     {
3760       case SVt_PVAV:
3761       {
3762         char
3763           message[MagickPathExtent];
3764 
3765         const SV
3766           *key;
3767 
3768         HV
3769           *hv;
3770 
3771         GV
3772           **gvp;
3773 
3774         struct PackageInfo
3775           *info;
3776 
3777         SV
3778           *sv;
3779 
3780         /*
3781           Array (AV *) reference
3782         */
3783         (void) FormatLocaleString(message,MagickPathExtent,"package%s%p",
3784           XS_VERSION,reference);
3785         hv=gv_stashpv(PackageName, FALSE);
3786         if (!hv)
3787           break;
3788         gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3789         if (!gvp)
3790           break;
3791         sv=GvSV(*gvp);
3792         if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3793           {
3794             info=INT2PTR(struct PackageInfo *,SvIV(sv));
3795             DestroyPackageInfo(info);
3796           }
3797         key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3798         (void) key;
3799         break;
3800       }
3801       case SVt_PVMG:
3802       {
3803         Image
3804           *image;
3805 
3806         /*
3807           Blessed scalar = (Image *) SvIV(reference)
3808         */
3809         image=INT2PTR(Image *,SvIV(reference));
3810         if (image != (Image *) NULL)
3811           DeleteImageFromRegistry(reference,image);
3812         break;
3813       }
3814       default:
3815         break;
3816     }
3817   }
3818 
3819 #
3820 ###############################################################################
3821 #                                                                             #
3822 #                                                                             #
3823 #                                                                             #
3824 #   D i s p l a y                                                             #
3825 #                                                                             #
3826 #                                                                             #
3827 #                                                                             #
3828 ###############################################################################
3829 #
3830 #
3831 void
Display(ref,...)3832 Display(ref,...)
3833   Image::Magick ref=NO_INIT
3834   ALIAS:
3835     DisplayImage  = 1
3836     display       = 2
3837     displayimage  = 3
3838   PPCODE:
3839   {
3840     ExceptionInfo
3841       *exception;
3842 
3843     Image
3844       *image;
3845 
3846     register ssize_t
3847       i;
3848 
3849     struct PackageInfo
3850       *info,
3851       *package_info;
3852 
3853     SV
3854       *perl_exception,
3855       *reference;
3856 
3857     PERL_UNUSED_VAR(ref);
3858     PERL_UNUSED_VAR(ix);
3859     exception=AcquireExceptionInfo();
3860     perl_exception=newSVpv("",0);
3861     package_info=(struct PackageInfo *) NULL;
3862     if (sv_isobject(ST(0)) == 0)
3863       {
3864         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3865           PackageName);
3866         goto PerlException;
3867       }
3868     reference=SvRV(ST(0));
3869     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3870     if (image == (Image *) NULL)
3871       {
3872         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3873           PackageName);
3874         goto PerlException;
3875       }
3876     package_info=ClonePackageInfo(info,exception);
3877     if (items == 2)
3878       SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3879     else
3880       if (items > 2)
3881         for (i=2; i < items; i+=2)
3882           SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3883             exception);
3884     (void) DisplayImages(package_info->image_info,image,exception);
3885     (void) CatchImageException(image);
3886 
3887   PerlException:
3888     if (package_info != (struct PackageInfo *) NULL)
3889       DestroyPackageInfo(package_info);
3890     InheritPerlException(exception,perl_exception);
3891     exception=DestroyExceptionInfo(exception);
3892     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3893     SvPOK_on(perl_exception);
3894     ST(0)=sv_2mortal(perl_exception);
3895     XSRETURN(1);
3896   }
3897 
3898 #
3899 ###############################################################################
3900 #                                                                             #
3901 #                                                                             #
3902 #                                                                             #
3903 #   E v a l u a t e I m a g e s                                               #
3904 #                                                                             #
3905 #                                                                             #
3906 #                                                                             #
3907 ###############################################################################
3908 #
3909 #
3910 void
EvaluateImages(ref)3911 EvaluateImages(ref)
3912   Image::Magick ref=NO_INIT
3913   ALIAS:
3914     EvaluateImages   = 1
3915     evaluateimages   = 2
3916   PPCODE:
3917   {
3918     AV
3919       *av;
3920 
3921     char
3922       *attribute,
3923       *p;
3924 
3925     ExceptionInfo
3926       *exception;
3927 
3928     HV
3929       *hv;
3930 
3931     Image
3932       *image;
3933 
3934     MagickEvaluateOperator
3935       op;
3936 
3937     register ssize_t
3938       i;
3939 
3940     struct PackageInfo
3941       *info;
3942 
3943     SV
3944       *perl_exception,
3945       *reference,
3946       *rv,
3947       *sv;
3948 
3949     PERL_UNUSED_VAR(ref);
3950     PERL_UNUSED_VAR(ix);
3951     exception=AcquireExceptionInfo();
3952     perl_exception=newSVpv("",0);
3953     sv=NULL;
3954     if (sv_isobject(ST(0)) == 0)
3955       {
3956         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3957           PackageName);
3958         goto PerlException;
3959       }
3960     reference=SvRV(ST(0));
3961     hv=SvSTASH(reference);
3962     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3963     if (image == (Image *) NULL)
3964       {
3965         ThrowPerlException(exception,OptionError,"NoImagesDefined",
3966           PackageName);
3967         goto PerlException;
3968       }
3969     op=MeanEvaluateOperator;
3970     if (items == 2)
3971       {
3972         ssize_t
3973           in;
3974 
3975         in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
3976           SvPV(ST(1),na));
3977         if (in < 0)
3978           {
3979             ThrowPerlException(exception,OptionError,"UnrecognizedType",
3980               SvPV(ST(1),na));
3981             return;
3982           }
3983         op=(MagickEvaluateOperator) in;
3984       }
3985     else
3986       for (i=2; i < items; i+=2)
3987       {
3988         attribute=(char *) SvPV(ST(i-1),na);
3989         switch (*attribute)
3990         {
3991           case 'O':
3992           case 'o':
3993           {
3994             if (LocaleCompare(attribute,"operator") == 0)
3995               {
3996                 ssize_t
3997                   in;
3998 
3999                 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
4000                   MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
4001                 if (in < 0)
4002                   {
4003                     ThrowPerlException(exception,OptionError,"UnrecognizedType",
4004                       SvPV(ST(i),na));
4005                     return;
4006                   }
4007                 op=(MagickEvaluateOperator) in;
4008                 break;
4009               }
4010             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4011               attribute);
4012             break;
4013           }
4014           default:
4015           {
4016             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4017               attribute);
4018             break;
4019           }
4020         }
4021       }
4022     image=EvaluateImages(image,op,exception);
4023     if (image == (Image *) NULL)
4024       goto PerlException;
4025     /*
4026       Create blessed Perl array for the returned image.
4027     */
4028     av=newAV();
4029     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4030     SvREFCNT_dec(av);
4031     AddImageToRegistry(sv,image);
4032     rv=newRV(sv);
4033     av_push(av,sv_bless(rv,hv));
4034     SvREFCNT_dec(sv);
4035     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4036     (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4037       "evaluate-%.*s",(int) (MagickPathExtent-9),
4038       ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4039     (void) CopyMagickString(image->filename,info->image_info->filename,
4040       MagickPathExtent);
4041     SetImageInfo(info->image_info,0,exception);
4042     exception=DestroyExceptionInfo(exception);
4043     SvREFCNT_dec(perl_exception);
4044     XSRETURN(1);
4045 
4046   PerlException:
4047     InheritPerlException(exception,perl_exception);
4048     exception=DestroyExceptionInfo(exception);
4049     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4050     SvPOK_on(perl_exception);
4051     ST(0)=sv_2mortal(perl_exception);
4052     XSRETURN(1);
4053   }
4054 
4055 #
4056 ###############################################################################
4057 #                                                                             #
4058 #                                                                             #
4059 #                                                                             #
4060 #   F e a t u r e s                                                           #
4061 #                                                                             #
4062 #                                                                             #
4063 #                                                                             #
4064 ###############################################################################
4065 #
4066 #
4067 void
Features(ref,...)4068 Features(ref,...)
4069   Image::Magick ref=NO_INIT
4070   ALIAS:
4071     FeaturesImage = 1
4072     features      = 2
4073     featuresimage = 3
4074   PPCODE:
4075   {
4076 #define ChannelFeatures(channel,direction) \
4077 { \
4078   (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4079     channel_features[channel].angular_second_moment[direction]); \
4080   PUSHs(sv_2mortal(newSVpv(message,0))); \
4081   (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4082     channel_features[channel].contrast[direction]); \
4083   PUSHs(sv_2mortal(newSVpv(message,0))); \
4084   (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4085     channel_features[channel].contrast[direction]); \
4086   PUSHs(sv_2mortal(newSVpv(message,0))); \
4087   (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4088     channel_features[channel].variance_sum_of_squares[direction]); \
4089   PUSHs(sv_2mortal(newSVpv(message,0))); \
4090   (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4091     channel_features[channel].inverse_difference_moment[direction]); \
4092   PUSHs(sv_2mortal(newSVpv(message,0))); \
4093   (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4094     channel_features[channel].sum_average[direction]); \
4095   PUSHs(sv_2mortal(newSVpv(message,0))); \
4096   (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4097     channel_features[channel].sum_variance[direction]); \
4098   PUSHs(sv_2mortal(newSVpv(message,0))); \
4099   (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4100     channel_features[channel].sum_entropy[direction]); \
4101   PUSHs(sv_2mortal(newSVpv(message,0))); \
4102   (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4103     channel_features[channel].entropy[direction]); \
4104   PUSHs(sv_2mortal(newSVpv(message,0))); \
4105   (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4106     channel_features[channel].difference_variance[direction]); \
4107   PUSHs(sv_2mortal(newSVpv(message,0))); \
4108   (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4109     channel_features[channel].difference_entropy[direction]); \
4110   PUSHs(sv_2mortal(newSVpv(message,0))); \
4111   (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4112     channel_features[channel].measure_of_correlation_1[direction]); \
4113   PUSHs(sv_2mortal(newSVpv(message,0))); \
4114   (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4115     channel_features[channel].measure_of_correlation_2[direction]); \
4116   PUSHs(sv_2mortal(newSVpv(message,0))); \
4117   (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
4118     channel_features[channel].maximum_correlation_coefficient[direction]); \
4119   PUSHs(sv_2mortal(newSVpv(message,0))); \
4120 }
4121 
4122     AV
4123       *av;
4124 
4125     char
4126       *attribute,
4127       message[MagickPathExtent];
4128 
4129     ChannelFeatures
4130       *channel_features;
4131 
4132     double
4133       distance;
4134 
4135     ExceptionInfo
4136       *exception;
4137 
4138     Image
4139       *image;
4140 
4141     register ssize_t
4142       i;
4143 
4144     ssize_t
4145       count;
4146 
4147     struct PackageInfo
4148       *info;
4149 
4150     SV
4151       *perl_exception,
4152       *reference;
4153 
4154     PERL_UNUSED_VAR(ref);
4155     PERL_UNUSED_VAR(ix);
4156     exception=AcquireExceptionInfo();
4157     perl_exception=newSVpv("",0);
4158     av=NULL;
4159     if (sv_isobject(ST(0)) == 0)
4160       {
4161         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4162           PackageName);
4163         goto PerlException;
4164       }
4165     reference=SvRV(ST(0));
4166     av=newAV();
4167     SvREFCNT_dec(av);
4168     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4169     if (image == (Image *) NULL)
4170       {
4171         ThrowPerlException(exception,OptionError,"NoImagesDefined",
4172           PackageName);
4173         goto PerlException;
4174       }
4175     distance=1.0;
4176     for (i=2; i < items; i+=2)
4177     {
4178       attribute=(char *) SvPV(ST(i-1),na);
4179       switch (*attribute)
4180       {
4181         case 'D':
4182         case 'd':
4183         {
4184           if (LocaleCompare(attribute,"distance") == 0)
4185             {
4186               distance=StringToLong((char *) SvPV(ST(1),na));
4187               break;
4188             }
4189           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4190             attribute);
4191           break;
4192         }
4193         default:
4194         {
4195           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4196             attribute);
4197           break;
4198         }
4199       }
4200     }
4201     count=0;
4202     for ( ; image; image=image->next)
4203     {
4204       channel_features=GetImageFeatures(image,distance,exception);
4205       if (channel_features == (ChannelFeatures *) NULL)
4206         continue;
4207       count++;
4208       EXTEND(sp,280*count);
4209       for (i=0; i < 4; i++)
4210       {
4211         ChannelFeatures(RedChannel,i);
4212         ChannelFeatures(GreenChannel,i);
4213         ChannelFeatures(BlueChannel,i);
4214         if (image->colorspace == CMYKColorspace)
4215           ChannelFeatures(BlackChannel,i);
4216         if (image->alpha_trait != UndefinedPixelTrait)
4217           ChannelFeatures(AlphaChannel,i);
4218       }
4219       channel_features=(ChannelFeatures *)
4220         RelinquishMagickMemory(channel_features);
4221     }
4222 
4223   PerlException:
4224     InheritPerlException(exception,perl_exception);
4225     exception=DestroyExceptionInfo(exception);
4226     SvREFCNT_dec(perl_exception);
4227   }
4228 
4229 #
4230 ###############################################################################
4231 #                                                                             #
4232 #                                                                             #
4233 #                                                                             #
4234 #   F l a t t e n                                                             #
4235 #                                                                             #
4236 #                                                                             #
4237 #                                                                             #
4238 ###############################################################################
4239 #
4240 #
4241 void
Flatten(ref)4242 Flatten(ref)
4243   Image::Magick ref=NO_INIT
4244   ALIAS:
4245     FlattenImage   = 1
4246     flatten        = 2
4247     flattenimage   = 3
4248   PPCODE:
4249   {
4250     AV
4251       *av;
4252 
4253     char
4254       *attribute,
4255       *p;
4256 
4257     ExceptionInfo
4258       *exception;
4259 
4260     HV
4261       *hv;
4262 
4263     Image
4264       *image;
4265 
4266     PixelInfo
4267       background_color;
4268 
4269     register ssize_t
4270       i;
4271 
4272     struct PackageInfo
4273       *info;
4274 
4275     SV
4276       *perl_exception,
4277       *reference,
4278       *rv,
4279       *sv;
4280 
4281     PERL_UNUSED_VAR(ref);
4282     PERL_UNUSED_VAR(ix);
4283     exception=AcquireExceptionInfo();
4284     perl_exception=newSVpv("",0);
4285     sv=NULL;
4286     if (sv_isobject(ST(0)) == 0)
4287       {
4288         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4289           PackageName);
4290         goto PerlException;
4291       }
4292     reference=SvRV(ST(0));
4293     hv=SvSTASH(reference);
4294     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4295     if (image == (Image *) NULL)
4296       {
4297         ThrowPerlException(exception,OptionError,"NoImagesDefined",
4298           PackageName);
4299         goto PerlException;
4300       }
4301     background_color=image->background_color;
4302     if (items == 2)
4303       (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4304         &background_color,exception);
4305     else
4306       for (i=2; i < items; i+=2)
4307       {
4308         attribute=(char *) SvPV(ST(i-1),na);
4309         switch (*attribute)
4310         {
4311           case 'B':
4312           case 'b':
4313           {
4314             if (LocaleCompare(attribute,"background") == 0)
4315               {
4316                 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4317                   AllCompliance,&background_color,exception);
4318                 break;
4319               }
4320             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4321               attribute);
4322             break;
4323           }
4324           default:
4325           {
4326             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4327               attribute);
4328             break;
4329           }
4330         }
4331       }
4332     image->background_color=background_color;
4333     image=MergeImageLayers(image,FlattenLayer,exception);
4334     if (image == (Image *) NULL)
4335       goto PerlException;
4336     /*
4337       Create blessed Perl array for the returned image.
4338     */
4339     av=newAV();
4340     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4341     SvREFCNT_dec(av);
4342     AddImageToRegistry(sv,image);
4343     rv=newRV(sv);
4344     av_push(av,sv_bless(rv,hv));
4345     SvREFCNT_dec(sv);
4346     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4347     (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4348       "flatten-%.*s",(int) (MagickPathExtent-9),
4349       ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4350     (void) CopyMagickString(image->filename,info->image_info->filename,
4351       MagickPathExtent);
4352     SetImageInfo(info->image_info,0,exception);
4353     exception=DestroyExceptionInfo(exception);
4354     SvREFCNT_dec(perl_exception);
4355     XSRETURN(1);
4356 
4357   PerlException:
4358     InheritPerlException(exception,perl_exception);
4359     exception=DestroyExceptionInfo(exception);
4360     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4361     SvPOK_on(perl_exception);  /* return messages in string context */
4362     ST(0)=sv_2mortal(perl_exception);
4363     XSRETURN(1);
4364   }
4365 
4366 #
4367 ###############################################################################
4368 #                                                                             #
4369 #                                                                             #
4370 #                                                                             #
4371 #   F x                                                                       #
4372 #                                                                             #
4373 #                                                                             #
4374 #                                                                             #
4375 ###############################################################################
4376 #
4377 #
4378 void
Fx(ref,...)4379 Fx(ref,...)
4380   Image::Magick ref=NO_INIT
4381   ALIAS:
4382     FxImage  = 1
4383     fx       = 2
4384     fximage  = 3
4385   PPCODE:
4386   {
4387     AV
4388       *av;
4389 
4390     char
4391       *attribute,
4392       expression[MagickPathExtent];
4393 
4394     ChannelType
4395       channel,
4396       channel_mask;
4397 
4398     ExceptionInfo
4399       *exception;
4400 
4401     HV
4402       *hv;
4403 
4404     Image
4405       *image;
4406 
4407     register ssize_t
4408       i;
4409 
4410     struct PackageInfo
4411       *info;
4412 
4413     SV
4414       *av_reference,
4415       *perl_exception,
4416       *reference,
4417       *rv,
4418       *sv;
4419 
4420     PERL_UNUSED_VAR(ref);
4421     PERL_UNUSED_VAR(ix);
4422     exception=AcquireExceptionInfo();
4423     perl_exception=newSVpv("",0);
4424     sv=NULL;
4425     attribute=NULL;
4426     av=NULL;
4427     if (sv_isobject(ST(0)) == 0)
4428       {
4429         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4430           PackageName);
4431         goto PerlException;
4432       }
4433     reference=SvRV(ST(0));
4434     hv=SvSTASH(reference);
4435     av=newAV();
4436     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4437     SvREFCNT_dec(av);
4438     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4439     if (image == (Image *) NULL)
4440       {
4441         ThrowPerlException(exception,OptionError,"NoImagesDefined",
4442           PackageName);
4443         goto PerlException;
4444       }
4445     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4446     /*
4447       Get options.
4448     */
4449     channel=DefaultChannels;
4450     (void) CopyMagickString(expression,"u",MagickPathExtent);
4451     if (items == 2)
4452       (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
4453     else
4454       for (i=2; i < items; i+=2)
4455       {
4456         attribute=(char *) SvPV(ST(i-1),na);
4457         switch (*attribute)
4458         {
4459           case 'C':
4460           case 'c':
4461           {
4462             if (LocaleCompare(attribute,"channel") == 0)
4463               {
4464                 ssize_t
4465                   option;
4466 
4467                 option=ParseChannelOption(SvPV(ST(i),na));
4468                 if (option < 0)
4469                   {
4470                     ThrowPerlException(exception,OptionError,
4471                       "UnrecognizedType",SvPV(ST(i),na));
4472                     return;
4473                   }
4474                 channel=(ChannelType) option;
4475                 break;
4476               }
4477             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4478               attribute);
4479             break;
4480           }
4481           case 'E':
4482           case 'e':
4483           {
4484             if (LocaleCompare(attribute,"expression") == 0)
4485               {
4486                 (void) CopyMagickString(expression,SvPV(ST(i),na),
4487                   MagickPathExtent);
4488                 break;
4489               }
4490             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4491               attribute);
4492             break;
4493           }
4494           default:
4495           {
4496             ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4497               attribute);
4498             break;
4499           }
4500         }
4501       }
4502     channel_mask=SetImageChannelMask(image,channel);
4503     image=FxImage(image,expression,exception);
4504     if (image != (Image *) NULL)
4505       (void) SetImageChannelMask(image,channel_mask);
4506     if (image == (Image *) NULL)
4507       goto PerlException;
4508     for ( ; image; image=image->next)
4509     {
4510       AddImageToRegistry(sv,image);
4511       rv=newRV(sv);
4512       av_push(av,sv_bless(rv,hv));
4513       SvREFCNT_dec(sv);
4514     }
4515     exception=DestroyExceptionInfo(exception);
4516     ST(0)=av_reference;
4517     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
4518     XSRETURN(1);
4519 
4520   PerlException:
4521     InheritPerlException(exception,perl_exception);
4522     exception=DestroyExceptionInfo(exception);
4523     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4524     SvPOK_on(perl_exception);
4525     ST(0)=sv_2mortal(perl_exception);
4526     XSRETURN(1);
4527   }
4528 
4529 #
4530 ###############################################################################
4531 #                                                                             #
4532 #                                                                             #
4533 #                                                                             #
4534 #   G e t                                                                     #
4535 #                                                                             #
4536 #                                                                             #
4537 #                                                                             #
4538 ###############################################################################
4539 #
4540 #
4541 void
Get(ref,...)4542 Get(ref,...)
4543   Image::Magick ref=NO_INIT
4544   ALIAS:
4545     GetAttributes = 1
4546     GetAttribute  = 2
4547     get           = 3
4548     getattributes = 4
4549     getattribute  = 5
4550   PPCODE:
4551   {
4552     char
4553       *attribute,
4554       color[MagickPathExtent];
4555 
4556     const char
4557       *value;
4558 
4559     ExceptionInfo
4560       *exception;
4561 
4562     Image
4563       *image;
4564 
4565     long
4566       j;
4567 
4568     register ssize_t
4569       i;
4570 
4571     struct PackageInfo
4572       *info;
4573 
4574     SV
4575       *perl_exception,
4576       *reference,
4577       *s;
4578 
4579     PERL_UNUSED_VAR(ref);
4580     PERL_UNUSED_VAR(ix);
4581     exception=AcquireExceptionInfo();
4582     perl_exception=newSVpv("",0);
4583     if (sv_isobject(ST(0)) == 0)
4584       {
4585         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4586           PackageName);
4587         XSRETURN_EMPTY;
4588       }
4589     reference=SvRV(ST(0));
4590     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4591     if (image == (Image *) NULL && !info)
4592       XSRETURN_EMPTY;
4593     EXTEND(sp,items);
4594     for (i=1; i < items; i++)
4595     {
4596       attribute=(char *) SvPV(ST(i),na);
4597       s=NULL;
4598       switch (*attribute)
4599       {
4600         case 'A':
4601         case 'a':
4602         {
4603           if (LocaleCompare(attribute,"adjoin") == 0)
4604             {
4605               if (info)
4606                 s=newSViv((ssize_t) info->image_info->adjoin);
4607               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4608               continue;
4609             }
4610           if (LocaleCompare(attribute,"antialias") == 0)
4611             {
4612               if (info)
4613                 s=newSViv((ssize_t) info->image_info->antialias);
4614               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4615               continue;
4616             }
4617           if (LocaleCompare(attribute,"area") == 0)
4618             {
4619               s=newSViv(GetMagickResource(AreaResource));
4620               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4621               continue;
4622             }
4623           if (LocaleCompare(attribute,"attenuate") == 0)
4624             {
4625               const char
4626                 *value;
4627 
4628               value=GetImageProperty(image,attribute,exception);
4629               if (value != (const char *) NULL)
4630                 s=newSVpv(value,0);
4631               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4632               continue;
4633             }
4634           if (LocaleCompare(attribute,"authenticate") == 0)
4635             {
4636               if (info)
4637                 {
4638                   const char
4639                     *option;
4640 
4641                   option=GetImageOption(info->image_info,attribute);
4642                   if (option != (const char *) NULL)
4643                     s=newSVpv(option,0);
4644                 }
4645               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4646               continue;
4647             }
4648           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4649             attribute);
4650           break;
4651         }
4652         case 'B':
4653         case 'b':
4654         {
4655           if (LocaleCompare(attribute,"background") == 0)
4656             {
4657               if (image == (Image *) NULL)
4658                 break;
4659               (void) FormatLocaleString(color,MagickPathExtent,
4660                 "%.20g,%.20g,%.20g,%.20g",(double) image->background_color.red,
4661                 (double) image->background_color.green,
4662                 (double) image->background_color.blue,
4663                 (double) image->background_color.alpha);
4664               s=newSVpv(color,0);
4665               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4666               continue;
4667             }
4668           if (LocaleCompare(attribute,"base-columns") == 0)
4669             {
4670               if (image != (Image *) NULL)
4671                 s=newSViv((ssize_t) image->magick_columns);
4672               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4673               continue;
4674             }
4675           if (LocaleCompare(attribute,"base-filename") == 0)
4676             {
4677               if (image != (Image *) NULL)
4678                 s=newSVpv(image->magick_filename,0);
4679               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4680               continue;
4681             }
4682           if (LocaleCompare(attribute,"base-height") == 0)
4683             {
4684               if (image != (Image *) NULL)
4685                 s=newSViv((ssize_t) image->magick_rows);
4686               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4687               continue;
4688             }
4689           if (LocaleCompare(attribute,"base-rows") == 0)
4690             {
4691               if (image != (Image *) NULL)
4692                 s=newSViv((ssize_t) image->magick_rows);
4693               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4694               continue;
4695             }
4696           if (LocaleCompare(attribute,"base-width") == 0)
4697             {
4698               if (image != (Image *) NULL)
4699                 s=newSViv((ssize_t) image->magick_columns);
4700               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4701               continue;
4702             }
4703           if (LocaleCompare(attribute,"blue-primary") == 0)
4704             {
4705               if (image == (Image *) NULL)
4706                 break;
4707               (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
4708                 image->chromaticity.blue_primary.x,
4709                 image->chromaticity.blue_primary.y);
4710               s=newSVpv(color,0);
4711               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4712               continue;
4713             }
4714           if (LocaleCompare(attribute,"bordercolor") == 0)
4715             {
4716               if (image == (Image *) NULL)
4717                 break;
4718               (void) FormatLocaleString(color,MagickPathExtent,
4719                 "%.20g,%.20g,%.20g,%.20g",(double) image->border_color.red,
4720                 (double) image->border_color.green,
4721                 (double) image->border_color.blue,
4722                 (double) image->border_color.alpha);
4723               s=newSVpv(color,0);
4724               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4725               continue;
4726             }
4727           if (LocaleCompare(attribute,"bounding-box") == 0)
4728             {
4729               char
4730                 geometry[MagickPathExtent];
4731 
4732               RectangleInfo
4733                 page;
4734 
4735               if (image == (Image *) NULL)
4736                 break;
4737               page=GetImageBoundingBox(image,exception);
4738               (void) FormatLocaleString(geometry,MagickPathExtent,
4739                 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4740                 page.height,(double) page.x,(double) page.y);
4741               s=newSVpv(geometry,0);
4742               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4743               continue;
4744             }
4745           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4746             attribute);
4747           break;
4748         }
4749         case 'C':
4750         case 'c':
4751         {
4752           if (LocaleCompare(attribute,"class") == 0)
4753             {
4754               if (image == (Image *) NULL)
4755                 break;
4756               s=newSViv(image->storage_class);
4757               (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4758                 image->storage_class));
4759               SvIOK_on(s);
4760               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4761               continue;
4762             }
4763           if (LocaleCompare(attribute,"clip-mask") == 0)
4764             {
4765               if (image != (Image *) NULL)
4766                 {
4767                   Image
4768                     *mask_image;
4769 
4770                   SV
4771                     *sv;
4772 
4773                   sv=NULL;
4774                   if (image->read_mask == MagickFalse)
4775                     ClipImage(image,exception);
4776                   mask_image=GetImageMask(image,ReadPixelMask,exception);
4777                   if (mask_image != (Image *) NULL)
4778                     {
4779                       AddImageToRegistry(sv,mask_image);
4780                       s=sv_bless(newRV(sv),SvSTASH(reference));
4781                     }
4782                 }
4783               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4784               continue;
4785             }
4786           if (LocaleCompare(attribute,"clip-path") == 0)
4787             {
4788               if (image != (Image *) NULL)
4789                 {
4790                   Image
4791                     *mask_image;
4792 
4793                   SV
4794                     *sv;
4795 
4796                   sv=NULL;
4797                   if (image->read_mask != MagickFalse)
4798                     ClipImage(image,exception);
4799                   mask_image=GetImageMask(image,ReadPixelMask,exception);
4800                   if (mask_image != (Image *) NULL)
4801                     {
4802                       AddImageToRegistry(sv,mask_image);
4803                       s=sv_bless(newRV(sv),SvSTASH(reference));
4804                     }
4805                 }
4806               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4807               continue;
4808             }
4809           if (LocaleCompare(attribute,"compression") == 0)
4810             {
4811               j=info ? info->image_info->compression : image ?
4812                 image->compression : UndefinedCompression;
4813               if (info)
4814                 if (info->image_info->compression == UndefinedCompression)
4815                   j=image->compression;
4816               s=newSViv(j);
4817               (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4818                 j));
4819               SvIOK_on(s);
4820               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4821               continue;
4822             }
4823           if (LocaleCompare(attribute,"colorspace") == 0)
4824             {
4825               j=image ? image->colorspace : RGBColorspace;
4826               s=newSViv(j);
4827               (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4828                 j));
4829               SvIOK_on(s);
4830               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4831               continue;
4832             }
4833           if (LocaleCompare(attribute,"colors") == 0)
4834             {
4835               if (image != (Image *) NULL)
4836                 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4837                   exception));
4838               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4839               continue;
4840             }
4841           if (LocaleNCompare(attribute,"colormap",8) == 0)
4842             {
4843               int
4844                 items;
4845 
4846               if (image == (Image *) NULL || !image->colormap)
4847                 break;
4848               j=0;
4849               items=sscanf(attribute,"%*[^[][%ld",&j);
4850               (void) items;
4851               if (j > (ssize_t) image->colors)
4852                 j%=image->colors;
4853               (void) FormatLocaleString(color,MagickPathExtent,
4854                 "%.20g,%.20g,%.20g,%.20g",(double) image->colormap[j].red,
4855                 (double) image->colormap[j].green,
4856                 (double) image->colormap[j].blue,
4857                 (double) image->colormap[j].alpha);
4858               s=newSVpv(color,0);
4859               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4860               continue;
4861             }
4862           if (LocaleCompare(attribute,"columns") == 0)
4863             {
4864               if (image != (Image *) NULL)
4865                 s=newSViv((ssize_t) image->columns);
4866               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4867               continue;
4868             }
4869           if (LocaleCompare(attribute,"comment") == 0)
4870             {
4871               const char
4872                 *value;
4873 
4874               value=GetImageProperty(image,attribute,exception);
4875               if (value != (const char *) NULL)
4876                 s=newSVpv(value,0);
4877               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4878               continue;
4879             }
4880           if (LocaleCompare(attribute,"copyright") == 0)
4881             {
4882               s=newSVpv(GetMagickCopyright(),0);
4883               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4884               continue;
4885             }
4886           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4887             attribute);
4888           break;
4889         }
4890         case 'D':
4891         case 'd':
4892         {
4893           if (LocaleCompare(attribute,"density") == 0)
4894             {
4895               char
4896                 geometry[MagickPathExtent];
4897 
4898               if (image == (Image *) NULL)
4899                 break;
4900               (void) FormatLocaleString(geometry,MagickPathExtent,"%.15gx%.15g",
4901                 image->resolution.x,image->resolution.y);
4902               s=newSVpv(geometry,0);
4903               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4904               continue;
4905             }
4906           if (LocaleCompare(attribute,"delay") == 0)
4907             {
4908               if (image != (Image *) NULL)
4909                 s=newSViv((ssize_t) image->delay);
4910               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4911               continue;
4912             }
4913           if (LocaleCompare(attribute,"depth") == 0)
4914             {
4915               s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4916               if (image != (Image *) NULL)
4917                 s=newSViv((ssize_t) GetImageDepth(image,exception));
4918               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4919               continue;
4920             }
4921           if (LocaleCompare(attribute,"directory") == 0)
4922             {
4923               if (image && image->directory)
4924                 s=newSVpv(image->directory,0);
4925               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4926               continue;
4927             }
4928           if (LocaleCompare(attribute,"dispose") == 0)
4929             {
4930               if (image == (Image *) NULL)
4931                 break;
4932 
4933               s=newSViv(image->dispose);
4934               (void) sv_setpv(s,
4935                 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
4936               SvIOK_on(s);
4937               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4938               continue;
4939             }
4940           if (LocaleCompare(attribute,"disk") == 0)
4941             {
4942               s=newSViv(GetMagickResource(DiskResource));
4943               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4944               continue;
4945             }
4946           if (LocaleCompare(attribute,"dither") == 0)
4947             {
4948               if (info)
4949                 s=newSViv((ssize_t) info->image_info->dither);
4950               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4951               continue;
4952             }
4953           if (LocaleCompare(attribute,"display") == 0)  /* same as server */
4954             {
4955               if (info && info->image_info->server_name)
4956                 s=newSVpv(info->image_info->server_name,0);
4957               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4958               continue;
4959             }
4960           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4961             attribute);
4962           break;
4963         }
4964         case 'E':
4965         case 'e':
4966         {
4967           if (LocaleCompare(attribute,"elapsed-time") == 0)
4968             {
4969               if (image != (Image *) NULL)
4970                 s=newSVnv(GetElapsedTime(&image->timer));
4971               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4972               continue;
4973             }
4974           if (LocaleCompare(attribute,"endian") == 0)
4975             {
4976               j=info ? info->image_info->endian : image ? image->endian :
4977                 UndefinedEndian;
4978               s=newSViv(j);
4979               (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
4980               SvIOK_on(s);
4981               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4982               continue;
4983             }
4984           if (LocaleCompare(attribute,"error") == 0)
4985             {
4986               if (image != (Image *) NULL)
4987                 s=newSVnv(image->error.mean_error_per_pixel);
4988               PUSHs(s ? sv_2mortal(s) : &sv_undef);
4989               continue;
4990             }
4991           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4992             attribute);
4993           break;
4994         }
4995         case 'F':
4996         case 'f':
4997         {
4998           if (LocaleCompare(attribute,"filesize") == 0)
4999             {
5000               if (image != (Image *) NULL)
5001                 s=newSViv((ssize_t) GetBlobSize(image));
5002               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5003               continue;
5004             }
5005           if (LocaleCompare(attribute,"filename") == 0)
5006             {
5007               if (info && info->image_info->filename &&
5008                   *info->image_info->filename)
5009                 s=newSVpv(info->image_info->filename,0);
5010               if (image != (Image *) NULL)
5011                 s=newSVpv(image->filename,0);
5012               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5013               continue;
5014             }
5015           if (LocaleCompare(attribute,"filter") == 0)
5016             {
5017               s=image ? newSViv(image->filter) : newSViv(0);
5018               (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
5019                 image->filter));
5020               SvIOK_on(s);
5021               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5022               continue;
5023             }
5024           if (LocaleCompare(attribute,"font") == 0)
5025             {
5026               if (info && info->image_info->font)
5027                 s=newSVpv(info->image_info->font,0);
5028               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5029               continue;
5030             }
5031           if (LocaleCompare(attribute,"foreground") == 0)
5032             continue;
5033           if (LocaleCompare(attribute,"format") == 0)
5034             {
5035               const MagickInfo
5036                 *magick_info;
5037 
5038               magick_info=(const MagickInfo *) NULL;
5039               if (info && (*info->image_info->magick != '\0'))
5040                 magick_info=GetMagickInfo(info->image_info->magick,exception);
5041               if (image != (Image *) NULL)
5042                 magick_info=GetMagickInfo(image->magick,exception);
5043               if ((magick_info != (const MagickInfo *) NULL) &&
5044                   (*magick_info->description != '\0'))
5045                 s=newSVpv((char *) magick_info->description,0);
5046               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5047               continue;
5048             }
5049           if (LocaleCompare(attribute,"fuzz") == 0)
5050             {
5051               if (info)
5052                 s=newSVnv(info->image_info->fuzz);
5053               if (image != (Image *) NULL)
5054                 s=newSVnv(image->fuzz);
5055               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5056               continue;
5057             }
5058           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5059             attribute);
5060           break;
5061         }
5062         case 'G':
5063         case 'g':
5064         {
5065           if (LocaleCompare(attribute,"gamma") == 0)
5066             {
5067               if (image != (Image *) NULL)
5068                 s=newSVnv(image->gamma);
5069               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5070               continue;
5071             }
5072           if (LocaleCompare(attribute,"geometry") == 0)
5073             {
5074               if (image && image->geometry)
5075                 s=newSVpv(image->geometry,0);
5076               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5077               continue;
5078             }
5079           if (LocaleCompare(attribute,"gravity") == 0)
5080             {
5081               s=image ? newSViv(image->gravity) : newSViv(0);
5082               (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
5083                 image->gravity));
5084               SvIOK_on(s);
5085               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5086               continue;
5087             }
5088           if (LocaleCompare(attribute,"green-primary") == 0)
5089             {
5090               if (image == (Image *) NULL)
5091                 break;
5092               (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
5093                 image->chromaticity.green_primary.x,
5094                 image->chromaticity.green_primary.y);
5095               s=newSVpv(color,0);
5096               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5097               continue;
5098             }
5099           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5100             attribute);
5101           break;
5102         }
5103         case 'H':
5104         case 'h':
5105         {
5106           if (LocaleCompare(attribute,"height") == 0)
5107             {
5108               if (image != (Image *) NULL)
5109                 s=newSViv((ssize_t) image->rows);
5110               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5111               continue;
5112             }
5113           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5114             attribute);
5115           break;
5116         }
5117         case 'I':
5118         case 'i':
5119         {
5120           if (LocaleCompare(attribute,"icc") == 0)
5121             {
5122               if (image != (Image *) NULL)
5123                 {
5124                   const StringInfo
5125                     *profile;
5126 
5127                   profile=GetImageProfile(image,"icc");
5128                   if (profile != (StringInfo *) NULL)
5129                     s=newSVpv((const char *) GetStringInfoDatum(profile),
5130                       GetStringInfoLength(profile));
5131                 }
5132               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5133               continue;
5134             }
5135           if (LocaleCompare(attribute,"icm") == 0)
5136             {
5137               if (image != (Image *) NULL)
5138                 {
5139                   const StringInfo
5140                     *profile;
5141 
5142                   profile=GetImageProfile(image,"icm");
5143                   if (profile != (const StringInfo *) NULL)
5144                     s=newSVpv((const char *) GetStringInfoDatum(profile),
5145                       GetStringInfoLength(profile));
5146                 }
5147               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5148               continue;
5149             }
5150           if (LocaleCompare(attribute,"id") == 0)
5151             {
5152               if (image != (Image *) NULL)
5153                 {
5154                   char
5155                     key[MagickPathExtent];
5156 
5157                   MagickBooleanType
5158                     status;
5159 
5160                   static ssize_t
5161                     id = 0;
5162 
5163                   (void) FormatLocaleString(key,MagickPathExtent,"%.20g\n",(double)
5164                     id);
5165                   status=SetImageRegistry(ImageRegistryType,key,image,
5166                     exception);
5167                   (void) status;
5168                   s=newSViv(id++);
5169                 }
5170               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5171               continue;
5172             }
5173           if (LocaleNCompare(attribute,"index",5) == 0)
5174             {
5175               char
5176                 name[MagickPathExtent];
5177 
5178               int
5179                 items;
5180 
5181               long
5182                 x,
5183                 y;
5184 
5185               register const Quantum
5186                 *p;
5187 
5188               CacheView
5189                 *image_view;
5190 
5191               if (image == (Image *) NULL)
5192                 break;
5193               if (image->storage_class != PseudoClass)
5194                 break;
5195               x=0;
5196               y=0;
5197               items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5198               (void) items;
5199               image_view=AcquireVirtualCacheView(image,exception);
5200               p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5201               if (p != (const Quantum *) NULL)
5202                 {
5203                   (void) FormatLocaleString(name,MagickPathExtent,QuantumFormat,
5204                     GetPixelIndex(image,p));
5205                   s=newSVpv(name,0);
5206                   PUSHs(s ? sv_2mortal(s) : &sv_undef);
5207                 }
5208               image_view=DestroyCacheView(image_view);
5209               continue;
5210             }
5211           if (LocaleCompare(attribute,"iptc") == 0)
5212             {
5213               if (image != (Image *) NULL)
5214                 {
5215                   const StringInfo
5216                     *profile;
5217 
5218                   profile=GetImageProfile(image,"iptc");
5219                   if (profile != (const StringInfo *) NULL)
5220                     s=newSVpv((const char *) GetStringInfoDatum(profile),
5221                       GetStringInfoLength(profile));
5222                 }
5223               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5224               continue;
5225             }
5226           if (LocaleCompare(attribute,"iterations") == 0)  /* same as loop */
5227             {
5228               if (image != (Image *) NULL)
5229                 s=newSViv((ssize_t) image->iterations);
5230               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5231               continue;
5232             }
5233           if (LocaleCompare(attribute,"interlace") == 0)
5234             {
5235               j=info ? info->image_info->interlace : image ? image->interlace :
5236                 UndefinedInterlace;
5237               s=newSViv(j);
5238               (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5239                 j));
5240               SvIOK_on(s);
5241               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5242               continue;
5243             }
5244           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5245             attribute);
5246           break;
5247         }
5248         case 'L':
5249         case 'l':
5250         {
5251           if (LocaleCompare(attribute,"label") == 0)
5252             {
5253               const char
5254                 *value;
5255 
5256               if (image == (Image *) NULL)
5257                 break;
5258               value=GetImageProperty(image,"Label",exception);
5259               if (value != (const char *) NULL)
5260                 s=newSVpv(value,0);
5261               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5262               continue;
5263             }
5264           if (LocaleCompare(attribute,"loop") == 0)  /* same as iterations */
5265             {
5266               if (image != (Image *) NULL)
5267                 s=newSViv((ssize_t) image->iterations);
5268               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5269               continue;
5270             }
5271           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5272             attribute);
5273           break;
5274         }
5275         case 'M':
5276         case 'm':
5277         {
5278           if (LocaleCompare(attribute,"magick") == 0)
5279             {
5280               if (info && *info->image_info->magick)
5281                 s=newSVpv(info->image_info->magick,0);
5282               if (image != (Image *) NULL)
5283                 s=newSVpv(image->magick,0);
5284               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5285               continue;
5286             }
5287           if (LocaleCompare(attribute,"map") == 0)
5288             {
5289               s=newSViv(GetMagickResource(MapResource));
5290               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5291               continue;
5292             }
5293           if (LocaleCompare(attribute,"maximum-error") == 0)
5294             {
5295               if (image != (Image *) NULL)
5296                 s=newSVnv(image->error.normalized_maximum_error);
5297               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5298               continue;
5299             }
5300           if (LocaleCompare(attribute,"memory") == 0)
5301             {
5302               s=newSViv(GetMagickResource(MemoryResource));
5303               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5304               continue;
5305             }
5306           if (LocaleCompare(attribute,"mean-error") == 0)
5307             {
5308               if (image != (Image *) NULL)
5309                 s=newSVnv(image->error.normalized_mean_error);
5310               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5311               continue;
5312             }
5313           if (LocaleCompare(attribute,"mime") == 0)
5314             {
5315               if (info && *info->image_info->magick)
5316                 s=newSVpv(MagickToMime(info->image_info->magick),0);
5317               if (image != (Image *) NULL)
5318                 s=newSVpv(MagickToMime(image->magick),0);
5319               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5320               continue;
5321             }
5322           if (LocaleCompare(attribute,"mattecolor") == 0)
5323             {
5324               if (image == (Image *) NULL)
5325                 break;
5326               (void) FormatLocaleString(color,MagickPathExtent,
5327                 "%.20g,%.20g,%.20g,%.20g",(double) image->alpha_color.red,
5328                 (double) image->alpha_color.green,
5329                 (double) image->alpha_color.blue,
5330                 (double) image->alpha_color.alpha);
5331               s=newSVpv(color,0);
5332               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5333               continue;
5334             }
5335           if (LocaleCompare(attribute,"matte") == 0)
5336             {
5337               if (image != (Image *) NULL)
5338                 s=newSViv((ssize_t) image->alpha_trait != UndefinedPixelTrait ?
5339                   1 : 0);
5340               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5341               continue;
5342             }
5343           if (LocaleCompare(attribute,"mime") == 0)
5344             {
5345               const char
5346                 *magick;
5347 
5348               magick=NULL;
5349               if (info && *info->image_info->magick)
5350                 magick=info->image_info->magick;
5351               if (image != (Image *) NULL)
5352                 magick=image->magick;
5353               if (magick)
5354                 {
5355                   char
5356                     *mime;
5357 
5358                   mime=MagickToMime(magick);
5359                   s=newSVpv(mime,0);
5360                   mime=(char *) RelinquishMagickMemory(mime);
5361                 }
5362               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5363               continue;
5364             }
5365           if (LocaleCompare(attribute,"monochrome") == 0)
5366             {
5367               if (image == (Image *) NULL)
5368                 continue;
5369               j=info ? info->image_info->monochrome :
5370                 SetImageMonochrome(image,exception);
5371               s=newSViv(j);
5372               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5373               continue;
5374             }
5375           if (LocaleCompare(attribute,"montage") == 0)
5376             {
5377               if (image && image->montage)
5378                 s=newSVpv(image->montage,0);
5379               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5380               continue;
5381             }
5382           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5383             attribute);
5384           break;
5385         }
5386         case 'O':
5387         case 'o':
5388         {
5389           if (LocaleCompare(attribute,"orientation") == 0)
5390             {
5391               j=info ? info->image_info->orientation : image ?
5392                 image->orientation : UndefinedOrientation;
5393               s=newSViv(j);
5394               (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5395                 j));
5396               SvIOK_on(s);
5397               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5398               continue;
5399             }
5400           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5401             attribute);
5402           break;
5403         }
5404         case 'P':
5405         case 'p':
5406         {
5407           if (LocaleCompare(attribute,"page") == 0)
5408             {
5409               if (info && info->image_info->page)
5410                 s=newSVpv(info->image_info->page,0);
5411               if (image != (Image *) NULL)
5412                 {
5413                   char
5414                     geometry[MagickPathExtent];
5415 
5416                   (void) FormatLocaleString(geometry,MagickPathExtent,
5417                     "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5418                     (double) image->page.height,(double) image->page.x,(double)
5419                     image->page.y);
5420                   s=newSVpv(geometry,0);
5421                 }
5422               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5423               continue;
5424             }
5425           if (LocaleCompare(attribute,"page.x") == 0)
5426             {
5427               if (image != (Image *) NULL)
5428                 s=newSViv((ssize_t) image->page.x);
5429               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5430               continue;
5431             }
5432           if (LocaleCompare(attribute,"page.y") == 0)
5433             {
5434               if (image != (Image *) NULL)
5435                 s=newSViv((ssize_t) image->page.y);
5436               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5437               continue;
5438             }
5439           if (LocaleNCompare(attribute,"pixel",5) == 0)
5440             {
5441               char
5442                 tuple[MagickPathExtent];
5443 
5444               int
5445                 items;
5446 
5447               long
5448                 x,
5449                 y;
5450 
5451               register const Quantum
5452                 *p;
5453 
5454               if (image == (Image *) NULL)
5455                 break;
5456               x=0;
5457               y=0;
5458               items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5459               (void) items;
5460               p=GetVirtualPixels(image,x,y,1,1,exception);
5461               if (image->colorspace != CMYKColorspace)
5462                 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
5463                   QuantumFormat "," QuantumFormat "," QuantumFormat,
5464                   GetPixelRed(image,p),GetPixelGreen(image,p),
5465                   GetPixelBlue(image,p),GetPixelAlpha(image,p));
5466               else
5467                 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
5468                   QuantumFormat "," QuantumFormat "," QuantumFormat ","
5469                   QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5470                   GetPixelBlue(image,p),GetPixelBlack(image,p),
5471                   GetPixelAlpha(image,p));
5472               s=newSVpv(tuple,0);
5473               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5474               continue;
5475             }
5476           if (LocaleCompare(attribute,"pointsize") == 0)
5477             {
5478               if (info)
5479                 s=newSViv((ssize_t) info->image_info->pointsize);
5480               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5481               continue;
5482             }
5483           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5484             attribute);
5485           break;
5486         }
5487         case 'Q':
5488         case 'q':
5489         {
5490           if (LocaleCompare(attribute,"quality") == 0)
5491             {
5492               if (info)
5493                 s=newSViv((ssize_t) info->image_info->quality);
5494               if (image != (Image *) NULL)
5495                 s=newSViv((ssize_t) image->quality);
5496               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5497               continue;
5498             }
5499           if (LocaleCompare(attribute,"quantum") == 0)
5500             {
5501               if (info)
5502                 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5503               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5504               continue;
5505             }
5506           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5507             attribute);
5508           break;
5509         }
5510         case 'R':
5511         case 'r':
5512         {
5513           if (LocaleCompare(attribute,"rendering-intent") == 0)
5514             {
5515               s=newSViv(image->rendering_intent);
5516               (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5517                 image->rendering_intent));
5518               SvIOK_on(s);
5519               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5520               continue;
5521             }
5522           if (LocaleCompare(attribute,"red-primary") == 0)
5523             {
5524               if (image == (Image *) NULL)
5525                 break;
5526               (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
5527                 image->chromaticity.red_primary.x,
5528                 image->chromaticity.red_primary.y);
5529               s=newSVpv(color,0);
5530               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5531               continue;
5532             }
5533           if (LocaleCompare(attribute,"rows") == 0)
5534             {
5535               if (image != (Image *) NULL)
5536                 s=newSViv((ssize_t) image->rows);
5537               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5538               continue;
5539             }
5540           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5541             attribute);
5542           break;
5543         }
5544         case 'S':
5545         case 's':
5546         {
5547           if (LocaleCompare(attribute,"sampling-factor") == 0)
5548             {
5549               if (info && info->image_info->sampling_factor)
5550                 s=newSVpv(info->image_info->sampling_factor,0);
5551               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5552               continue;
5553             }
5554           if (LocaleCompare(attribute,"server") == 0)  /* same as display */
5555             {
5556               if (info && info->image_info->server_name)
5557                 s=newSVpv(info->image_info->server_name,0);
5558               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5559               continue;
5560             }
5561           if (LocaleCompare(attribute,"size") == 0)
5562             {
5563               if (info && info->image_info->size)
5564                 s=newSVpv(info->image_info->size,0);
5565               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5566               continue;
5567             }
5568           if (LocaleCompare(attribute,"scene") == 0)
5569             {
5570               if (image != (Image *) NULL)
5571                 s=newSViv((ssize_t) image->scene);
5572               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5573               continue;
5574             }
5575           if (LocaleCompare(attribute,"scenes") == 0)
5576             {
5577               if (image != (Image *) NULL)
5578                 s=newSViv((ssize_t) info->image_info->number_scenes);
5579               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5580               continue;
5581             }
5582           if (LocaleCompare(attribute,"signature") == 0)
5583             {
5584               const char
5585                 *value;
5586 
5587               if (image == (Image *) NULL)
5588                 break;
5589               (void) SignatureImage(image,exception);
5590               value=GetImageProperty(image,"Signature",exception);
5591               if (value != (const char *) NULL)
5592                 s=newSVpv(value,0);
5593               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5594               continue;
5595             }
5596           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5597             attribute);
5598           break;
5599         }
5600         case 'T':
5601         case 't':
5602         {
5603           if (LocaleCompare(attribute,"taint") == 0)
5604             {
5605               if (image != (Image *) NULL)
5606                 s=newSViv((ssize_t) IsTaintImage(image));
5607               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5608               continue;
5609             }
5610           if (LocaleCompare(attribute,"texture") == 0)
5611             {
5612               if (info && info->image_info->texture)
5613                 s=newSVpv(info->image_info->texture,0);
5614               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5615               continue;
5616             }
5617           if (LocaleCompare(attribute,"total-ink-density") == 0)
5618             {
5619               s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5620               if (image != (Image *) NULL)
5621                 s=newSVnv(GetImageTotalInkDensity(image,exception));
5622               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5623               continue;
5624             }
5625           if (LocaleCompare(attribute,"transparent-color") == 0)
5626             {
5627               if (image == (Image *) NULL)
5628                 break;
5629               (void) FormatLocaleString(color,MagickPathExtent,
5630                 "%.20g,%.20g,%.20g,%.20g",(double) image->transparent_color.red,
5631                 (double) image->transparent_color.green,
5632                 (double) image->transparent_color.blue,
5633                 (double) image->transparent_color.alpha);
5634               s=newSVpv(color,0);
5635               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5636               continue;
5637             }
5638           if (LocaleCompare(attribute,"type") == 0)
5639             {
5640               if (image == (Image *) NULL)
5641                 break;
5642               j=(ssize_t) GetImageType(image);
5643               s=newSViv(j);
5644               (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5645               SvIOK_on(s);
5646               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5647               continue;
5648             }
5649           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5650             attribute);
5651           break;
5652         }
5653         case 'U':
5654         case 'u':
5655         {
5656           if (LocaleCompare(attribute,"units") == 0)
5657             {
5658               j=info ? info->image_info->units : image ? image->units :
5659                 UndefinedResolution;
5660               if (info && (info->image_info->units == UndefinedResolution))
5661                 if (image)
5662                   j=image->units;
5663               if (j == UndefinedResolution)
5664                 s=newSVpv("undefined units",0);
5665               else
5666                 if (j == PixelsPerInchResolution)
5667                   s=newSVpv("pixels / inch",0);
5668                 else
5669                   s=newSVpv("pixels / centimeter",0);
5670               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5671               continue;
5672             }
5673           if (LocaleCompare(attribute,"user-time") == 0)
5674             {
5675               if (image != (Image *) NULL)
5676                 s=newSVnv(GetUserTime(&image->timer));
5677               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5678               continue;
5679             }
5680           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5681             attribute);
5682           break;
5683         }
5684         case 'V':
5685         case 'v':
5686         {
5687           if (LocaleCompare(attribute,"verbose") == 0)
5688             {
5689               if (info)
5690                 s=newSViv((ssize_t) info->image_info->verbose);
5691               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5692               continue;
5693             }
5694           if (LocaleCompare(attribute,"version") == 0)
5695             {
5696               s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5697               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5698               continue;
5699             }
5700           if (LocaleCompare(attribute,"virtual-pixel") == 0)
5701             {
5702               if (image == (Image *) NULL)
5703                 break;
5704               j=(ssize_t) GetImageVirtualPixelMethod(image);
5705               s=newSViv(j);
5706               (void) sv_setpv(s,CommandOptionToMnemonic(
5707                 MagickVirtualPixelOptions,j));
5708               SvIOK_on(s);
5709               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5710               continue;
5711             }
5712           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5713             attribute);
5714           break;
5715         }
5716         case 'W':
5717         case 'w':
5718         {
5719           if (LocaleCompare(attribute,"white-point") == 0)
5720             {
5721               if (image == (Image *) NULL)
5722                 break;
5723               (void) FormatLocaleString(color,MagickPathExtent,"%.15g,%.15g",
5724                 image->chromaticity.white_point.x,
5725                 image->chromaticity.white_point.y);
5726               s=newSVpv(color,0);
5727               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5728               continue;
5729             }
5730           if (LocaleCompare(attribute,"width") == 0)
5731             {
5732               if (image != (Image *) NULL)
5733                 s=newSViv((ssize_t) image->columns);
5734               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5735               continue;
5736             }
5737           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5738              attribute);
5739           break;
5740         }
5741         case 'X':
5742         case 'x':
5743         {
5744           if (LocaleCompare(attribute,"xmp") == 0)
5745             {
5746               if (image != (Image *) NULL)
5747                 {
5748                   const StringInfo
5749                     *profile;
5750 
5751                   profile=GetImageProfile(image,"xmp");
5752                   if (profile != (StringInfo *) NULL)
5753                     s=newSVpv((const char *) GetStringInfoDatum(profile),
5754                       GetStringInfoLength(profile));
5755                 }
5756               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5757               continue;
5758             }
5759           if (LocaleCompare(attribute,"x-resolution") == 0)
5760             {
5761               if (image != (Image *) NULL)
5762                 s=newSVnv(image->resolution.x);
5763               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5764               continue;
5765             }
5766           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5767             attribute);
5768           break;
5769         }
5770         case 'Y':
5771         case 'y':
5772         {
5773           if (LocaleCompare(attribute,"y-resolution") == 0)
5774             {
5775               if (image != (Image *) NULL)
5776                 s=newSVnv(image->resolution.y);
5777               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5778               continue;
5779             }
5780           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5781             attribute);
5782           break;
5783         }
5784         default:
5785           break;
5786       }
5787       if (image == (Image *) NULL)
5788         ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5789           attribute)
5790       else
5791         {
5792           value=GetImageProperty(image,attribute,exception);
5793           if (value != (const char *) NULL)
5794             {
5795               s=newSVpv(value,0);
5796               PUSHs(s ? sv_2mortal(s) : &sv_undef);
5797             }
5798           else
5799             if (*attribute != '%')
5800               ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5801                 attribute)
5802             else
5803               {
5804                  char
5805                    *meta;
5806 
5807                  meta=InterpretImageProperties(info ? info->image_info :
5808                    (ImageInfo *) NULL,image,attribute,exception);
5809                  s=newSVpv(meta,0);
5810                  PUSHs(s ? sv_2mortal(s) : &sv_undef);
5811                  meta=(char *) RelinquishMagickMemory(meta);
5812               }
5813         }
5814     }
5815     exception=DestroyExceptionInfo(exception);
5816     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
5817   }
5818 
5819 #
5820 ###############################################################################
5821 #                                                                             #
5822 #                                                                             #
5823 #                                                                             #
5824 #   G e t A u t h e n t i c P i x e l s                                       #
5825 #                                                                             #
5826 #                                                                             #
5827 #                                                                             #
5828 ###############################################################################
5829 #
5830 #
5831 void *
GetAuthenticPixels(ref,...)5832 GetAuthenticPixels(ref,...)
5833   Image::Magick ref = NO_INIT
5834   ALIAS:
5835     getauthenticpixels = 1
5836     GetImagePixels = 2
5837     getimagepixels = 3
5838   CODE:
5839   {
5840     char
5841       *attribute;
5842 
5843     ExceptionInfo
5844       *exception;
5845 
5846     Image
5847       *image;
5848 
5849     RectangleInfo
5850       region;
5851 
5852     ssize_t
5853       i;
5854 
5855     struct PackageInfo
5856       *info;
5857 
5858     SV
5859       *perl_exception,
5860       *reference;
5861 
5862     void
5863       *blob = NULL;
5864 
5865     PERL_UNUSED_VAR(ref);
5866     PERL_UNUSED_VAR(ix);
5867     exception=AcquireExceptionInfo();
5868     perl_exception=newSVpv("",0);
5869     if (sv_isobject(ST(0)) == 0)
5870       {
5871         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5872           PackageName);
5873         goto PerlException;
5874       }
5875     reference=SvRV(ST(0));
5876 
5877     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5878     if (image == (Image *) NULL)
5879       {
5880         ThrowPerlException(exception,OptionError,"NoImagesDefined",
5881           PackageName);
5882         goto PerlException;
5883       }
5884 
5885     region.x=0;
5886     region.y=0;
5887     region.width=image->columns;
5888     region.height=1;
5889     if (items == 1)
5890       (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5891     for (i=2; i < items; i+=2)
5892     {
5893       attribute=(char *) SvPV(ST(i-1),na);
5894       switch (*attribute)
5895       {
5896         case 'g':
5897         case 'G':
5898         {
5899           if (LocaleCompare(attribute,"geometry") == 0)
5900             {
5901               (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5902               break;
5903             }
5904           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5905             attribute);
5906           break;
5907         }
5908         case 'H':
5909         case 'h':
5910         {
5911           if (LocaleCompare(attribute,"height") == 0)
5912             {
5913               region.height=SvIV(ST(i));
5914               continue;
5915             }
5916           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5917             attribute);
5918           break;
5919         }
5920         case 'X':
5921         case 'x':
5922         {
5923           if (LocaleCompare(attribute,"x") == 0)
5924             {
5925               region.x=SvIV(ST(i));
5926               continue;
5927             }
5928           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5929             attribute);
5930           break;
5931         }
5932         case 'Y':
5933         case 'y':
5934         {
5935           if (LocaleCompare(attribute,"y") == 0)
5936             {
5937               region.y=SvIV(ST(i));
5938               continue;
5939             }
5940           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5941             attribute);
5942           break;
5943         }
5944         case 'W':
5945         case 'w':
5946         {
5947           if (LocaleCompare(attribute,"width") == 0)
5948             {
5949               region.width=SvIV(ST(i));
5950               continue;
5951             }
5952           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5953             attribute);
5954           break;
5955         }
5956       }
5957     }
5958     blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
5959       region.height,exception);
5960     if (blob != (void *) NULL)
5961       goto PerlEnd;
5962 
5963   PerlException:
5964     InheritPerlException(exception,perl_exception);
5965     exception=DestroyExceptionInfo(exception);
5966     SvREFCNT_dec(perl_exception);  /* throw away all errors */
5967 
5968   PerlEnd:
5969     RETVAL = blob;
5970   }
5971   OUTPUT:
5972     RETVAL
5973 
5974 #
5975 ###############################################################################
5976 #                                                                             #
5977 #                                                                             #
5978 #                                                                             #
5979 #   G e t V i r t u a l P i x e l s                                           #
5980 #                                                                             #
5981 #                                                                             #
5982 #                                                                             #
5983 ###############################################################################
5984 #
5985 #
5986 void *
GetVirtualPixels(ref,...)5987 GetVirtualPixels(ref,...)
5988   Image::Magick ref = NO_INIT
5989   ALIAS:
5990     getvirtualpixels = 1
5991     AcquireImagePixels = 2
5992     acquireimagepixels = 3
5993   CODE:
5994   {
5995     char
5996       *attribute;
5997 
5998     const void
5999       *blob = NULL;
6000 
6001     ExceptionInfo
6002       *exception;
6003 
6004     Image
6005       *image;
6006 
6007     RectangleInfo
6008       region;
6009 
6010     ssize_t
6011       i;
6012 
6013     struct PackageInfo
6014       *info;
6015 
6016     SV
6017       *perl_exception,
6018       *reference;
6019 
6020     PERL_UNUSED_VAR(ref);
6021     PERL_UNUSED_VAR(ix);
6022     exception=AcquireExceptionInfo();
6023     perl_exception=newSVpv("",0);
6024     if (sv_isobject(ST(0)) == 0)
6025       {
6026         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6027           PackageName);
6028         goto PerlException;
6029       }
6030     reference=SvRV(ST(0));
6031 
6032     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6033     if (image == (Image *) NULL)
6034       {
6035         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6036           PackageName);
6037         goto PerlException;
6038       }
6039 
6040     region.x=0;
6041     region.y=0;
6042     region.width=image->columns;
6043     region.height=1;
6044     if (items == 1)
6045       (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6046     for (i=2; i < items; i+=2)
6047     {
6048       attribute=(char *) SvPV(ST(i-1),na);
6049       switch (*attribute)
6050       {
6051         case 'g':
6052         case 'G':
6053         {
6054           if (LocaleCompare(attribute,"geometry") == 0)
6055             {
6056               (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6057               break;
6058             }
6059           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6060             attribute);
6061           break;
6062         }
6063         case 'H':
6064         case 'h':
6065         {
6066           if (LocaleCompare(attribute,"height") == 0)
6067             {
6068               region.height=SvIV(ST(i));
6069               continue;
6070             }
6071           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6072             attribute);
6073           break;
6074         }
6075         case 'X':
6076         case 'x':
6077         {
6078           if (LocaleCompare(attribute,"x") == 0)
6079             {
6080               region.x=SvIV(ST(i));
6081               continue;
6082             }
6083           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6084             attribute);
6085           break;
6086         }
6087         case 'Y':
6088         case 'y':
6089         {
6090           if (LocaleCompare(attribute,"y") == 0)
6091             {
6092               region.y=SvIV(ST(i));
6093               continue;
6094             }
6095           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6096             attribute);
6097           break;
6098         }
6099         case 'W':
6100         case 'w':
6101         {
6102           if (LocaleCompare(attribute,"width") == 0)
6103             {
6104               region.width=SvIV(ST(i));
6105               continue;
6106             }
6107           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6108             attribute);
6109           break;
6110         }
6111       }
6112     }
6113     blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
6114       region.height,exception);
6115     if (blob != (void *) NULL)
6116       goto PerlEnd;
6117 
6118   PerlException:
6119     InheritPerlException(exception,perl_exception);
6120     exception=DestroyExceptionInfo(exception);
6121     SvREFCNT_dec(perl_exception);  /* throw away all errors */
6122 
6123   PerlEnd:
6124     RETVAL = (void *) blob;
6125   }
6126   OUTPUT:
6127     RETVAL
6128 
6129 #
6130 ###############################################################################
6131 #                                                                             #
6132 #                                                                             #
6133 #                                                                             #
6134 #   G e t A u t h e n t i c M e t a c o n t e n t                             #
6135 #                                                                             #
6136 #                                                                             #
6137 #                                                                             #
6138 ###############################################################################
6139 #
6140 #
6141 void *
GetAuthenticMetacontent(ref,...)6142 GetAuthenticMetacontent(ref,...)
6143   Image::Magick ref = NO_INIT
6144   ALIAS:
6145     getauthenticmetacontent = 1
6146     GetMetacontent = 2
6147     getmetacontent = 3
6148   CODE:
6149   {
6150     ExceptionInfo
6151       *exception;
6152 
6153     Image
6154       *image;
6155 
6156     struct PackageInfo
6157       *info;
6158 
6159     SV
6160       *perl_exception,
6161       *reference;
6162 
6163     void
6164       *blob = NULL;
6165 
6166     PERL_UNUSED_VAR(ref);
6167     PERL_UNUSED_VAR(ix);
6168     exception=AcquireExceptionInfo();
6169     perl_exception=newSVpv("",0);
6170     if (sv_isobject(ST(0)) == 0)
6171       {
6172         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6173           PackageName);
6174         goto PerlException;
6175       }
6176     reference=SvRV(ST(0));
6177 
6178     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6179     if (image == (Image *) NULL)
6180       {
6181         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6182           PackageName);
6183         goto PerlException;
6184       }
6185 
6186     blob=(void *) GetAuthenticMetacontent(image);
6187     if (blob != (void *) NULL)
6188       goto PerlEnd;
6189 
6190   PerlException:
6191     InheritPerlException(exception,perl_exception);
6192     exception=DestroyExceptionInfo(exception);
6193     SvREFCNT_dec(perl_exception);  /* throw away all errors */
6194 
6195   PerlEnd:
6196     RETVAL = blob;
6197   }
6198   OUTPUT:
6199     RETVAL
6200 
6201 #
6202 ###############################################################################
6203 #                                                                             #
6204 #                                                                             #
6205 #                                                                             #
6206 #   G e t V i r t u a l M e t a c o n t e n t                                 #
6207 #                                                                             #
6208 #                                                                             #
6209 #                                                                             #
6210 ###############################################################################
6211 #
6212 #
6213 void *
GetVirtualMetacontent(ref,...)6214 GetVirtualMetacontent(ref,...)
6215   Image::Magick ref = NO_INIT
6216   ALIAS:
6217     getvirtualmetacontent = 1
6218   CODE:
6219   {
6220     ExceptionInfo
6221       *exception;
6222 
6223     Image
6224       *image;
6225 
6226     struct PackageInfo
6227       *info;
6228 
6229     SV
6230       *perl_exception,
6231       *reference;
6232 
6233     void
6234       *blob = NULL;
6235 
6236     PERL_UNUSED_VAR(ref);
6237     PERL_UNUSED_VAR(ix);
6238     exception=AcquireExceptionInfo();
6239     perl_exception=newSVpv("",0);
6240     if (sv_isobject(ST(0)) == 0)
6241       {
6242         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6243           PackageName);
6244         goto PerlException;
6245       }
6246     reference=SvRV(ST(0));
6247 
6248     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6249     if (image == (Image *) NULL)
6250       {
6251         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6252           PackageName);
6253         goto PerlException;
6254       }
6255 
6256     blob=(void *) GetVirtualMetacontent(image);
6257     if (blob != (void *) NULL)
6258       goto PerlEnd;
6259 
6260   PerlException:
6261     InheritPerlException(exception,perl_exception);
6262     exception=DestroyExceptionInfo(exception);
6263     SvREFCNT_dec(perl_exception);  /* throw away all errors */
6264 
6265   PerlEnd:
6266     RETVAL = blob;
6267   }
6268   OUTPUT:
6269     RETVAL
6270 
6271 #
6272 ###############################################################################
6273 #                                                                             #
6274 #                                                                             #
6275 #                                                                             #
6276 #   H i s t o g r a m                                                         #
6277 #                                                                             #
6278 #                                                                             #
6279 #                                                                             #
6280 ###############################################################################
6281 #
6282 #
6283 void
Histogram(ref,...)6284 Histogram(ref,...)
6285   Image::Magick ref=NO_INIT
6286   ALIAS:
6287     HistogramImage = 1
6288     histogram      = 2
6289     histogramimage = 3
6290   PPCODE:
6291   {
6292     AV
6293       *av;
6294 
6295     char
6296       message[MagickPathExtent];
6297 
6298     PixelInfo
6299       *histogram;
6300 
6301     ExceptionInfo
6302       *exception;
6303 
6304     Image
6305       *image;
6306 
6307     register ssize_t
6308       i;
6309 
6310     ssize_t
6311       count;
6312 
6313     struct PackageInfo
6314       *info;
6315 
6316     SV
6317       *perl_exception,
6318       *reference;
6319 
6320     size_t
6321       number_colors;
6322 
6323     PERL_UNUSED_VAR(ref);
6324     PERL_UNUSED_VAR(ix);
6325     exception=AcquireExceptionInfo();
6326     perl_exception=newSVpv("",0);
6327     av=NULL;
6328     if (sv_isobject(ST(0)) == 0)
6329       {
6330         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6331           PackageName);
6332         goto PerlException;
6333       }
6334     reference=SvRV(ST(0));
6335     av=newAV();
6336     SvREFCNT_dec(av);
6337     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6338     if (image == (Image *) NULL)
6339       {
6340         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6341           PackageName);
6342         goto PerlException;
6343       }
6344     count=0;
6345     for ( ; image; image=image->next)
6346     {
6347       histogram=GetImageHistogram(image,&number_colors,exception);
6348       if (histogram == (PixelInfo *) NULL)
6349         continue;
6350       count+=(ssize_t) number_colors;
6351       EXTEND(sp,6*count);
6352       for (i=0; i < (ssize_t) number_colors; i++)
6353       {
6354         (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
6355           histogram[i].red);
6356         PUSHs(sv_2mortal(newSVpv(message,0)));
6357         (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
6358           histogram[i].green);
6359         PUSHs(sv_2mortal(newSVpv(message,0)));
6360         (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
6361           histogram[i].blue);
6362         PUSHs(sv_2mortal(newSVpv(message,0)));
6363         if (image->colorspace == CMYKColorspace)
6364           {
6365             (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
6366               histogram[i].black);
6367             PUSHs(sv_2mortal(newSVpv(message,0)));
6368           }
6369         (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
6370           histogram[i].alpha);
6371         PUSHs(sv_2mortal(newSVpv(message,0)));
6372         (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
6373           histogram[i].count);
6374         PUSHs(sv_2mortal(newSVpv(message,0)));
6375       }
6376       histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6377     }
6378 
6379   PerlException:
6380     InheritPerlException(exception,perl_exception);
6381     exception=DestroyExceptionInfo(exception);
6382     SvREFCNT_dec(perl_exception);
6383   }
6384 
6385 #
6386 ###############################################################################
6387 #                                                                             #
6388 #                                                                             #
6389 #                                                                             #
6390 #   G e t P i x e l                                                           #
6391 #                                                                             #
6392 #                                                                             #
6393 #                                                                             #
6394 ###############################################################################
6395 #
6396 #
6397 void
GetPixel(ref,...)6398 GetPixel(ref,...)
6399   Image::Magick ref=NO_INIT
6400   ALIAS:
6401     getpixel = 1
6402     getPixel = 2
6403   PPCODE:
6404   {
6405     AV
6406       *av;
6407 
6408     char
6409       *attribute;
6410 
6411     ExceptionInfo
6412       *exception;
6413 
6414     Image
6415       *image;
6416 
6417     MagickBooleanType
6418       normalize;
6419 
6420     RectangleInfo
6421       region;
6422 
6423     register const Quantum
6424       *p;
6425 
6426     register ssize_t
6427       i;
6428 
6429     ssize_t
6430       option;
6431 
6432     struct PackageInfo
6433       *info;
6434 
6435     SV
6436       *perl_exception,
6437       *reference;  /* reference is the SV* of ref=SvIV(reference) */
6438 
6439     PERL_UNUSED_VAR(ref);
6440     PERL_UNUSED_VAR(ix);
6441     exception=AcquireExceptionInfo();
6442     perl_exception=newSVpv("",0);
6443     reference=SvRV(ST(0));
6444     av=(AV *) reference;
6445     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6446       exception);
6447     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6448     if (image == (Image *) NULL)
6449       {
6450         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6451           PackageName);
6452         goto PerlException;
6453       }
6454     normalize=MagickTrue;
6455     region.x=0;
6456     region.y=0;
6457     region.width=image->columns;
6458     region.height=1;
6459     if (items == 1)
6460       (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6461     for (i=2; i < items; i+=2)
6462     {
6463       attribute=(char *) SvPV(ST(i-1),na);
6464       switch (*attribute)
6465       {
6466         case 'C':
6467         case 'c':
6468         {
6469           if (LocaleCompare(attribute,"channel") == 0)
6470             {
6471               ssize_t
6472                 option;
6473 
6474               option=ParseChannelOption(SvPV(ST(i),na));
6475               if (option < 0)
6476                 {
6477                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
6478                     SvPV(ST(i),na));
6479                   return;
6480                 }
6481               (void) SetPixelChannelMask(image,(ChannelType) option);
6482               break;
6483             }
6484           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6485             attribute);
6486           break;
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 'N':
6501         case 'n':
6502         {
6503           if (LocaleCompare(attribute,"normalize") == 0)
6504             {
6505               option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6506                 SvPV(ST(i),na));
6507               if (option < 0)
6508                 {
6509                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
6510                     SvPV(ST(i),na));
6511                   break;
6512                 }
6513              normalize=option != 0 ? MagickTrue : MagickFalse;
6514              break;
6515             }
6516           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6517             attribute);
6518           break;
6519         }
6520         case 'x':
6521         case 'X':
6522         {
6523           if (LocaleCompare(attribute,"x") == 0)
6524             {
6525               region.x=SvIV(ST(i));
6526               break;
6527             }
6528           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6529             attribute);
6530           break;
6531         }
6532         case 'y':
6533         case 'Y':
6534         {
6535           if (LocaleCompare(attribute,"y") == 0)
6536             {
6537               region.y=SvIV(ST(i));
6538               break;
6539             }
6540           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6541             attribute);
6542           break;
6543         }
6544         default:
6545         {
6546           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6547             attribute);
6548           break;
6549         }
6550       }
6551     }
6552     p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6553     if (p == (const Quantum *) NULL)
6554       PUSHs(&sv_undef);
6555     else
6556       {
6557         double
6558           scale;
6559 
6560         scale=1.0;
6561         if (normalize != MagickFalse)
6562           scale=1.0/QuantumRange;
6563         if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6564           PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6565         if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6566           PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6567         if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6568           PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6569         if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6570             (image->colorspace == CMYKColorspace))
6571           PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6572         if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6573           PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6574       }
6575 
6576   PerlException:
6577     InheritPerlException(exception,perl_exception);
6578     exception=DestroyExceptionInfo(exception);
6579     SvREFCNT_dec(perl_exception);
6580   }
6581 
6582 #
6583 ###############################################################################
6584 #                                                                             #
6585 #                                                                             #
6586 #                                                                             #
6587 #   G e t P i x e l s                                                         #
6588 #                                                                             #
6589 #                                                                             #
6590 #                                                                             #
6591 ###############################################################################
6592 #
6593 #
6594 void
GetPixels(ref,...)6595 GetPixels(ref,...)
6596   Image::Magick ref=NO_INIT
6597   ALIAS:
6598     getpixels = 1
6599     getPixels = 2
6600   PPCODE:
6601   {
6602     AV
6603       *av;
6604 
6605     char
6606       *attribute;
6607 
6608     const char
6609       *map;
6610 
6611     ExceptionInfo
6612       *exception;
6613 
6614     Image
6615       *image;
6616 
6617     MagickBooleanType
6618       normalize,
6619       status;
6620 
6621     RectangleInfo
6622       region;
6623 
6624     register ssize_t
6625       i;
6626 
6627     ssize_t
6628       option;
6629 
6630     struct PackageInfo
6631       *info;
6632 
6633     SV
6634       *perl_exception,
6635       *reference;  /* reference is the SV* of ref=SvIV(reference) */
6636 
6637     PERL_UNUSED_VAR(ref);
6638     PERL_UNUSED_VAR(ix);
6639     exception=AcquireExceptionInfo();
6640     perl_exception=newSVpv("",0);
6641     reference=SvRV(ST(0));
6642     av=(AV *) reference;
6643     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6644       exception);
6645     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6646     if (image == (Image *) NULL)
6647       {
6648         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6649           PackageName);
6650         goto PerlException;
6651       }
6652     map="RGB";
6653     if (image->alpha_trait != UndefinedPixelTrait)
6654       map="RGBA";
6655     if (image->colorspace == CMYKColorspace)
6656       {
6657         map="CMYK";
6658         if (image->alpha_trait != UndefinedPixelTrait)
6659           map="CMYKA";
6660       }
6661     normalize=MagickFalse;
6662     region.x=0;
6663     region.y=0;
6664     region.width=image->columns;
6665     region.height=1;
6666     if (items == 1)
6667       (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6668     for (i=2; i < items; i+=2)
6669     {
6670       attribute=(char *) SvPV(ST(i-1),na);
6671       switch (*attribute)
6672       {
6673         case 'g':
6674         case 'G':
6675         {
6676           if (LocaleCompare(attribute,"geometry") == 0)
6677             {
6678               (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6679               break;
6680             }
6681           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6682             attribute);
6683           break;
6684         }
6685         case 'H':
6686         case 'h':
6687         {
6688           if (LocaleCompare(attribute,"height") == 0)
6689             {
6690               region.height=SvIV(ST(i));
6691               break;
6692             }
6693           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6694             attribute);
6695           break;
6696         }
6697         case 'M':
6698         case 'm':
6699         {
6700           if (LocaleCompare(attribute,"map") == 0)
6701             {
6702               map=SvPV(ST(i),na);
6703               break;
6704             }
6705           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6706             attribute);
6707           break;
6708         }
6709         case 'N':
6710         case 'n':
6711         {
6712           if (LocaleCompare(attribute,"normalize") == 0)
6713             {
6714               option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6715                 SvPV(ST(i),na));
6716               if (option < 0)
6717                 {
6718                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
6719                     SvPV(ST(i),na));
6720                   break;
6721                 }
6722              normalize=option != 0 ? MagickTrue : MagickFalse;
6723              break;
6724             }
6725           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6726             attribute);
6727           break;
6728         }
6729         case 'W':
6730         case 'w':
6731         {
6732           if (LocaleCompare(attribute,"width") == 0)
6733             {
6734               region.width=SvIV(ST(i));
6735               break;
6736             }
6737           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6738             attribute);
6739           break;
6740         }
6741         case 'x':
6742         case 'X':
6743         {
6744           if (LocaleCompare(attribute,"x") == 0)
6745             {
6746               region.x=SvIV(ST(i));
6747               break;
6748             }
6749           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6750             attribute);
6751           break;
6752         }
6753         case 'y':
6754         case 'Y':
6755         {
6756           if (LocaleCompare(attribute,"y") == 0)
6757             {
6758               region.y=SvIV(ST(i));
6759               break;
6760             }
6761           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6762             attribute);
6763           break;
6764         }
6765         default:
6766         {
6767           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6768             attribute);
6769           break;
6770         }
6771       }
6772     }
6773     if (normalize != MagickFalse)
6774       {
6775         float
6776           *pixels;
6777 
6778         pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6779           region.height*sizeof(*pixels));
6780         if (pixels == (float *) NULL)
6781           {
6782             ThrowPerlException(exception,ResourceLimitError,
6783               "MemoryAllocationFailed",PackageName);
6784             goto PerlException;
6785           }
6786         status=ExportImagePixels(image,region.x,region.y,region.width,
6787           region.height,map,FloatPixel,pixels,exception);
6788         if (status == MagickFalse)
6789           PUSHs(&sv_undef);
6790         else
6791           {
6792             EXTEND(sp,strlen(map)*region.width*region.height);
6793             for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6794               PUSHs(sv_2mortal(newSVnv(pixels[i])));
6795           }
6796         pixels=(float *) RelinquishMagickMemory(pixels);
6797       }
6798     else
6799       {
6800         Quantum
6801           *pixels;
6802 
6803         pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6804           region.height*sizeof(*pixels));
6805         if (pixels == (Quantum *) NULL)
6806           {
6807             ThrowPerlException(exception,ResourceLimitError,
6808               "MemoryAllocationFailed",PackageName);
6809             goto PerlException;
6810           }
6811         status=ExportImagePixels(image,region.x,region.y,region.width,
6812           region.height,map,QuantumPixel,pixels,exception);
6813         if (status == MagickFalse)
6814           PUSHs(&sv_undef);
6815         else
6816           {
6817             EXTEND(sp,strlen(map)*region.width*region.height);
6818             for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6819               PUSHs(sv_2mortal(newSViv(pixels[i])));
6820           }
6821         pixels=(Quantum *) RelinquishMagickMemory(pixels);
6822       }
6823 
6824   PerlException:
6825     InheritPerlException(exception,perl_exception);
6826     exception=DestroyExceptionInfo(exception);
6827     SvREFCNT_dec(perl_exception);
6828   }
6829 
6830 #
6831 ###############################################################################
6832 #                                                                             #
6833 #                                                                             #
6834 #                                                                             #
6835 #   I m a g e T o B l o b                                                     #
6836 #                                                                             #
6837 #                                                                             #
6838 #                                                                             #
6839 ###############################################################################
6840 #
6841 #
6842 void
ImageToBlob(ref,...)6843 ImageToBlob(ref,...)
6844   Image::Magick ref=NO_INIT
6845   ALIAS:
6846     ImageToBlob  = 1
6847     imagetoblob  = 2
6848     toblob       = 3
6849     blob         = 4
6850   PPCODE:
6851   {
6852     char
6853       filename[MagickPathExtent];
6854 
6855     ExceptionInfo
6856       *exception;
6857 
6858     Image
6859       *image,
6860       *next;
6861 
6862     register ssize_t
6863       i;
6864 
6865     struct PackageInfo
6866       *info,
6867       *package_info;
6868 
6869     size_t
6870       length;
6871 
6872     ssize_t
6873       scene;
6874 
6875     SV
6876       *perl_exception,
6877       *reference;
6878 
6879     void
6880       *blob;
6881 
6882     PERL_UNUSED_VAR(ref);
6883     PERL_UNUSED_VAR(ix);
6884     exception=AcquireExceptionInfo();
6885     perl_exception=newSVpv("",0);
6886     package_info=(struct PackageInfo *) NULL;
6887     if (sv_isobject(ST(0)) == 0)
6888       {
6889         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6890           PackageName);
6891         goto PerlException;
6892       }
6893     reference=SvRV(ST(0));
6894     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6895     if (image == (Image *) NULL)
6896       {
6897         ThrowPerlException(exception,OptionError,"NoImagesDefined",
6898           PackageName);
6899         goto PerlException;
6900       }
6901     package_info=ClonePackageInfo(info,exception);
6902     for (i=2; i < items; i+=2)
6903       SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6904     (void) CopyMagickString(filename,package_info->image_info->filename,
6905       MagickPathExtent);
6906     scene=0;
6907     for (next=image; next; next=next->next)
6908     {
6909       (void) CopyMagickString(next->filename,filename,MagickPathExtent);
6910       next->scene=scene++;
6911     }
6912     SetImageInfo(package_info->image_info,(unsigned int)
6913       GetImageListLength(image),exception);
6914     EXTEND(sp,(ssize_t) GetImageListLength(image));
6915     for ( ; image; image=image->next)
6916     {
6917       length=0;
6918       blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6919       if (blob != (char *) NULL)
6920         {
6921           PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6922           blob=(unsigned char *) RelinquishMagickMemory(blob);
6923         }
6924       if (package_info->image_info->adjoin)
6925         break;
6926     }
6927 
6928   PerlException:
6929     if (package_info != (struct PackageInfo *) NULL)
6930       DestroyPackageInfo(package_info);
6931     InheritPerlException(exception,perl_exception);
6932     exception=DestroyExceptionInfo(exception);
6933     SvREFCNT_dec(perl_exception);  /* throw away all errors */
6934   }
6935 
6936 #
6937 ###############################################################################
6938 #                                                                             #
6939 #                                                                             #
6940 #                                                                             #
6941 #   L a y e r s                                                               #
6942 #                                                                             #
6943 #                                                                             #
6944 #                                                                             #
6945 ###############################################################################
6946 #
6947 #
6948 void
Layers(ref,...)6949 Layers(ref,...)
6950   Image::Magick ref=NO_INIT
6951   ALIAS:
6952     Layers                = 1
6953     layers           = 2
6954     OptimizeImageLayers   = 3
6955     optimizelayers        = 4
6956     optimizeimagelayers   = 5
6957   PPCODE:
6958   {
6959     AV
6960       *av;
6961 
6962     char
6963       *attribute;
6964 
6965     CompositeOperator
6966       compose;
6967 
6968     ExceptionInfo
6969       *exception;
6970 
6971     HV
6972       *hv;
6973 
6974     Image
6975       *image,
6976       *layers;
6977 
6978     LayerMethod
6979       method;
6980 
6981     register ssize_t
6982       i;
6983 
6984     ssize_t
6985       option,
6986       sp;
6987 
6988     struct PackageInfo
6989       *info;
6990 
6991     SV
6992       *av_reference,
6993       *perl_exception,
6994       *reference,
6995       *rv,
6996       *sv;
6997 
6998     PERL_UNUSED_VAR(ref);
6999     PERL_UNUSED_VAR(ix);
7000     exception=AcquireExceptionInfo();
7001     perl_exception=newSVpv("",0);
7002     sv=NULL;
7003     if (sv_isobject(ST(0)) == 0)
7004       {
7005         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7006           PackageName);
7007         goto PerlException;
7008       }
7009     reference=SvRV(ST(0));
7010     hv=SvSTASH(reference);
7011     av=newAV();
7012     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
7013     SvREFCNT_dec(av);
7014     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
7015     if (image == (Image *) NULL)
7016       {
7017         ThrowPerlException(exception,OptionError,"NoImagesDefined",
7018           PackageName);
7019         goto PerlException;
7020       }
7021     compose=image->compose;
7022     method=OptimizeLayer;
7023     for (i=2; i < items; i+=2)
7024     {
7025       attribute=(char *) SvPV(ST(i-1),na);
7026       switch (*attribute)
7027       {
7028         case 'C':
7029         case 'c':
7030         {
7031           if (LocaleCompare(attribute,"compose") == 0)
7032             {
7033               sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
7034                 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
7035               if (sp < 0)
7036                 {
7037                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
7038                     SvPV(ST(i),na));
7039                   break;
7040                 }
7041               compose=(CompositeOperator) sp;
7042               break;
7043             }
7044           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7045             attribute);
7046           break;
7047         }
7048         case 'M':
7049         case 'm':
7050         {
7051           if (LocaleCompare(attribute,"method") == 0)
7052             {
7053               option=ParseCommandOption(MagickLayerOptions,MagickFalse,
7054                 SvPV(ST(i),na));
7055               if (option < 0)
7056                 {
7057                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
7058                     SvPV(ST(i),na));
7059                   break;
7060                 }
7061               method=(LayerMethod) option;
7062               break;
7063             }
7064           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7065             attribute);
7066           break;
7067         }
7068         default:
7069         {
7070           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7071             attribute);
7072           break;
7073         }
7074       }
7075     }
7076     layers=(Image *) NULL;
7077     switch (method)
7078     {
7079       case CompareAnyLayer:
7080       case CompareClearLayer:
7081       case CompareOverlayLayer:
7082       default:
7083       {
7084         layers=CompareImagesLayers(image,method,exception);
7085         break;
7086       }
7087       case MergeLayer:
7088       case FlattenLayer:
7089       case MosaicLayer:
7090       {
7091         layers=MergeImageLayers(image,method,exception);
7092         break;
7093       }
7094       case DisposeLayer:
7095       {
7096         layers=DisposeImages(image,exception);
7097         break;
7098       }
7099       case OptimizeImageLayer:
7100       {
7101         layers=OptimizeImageLayers(image,exception);
7102         break;
7103       }
7104       case OptimizePlusLayer:
7105       {
7106         layers=OptimizePlusImageLayers(image,exception);
7107         break;
7108       }
7109       case OptimizeTransLayer:
7110       {
7111         OptimizeImageTransparency(image,exception);
7112         break;
7113       }
7114       case RemoveDupsLayer:
7115       {
7116         RemoveDuplicateLayers(&image,exception);
7117         break;
7118       }
7119       case RemoveZeroLayer:
7120       {
7121         RemoveZeroDelayLayers(&image,exception);
7122         break;
7123       }
7124       case OptimizeLayer:
7125       {
7126         QuantizeInfo
7127           *quantize_info;
7128 
7129         /*
7130           General Purpose, GIF Animation Optimizer.
7131         */
7132         layers=CoalesceImages(image,exception);
7133         if (layers == (Image *) NULL)
7134           break;
7135         image=layers;
7136         layers=OptimizeImageLayers(image,exception);
7137         if (layers == (Image *) NULL)
7138           break;
7139         image=DestroyImageList(image);
7140         image=layers;
7141         layers=(Image *) NULL;
7142         OptimizeImageTransparency(image,exception);
7143         quantize_info=AcquireQuantizeInfo(info->image_info);
7144         (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
7145         quantize_info=DestroyQuantizeInfo(quantize_info);
7146         break;
7147       }
7148       case CompositeLayer:
7149       {
7150         Image
7151           *source;
7152 
7153         RectangleInfo
7154           geometry;
7155 
7156         /*
7157           Split image sequence at the first 'NULL:' image.
7158         */
7159         source=image;
7160         while (source != (Image *) NULL)
7161         {
7162           source=GetNextImageInList(source);
7163           if ((source != (Image *) NULL) &&
7164               (LocaleCompare(source->magick,"NULL") == 0))
7165             break;
7166         }
7167         if (source != (Image *) NULL)
7168           {
7169             if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7170                 (GetNextImageInList(source) == (Image *) NULL))
7171               source=(Image *) NULL;
7172             else
7173               {
7174                 /*
7175                   Separate the two lists, junk the null: image.
7176                 */
7177                 source=SplitImageList(source->previous);
7178                 DeleteImageFromList(&source);
7179               }
7180           }
7181         if (source == (Image *) NULL)
7182           {
7183             (void) ThrowMagickException(exception,GetMagickModule(),
7184               OptionError,"MissingNullSeparator","layers Composite");
7185             break;
7186           }
7187         /*
7188           Adjust offset with gravity and virtual canvas.
7189         */
7190         SetGeometry(image,&geometry);
7191         (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7192         geometry.width=source->page.width != 0 ? source->page.width :
7193           source->columns;
7194         geometry.height=source->page.height != 0 ? source->page.height :
7195           source->rows;
7196         GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7197           image->columns,image->page.height != 0 ? image->page.height :
7198           image->rows,image->gravity,&geometry);
7199         CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7200         source=DestroyImageList(source);
7201         break;
7202       }
7203     }
7204     if (layers != (Image *) NULL)
7205       image=layers;
7206     else
7207       image=CloneImage(image,0,0,MagickTrue,exception);
7208     if (image == (Image *) NULL)
7209       goto PerlException;
7210     for ( ; image; image=image->next)
7211     {
7212       AddImageToRegistry(sv,image);
7213       rv=newRV(sv);
7214       av_push(av,sv_bless(rv,hv));
7215       SvREFCNT_dec(sv);
7216     }
7217     exception=DestroyExceptionInfo(exception);
7218     ST(0)=av_reference;
7219     SvREFCNT_dec(perl_exception);
7220     XSRETURN(1);
7221 
7222   PerlException:
7223     InheritPerlException(exception,perl_exception);
7224     exception=DestroyExceptionInfo(exception);
7225     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7226     SvPOK_on(perl_exception);
7227     ST(0)=sv_2mortal(perl_exception);
7228     XSRETURN(1);
7229   }
7230 
7231 #
7232 ###############################################################################
7233 #                                                                             #
7234 #                                                                             #
7235 #                                                                             #
7236 #   M a g i c k T o M i m e                                                   #
7237 #                                                                             #
7238 #                                                                             #
7239 #                                                                             #
7240 ###############################################################################
7241 #
7242 #
7243 SV *
MagickToMime(ref,name)7244 MagickToMime(ref,name)
7245   Image::Magick ref=NO_INIT
7246   char *name
7247   ALIAS:
7248     magicktomime = 1
7249   CODE:
7250   {
7251     char
7252       *mime;
7253 
7254     PERL_UNUSED_VAR(ref);
7255     PERL_UNUSED_VAR(ix);
7256     mime=MagickToMime(name);
7257     RETVAL=newSVpv(mime,0);
7258     mime=(char *) RelinquishMagickMemory(mime);
7259   }
7260   OUTPUT:
7261     RETVAL
7262 
7263 #
7264 ###############################################################################
7265 #                                                                             #
7266 #                                                                             #
7267 #                                                                             #
7268 #   M o g r i f y                                                             #
7269 #                                                                             #
7270 #                                                                             #
7271 #                                                                             #
7272 ###############################################################################
7273 #
7274 #
7275 void
Mogrify(ref,...)7276 Mogrify(ref,...)
7277   Image::Magick ref=NO_INIT
7278   ALIAS:
7279     Comment            =   1
7280     CommentImage       =   2
7281     Label              =   3
7282     LabelImage         =   4
7283     AddNoise           =   5
7284     AddNoiseImage      =   6
7285     Colorize           =   7
7286     ColorizeImage      =   8
7287     Border             =   9
7288     BorderImage        =  10
7289     Blur               =  11
7290     BlurImage          =  12
7291     Chop               =  13
7292     ChopImage          =  14
7293     Crop               =  15
7294     CropImage          =  16
7295     Despeckle          =  17
7296     DespeckleImage     =  18
7297     Edge               =  19
7298     EdgeImage          =  20
7299     Emboss             =  21
7300     EmbossImage        =  22
7301     Enhance            =  23
7302     EnhanceImage       =  24
7303     Flip               =  25
7304     FlipImage          =  26
7305     Flop               =  27
7306     FlopImage          =  28
7307     Frame              =  29
7308     FrameImage         =  30
7309     Implode            =  31
7310     ImplodeImage       =  32
7311     Magnify            =  33
7312     MagnifyImage       =  34
7313     MedianFilter       =  35
7314     MedianConvolveImage  =  36
7315     Minify             =  37
7316     MinifyImage        =  38
7317     OilPaint           =  39
7318     OilPaintImage      =  40
7319     ReduceNoise        =  41
7320     ReduceNoiseImage   =  42
7321     Roll               =  43
7322     RollImage          =  44
7323     Rotate             =  45
7324     RotateImage        =  46
7325     Sample             =  47
7326     SampleImage        =  48
7327     Scale              =  49
7328     ScaleImage         =  50
7329     Shade              =  51
7330     ShadeImage         =  52
7331     Sharpen            =  53
7332     SharpenImage       =  54
7333     Shear              =  55
7334     ShearImage         =  56
7335     Spread             =  57
7336     SpreadImage        =  58
7337     Swirl              =  59
7338     SwirlImage         =  60
7339     Resize             =  61
7340     ResizeImage        =  62
7341     Zoom               =  63
7342     ZoomImage          =  64
7343     Annotate           =  65
7344     AnnotateImage      =  66
7345     ColorFloodfill     =  67
7346     ColorFloodfillImage=  68
7347     Composite          =  69
7348     CompositeImage     =  70
7349     Contrast           =  71
7350     ContrastImage      =  72
7351     CycleColormap      =  73
7352     CycleColormapImage =  74
7353     Draw               =  75
7354     DrawImage          =  76
7355     Equalize           =  77
7356     EqualizeImage      =  78
7357     Gamma              =  79
7358     GammaImage         =  80
7359     Map                =  81
7360     MapImage           =  82
7361     MatteFloodfill     =  83
7362     MatteFloodfillImage=  84
7363     Modulate           =  85
7364     ModulateImage      =  86
7365     Negate             =  87
7366     NegateImage        =  88
7367     Normalize          =  89
7368     NormalizeImage     =  90
7369     NumberColors       =  91
7370     NumberColorsImage  =  92
7371     Opaque             =  93
7372     OpaqueImage        =  94
7373     Quantize           =  95
7374     QuantizeImage      =  96
7375     Raise              =  97
7376     RaiseImage         =  98
7377     Segment            =  99
7378     SegmentImage       = 100
7379     Signature          = 101
7380     SignatureImage     = 102
7381     Solarize           = 103
7382     SolarizeImage      = 104
7383     Sync               = 105
7384     SyncImage          = 106
7385     Texture            = 107
7386     TextureImage       = 108
7387     Evaluate           = 109
7388     EvaluateImage      = 110
7389     Transparent        = 111
7390     TransparentImage   = 112
7391     Threshold          = 113
7392     ThresholdImage     = 114
7393     Charcoal           = 115
7394     CharcoalImage      = 116
7395     Trim               = 117
7396     TrimImage          = 118
7397     Wave               = 119
7398     WaveImage          = 120
7399     Separate           = 121
7400     SeparateImage      = 122
7401     Stereo             = 125
7402     StereoImage        = 126
7403     Stegano            = 127
7404     SteganoImage       = 128
7405     Deconstruct        = 129
7406     DeconstructImage   = 130
7407     GaussianBlur       = 131
7408     GaussianBlurImage  = 132
7409     Convolve           = 133
7410     ConvolveImage      = 134
7411     Profile            = 135
7412     ProfileImage       = 136
7413     UnsharpMask        = 137
7414     UnsharpMaskImage   = 138
7415     MotionBlur         = 139
7416     MotionBlurImage    = 140
7417     OrderedDither      = 141
7418     OrderedDitherImage = 142
7419     Shave              = 143
7420     ShaveImage         = 144
7421     Level              = 145
7422     LevelImage         = 146
7423     Clip               = 147
7424     ClipImage          = 148
7425     AffineTransform    = 149
7426     AffineTransformImage = 150
7427     Difference         = 151
7428     DifferenceImage    = 152
7429     AdaptiveThreshold  = 153
7430     AdaptiveThresholdImage = 154
7431     Resample           = 155
7432     ResampleImage      = 156
7433     Describe           = 157
7434     DescribeImage      = 158
7435     BlackThreshold     = 159
7436     BlackThresholdImage= 160
7437     WhiteThreshold     = 161
7438     WhiteThresholdImage= 162
7439     RotationalBlur     = 163
7440     RotationalBlurImage= 164
7441     Thumbnail          = 165
7442     ThumbnailImage     = 166
7443     Strip              = 167
7444     StripImage         = 168
7445     Tint               = 169
7446     TintImage          = 170
7447     Channel            = 171
7448     ChannelImage       = 172
7449     Splice             = 173
7450     SpliceImage        = 174
7451     Posterize          = 175
7452     PosterizeImage     = 176
7453     Shadow             = 177
7454     ShadowImage        = 178
7455     Identify           = 179
7456     IdentifyImage      = 180
7457     SepiaTone          = 181
7458     SepiaToneImage     = 182
7459     SigmoidalContrast  = 183
7460     SigmoidalContrastImage = 184
7461     Extent             = 185
7462     ExtentImage        = 186
7463     Vignette           = 187
7464     VignetteImage      = 188
7465     ContrastStretch    = 189
7466     ContrastStretchImage = 190
7467     Sans0              = 191
7468     Sans0Image         = 192
7469     Sans1              = 193
7470     Sans1Image         = 194
7471     AdaptiveSharpen    = 195
7472     AdaptiveSharpenImage = 196
7473     Transpose          = 197
7474     TransposeImage     = 198
7475     Transverse         = 199
7476     TransverseImage    = 200
7477     AutoOrient         = 201
7478     AutoOrientImage    = 202
7479     AdaptiveBlur       = 203
7480     AdaptiveBlurImage  = 204
7481     Sketch             = 205
7482     SketchImage        = 206
7483     UniqueColors       = 207
7484     UniqueColorsImage  = 208
7485     AdaptiveResize     = 209
7486     AdaptiveResizeImage= 210
7487     ClipMask           = 211
7488     ClipMaskImage      = 212
7489     LinearStretch      = 213
7490     LinearStretchImage = 214
7491     ColorMatrix        = 215
7492     ColorMatrixImage   = 216
7493     Mask               = 217
7494     MaskImage          = 218
7495     Polaroid           = 219
7496     PolaroidImage      = 220
7497     FloodfillPaint     = 221
7498     FloodfillPaintImage= 222
7499     Distort            = 223
7500     DistortImage       = 224
7501     Clut               = 225
7502     ClutImage          = 226
7503     LiquidRescale      = 227
7504     LiquidRescaleImage = 228
7505     Encipher           = 229
7506     EncipherImage      = 230
7507     Decipher           = 231
7508     DecipherImage      = 232
7509     Deskew             = 233
7510     DeskewImage        = 234
7511     Remap              = 235
7512     RemapImage         = 236
7513     SparseColor        = 237
7514     SparseColorImage   = 238
7515     Function           = 239
7516     FunctionImage      = 240
7517     SelectiveBlur      = 241
7518     SelectiveBlurImage = 242
7519     HaldClut           = 243
7520     HaldClutImage      = 244
7521     BlueShift          = 245
7522     BlueShiftImage     = 246
7523     ForwardFourierTransform  = 247
7524     ForwardFourierTransformImage = 248
7525     InverseFourierTransform = 249
7526     InverseFourierTransformImage = 250
7527     ColorDecisionList  = 251
7528     ColorDecisionListImage = 252
7529     AutoGamma          = 253
7530     AutoGammaImage     = 254
7531     AutoLevel          = 255
7532     AutoLevelImage     = 256
7533     LevelColors        = 257
7534     LevelImageColors   = 258
7535     Clamp              = 259
7536     ClampImage         = 260
7537     BrightnessContrast = 261
7538     BrightnessContrastImage = 262
7539     Morphology         = 263
7540     MorphologyImage    = 264
7541     Mode               = 265
7542     ModeImage          = 266
7543     Statistic          = 267
7544     StatisticImage     = 268
7545     Perceptible        = 269
7546     PerceptibleImage   = 270
7547     Poly               = 271
7548     PolyImage          = 272
7549     Grayscale          = 273
7550     GrayscaleImage     = 274
7551     CannyEdge          = 275
7552     CannyEdgeImage     = 276
7553     HoughLine          = 277
7554     HoughLineImage     = 278
7555     MeanShift          = 279
7556     MeanShiftImage     = 280
7557     Kuwahara           = 281
7558     KuwaharaImage      = 282
7559     ConnectedComponent = 283
7560     ConnectedComponentImage = 284
7561     CopyPixels         = 285
7562     CopyImagePixels    = 286
7563     Color              = 287
7564     ColorImage         = 288
7565     WaveletDenoise     = 289
7566     WaveletDenoiseImage= 290
7567     MogrifyRegion      = 666
7568   PPCODE:
7569   {
7570     AffineMatrix
7571       affine,
7572       current;
7573 
7574     char
7575       attribute_flag[MaxArguments],
7576       message[MagickPathExtent];
7577 
7578     ChannelType
7579       channel,
7580       channel_mask;
7581 
7582     CompositeOperator
7583       compose;
7584 
7585     const char
7586       *attribute,
7587       *value;
7588 
7589     double
7590       angle;
7591 
7592     ExceptionInfo
7593       *exception;
7594 
7595     GeometryInfo
7596       geometry_info;
7597 
7598     Image
7599       *image,
7600       *next,
7601       *region_image;
7602 
7603     MagickBooleanType
7604       status;
7605 
7606     MagickStatusType
7607       flags;
7608 
7609     PixelInfo
7610       fill_color;
7611 
7612     RectangleInfo
7613       geometry,
7614       region_info;
7615 
7616     register ssize_t
7617       i;
7618 
7619     ssize_t
7620       base,
7621       j,
7622       number_images;
7623 
7624     struct Methods
7625       *rp;
7626 
7627     struct PackageInfo
7628       *info;
7629 
7630     SV
7631       *perl_exception,
7632       **pv,
7633       *reference,
7634       **reference_vector;
7635 
7636     struct ArgumentList
7637       argument_list[MaxArguments];
7638 
7639     PERL_UNUSED_VAR(ref);
7640     PERL_UNUSED_VAR(ix);
7641     exception=AcquireExceptionInfo();
7642     perl_exception=newSVpv("",0);
7643     reference_vector=NULL;
7644     region_image=NULL;
7645     number_images=0;
7646     base=2;
7647     if (sv_isobject(ST(0)) == 0)
7648       {
7649         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7650           PackageName);
7651         goto PerlException;
7652       }
7653     reference=SvRV(ST(0));
7654     region_info.width=0;
7655     region_info.height=0;
7656     region_info.x=0;
7657     region_info.y=0;
7658     region_image=(Image *) NULL;
7659     image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7660     if (ix && (ix != 666))
7661       {
7662         /*
7663           Called as Method(...)
7664         */
7665         ix=(ix+1)/2;
7666         rp=(&Methods[ix-1]);
7667         attribute=rp->name;
7668       }
7669     else
7670       {
7671         /*
7672           Called as Mogrify("Method",...)
7673         */
7674         attribute=(char *) SvPV(ST(1),na);
7675         if (ix)
7676           {
7677             flags=ParseGravityGeometry(image,attribute,&region_info,exception);
7678             attribute=(char *) SvPV(ST(2),na);
7679             base++;
7680           }
7681         for (rp=Methods; ; rp++)
7682         {
7683           if (rp >= EndOf(Methods))
7684             {
7685               ThrowPerlException(exception,OptionError,
7686                 "UnrecognizedPerlMagickMethod",attribute);
7687               goto PerlException;
7688             }
7689           if (strEQcase(attribute,rp->name))
7690             break;
7691         }
7692         ix=rp-Methods+1;
7693         base++;
7694       }
7695     if (image == (Image *) NULL)
7696       {
7697         ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7698         goto PerlException;
7699       }
7700     Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7701     Zero(&attribute_flag,NumberOf(attribute_flag),char);
7702     for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7703     {
7704       Arguments
7705         *pp,
7706         *qq;
7707 
7708       ssize_t
7709         ssize_test;
7710 
7711       struct ArgumentList
7712         *al;
7713 
7714       SV
7715         *sv;
7716 
7717       sv=NULL;
7718       ssize_test=0;
7719       pp=(Arguments *) NULL;
7720       qq=rp->arguments;
7721       if (i == items)
7722         {
7723           pp=rp->arguments,
7724           sv=ST(i-1);
7725         }
7726       else
7727         for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7728         {
7729           if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7730             break;
7731           if (strEQcase(attribute,qq->method) > ssize_test)
7732             {
7733               pp=qq;
7734               ssize_test=strEQcase(attribute,qq->method);
7735             }
7736         }
7737       if (pp == (Arguments *) NULL)
7738         {
7739           ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7740             attribute);
7741           goto continue_outer_loop;
7742         }
7743       al=(&argument_list[pp-rp->arguments]);
7744       switch (pp->type)
7745       {
7746         case ArrayReference:
7747         {
7748           if (SvTYPE(sv) != SVt_RV)
7749             {
7750               (void) FormatLocaleString(message,MagickPathExtent,
7751                 "invalid %.60s value",pp->method);
7752               ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7753               goto continue_outer_loop;
7754             }
7755           al->array_reference=SvRV(sv);
7756           break;
7757         }
7758         case RealReference:
7759         {
7760           al->real_reference=SvNV(sv);
7761           break;
7762         }
7763         case FileReference:
7764         {
7765           al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7766           break;
7767         }
7768         case ImageReference:
7769         {
7770           if (!sv_isobject(sv) ||
7771               !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7772                 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7773             {
7774               ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7775                 PackageName);
7776               goto PerlException;
7777             }
7778           break;
7779         }
7780         case IntegerReference:
7781         {
7782           al->integer_reference=SvIV(sv);
7783           break;
7784         }
7785         case StringReference:
7786         {
7787           al->string_reference=(char *) SvPV(sv,al->length);
7788           if (sv_isobject(sv))
7789             al->image_reference=SetupList(aTHX_ SvRV(sv),
7790               (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7791           break;
7792         }
7793         default:
7794         {
7795           /*
7796             Is a string; look up name.
7797           */
7798           if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7799             {
7800               al->string_reference=(char *) SvPV(sv,al->length);
7801               al->integer_reference=(-1);
7802               break;
7803             }
7804           al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7805             MagickFalse,SvPV(sv,na));
7806           if (pp->type == MagickChannelOptions)
7807             al->integer_reference=ParseChannelOption(SvPV(sv,na));
7808           if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7809             {
7810               (void) FormatLocaleString(message,MagickPathExtent,
7811                 "invalid %.60s value",pp->method);
7812               ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7813               goto continue_outer_loop;
7814             }
7815           break;
7816         }
7817       }
7818       attribute_flag[pp-rp->arguments]++;
7819       continue_outer_loop: ;
7820     }
7821     (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7822     pv=reference_vector;
7823     SetGeometryInfo(&geometry_info);
7824     channel=DefaultChannels;
7825     for (next=image; next; next=next->next)
7826     {
7827       image=next;
7828       SetGeometry(image,&geometry);
7829       if ((region_info.width*region_info.height) != 0)
7830         {
7831           region_image=image;
7832           image=CropImage(image,&region_info,exception);
7833         }
7834       switch (ix)
7835       {
7836         default:
7837         {
7838           (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double) ix);
7839           ThrowPerlException(exception,OptionError,
7840             "UnrecognizedPerlMagickMethod",message);
7841           goto PerlException;
7842         }
7843         case 1:  /* Comment */
7844         {
7845           if (attribute_flag[0] == 0)
7846             argument_list[0].string_reference=(char *) NULL;
7847           (void) SetImageProperty(image,"comment",InterpretImageProperties(
7848             info ? info->image_info : (ImageInfo *) NULL,image,
7849             argument_list[0].string_reference,exception),exception);
7850           break;
7851         }
7852         case 2:  /* Label */
7853         {
7854           if (attribute_flag[0] == 0)
7855             argument_list[0].string_reference=(char *) NULL;
7856           (void) SetImageProperty(image,"label",InterpretImageProperties(
7857             info ? info->image_info : (ImageInfo *) NULL,image,
7858             argument_list[0].string_reference,exception),exception);
7859           break;
7860         }
7861         case 3:  /* AddNoise */
7862         {
7863           double
7864             attenuate;
7865 
7866           if (attribute_flag[0] == 0)
7867             argument_list[0].integer_reference=UniformNoise;
7868           attenuate=1.0;
7869           if (attribute_flag[1] != 0)
7870             attenuate=argument_list[1].real_reference;
7871           if (attribute_flag[2] != 0)
7872             channel=(ChannelType) argument_list[2].integer_reference;
7873           channel_mask=SetImageChannelMask(image,channel);
7874           image=AddNoiseImage(image,(NoiseType)
7875             argument_list[0].integer_reference,attenuate,exception);
7876           if (image != (Image *) NULL)
7877             (void) SetImageChannelMask(image,channel_mask);
7878           break;
7879         }
7880         case 4:  /* Colorize */
7881         {
7882           PixelInfo
7883             target;
7884 
7885           (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7886             0,0,&target,exception);
7887           if (attribute_flag[0] != 0)
7888             (void) QueryColorCompliance(argument_list[0].string_reference,
7889               AllCompliance,&target,exception);
7890           if (attribute_flag[1] == 0)
7891             argument_list[1].string_reference="100%";
7892           image=ColorizeImage(image,argument_list[1].string_reference,&target,
7893             exception);
7894           break;
7895         }
7896         case 5:  /* Border */
7897         {
7898           CompositeOperator
7899             compose;
7900 
7901           geometry.width=0;
7902           geometry.height=0;
7903           if (attribute_flag[0] != 0)
7904             flags=ParsePageGeometry(image,argument_list[0].string_reference,
7905               &geometry,exception);
7906           if (attribute_flag[1] != 0)
7907             geometry.width=argument_list[1].integer_reference;
7908           if (attribute_flag[2] != 0)
7909             geometry.height=argument_list[2].integer_reference;
7910           if (attribute_flag[3] != 0)
7911             QueryColorCompliance(argument_list[3].string_reference,
7912               AllCompliance,&image->border_color,exception);
7913           if (attribute_flag[4] != 0)
7914             QueryColorCompliance(argument_list[4].string_reference,
7915               AllCompliance,&image->border_color,exception);
7916           if (attribute_flag[5] != 0)
7917             QueryColorCompliance(argument_list[5].string_reference,
7918               AllCompliance,&image->border_color,exception);
7919           compose=image->compose;
7920           if (attribute_flag[6] != 0)
7921             compose=(CompositeOperator) argument_list[6].integer_reference;
7922           image=BorderImage(image,&geometry,compose,exception);
7923           break;
7924         }
7925         case 6:  /* Blur */
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=BlurImage(image,geometry_info.rho,geometry_info.sigma,
7942             exception);
7943           if (image != (Image *) NULL)
7944             (void) SetImageChannelMask(image,channel_mask);
7945           break;
7946         }
7947         case 7:  /* Chop */
7948         {
7949           if (attribute_flag[5] != 0)
7950             image->gravity=(GravityType) argument_list[5].integer_reference;
7951           if (attribute_flag[0] != 0)
7952             flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7953               &geometry,exception);
7954           if (attribute_flag[1] != 0)
7955             geometry.width=argument_list[1].integer_reference;
7956           if (attribute_flag[2] != 0)
7957             geometry.height=argument_list[2].integer_reference;
7958           if (attribute_flag[3] != 0)
7959             geometry.x=argument_list[3].integer_reference;
7960           if (attribute_flag[4] != 0)
7961             geometry.y=argument_list[4].integer_reference;
7962           image=ChopImage(image,&geometry,exception);
7963           break;
7964         }
7965         case 8:  /* Crop */
7966         {
7967           if (attribute_flag[6] != 0)
7968             image->gravity=(GravityType) argument_list[6].integer_reference;
7969           if (attribute_flag[0] != 0)
7970             flags=ParseGravityGeometry(image,argument_list[0].string_reference,
7971               &geometry,exception);
7972           if (attribute_flag[1] != 0)
7973             geometry.width=argument_list[1].integer_reference;
7974           if (attribute_flag[2] != 0)
7975             geometry.height=argument_list[2].integer_reference;
7976           if (attribute_flag[3] != 0)
7977             geometry.x=argument_list[3].integer_reference;
7978           if (attribute_flag[4] != 0)
7979             geometry.y=argument_list[4].integer_reference;
7980           if (attribute_flag[5] != 0)
7981             image->fuzz=StringToDoubleInterval(
7982               argument_list[5].string_reference,(double) QuantumRange+1.0);
7983           image=CropImage(image,&geometry,exception);
7984           break;
7985         }
7986         case 9:  /* Despeckle */
7987         {
7988           image=DespeckleImage(image,exception);
7989           break;
7990         }
7991         case 10:  /* Edge */
7992         {
7993           if (attribute_flag[0] != 0)
7994             geometry_info.rho=argument_list[0].real_reference;
7995           image=EdgeImage(image,geometry_info.rho,exception);
7996           break;
7997         }
7998         case 11:  /* Emboss */
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=1.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=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
8012             exception);
8013           break;
8014         }
8015         case 12:  /* Enhance */
8016         {
8017           image=EnhanceImage(image,exception);
8018           break;
8019         }
8020         case 13:  /* Flip */
8021         {
8022           image=FlipImage(image,exception);
8023           break;
8024         }
8025         case 14:  /* Flop */
8026         {
8027           image=FlopImage(image,exception);
8028           break;
8029         }
8030         case 15:  /* Frame */
8031         {
8032           CompositeOperator
8033             compose;
8034 
8035           FrameInfo
8036             frame_info;
8037 
8038           if (attribute_flag[0] != 0)
8039             {
8040               flags=ParsePageGeometry(image,argument_list[0].string_reference,
8041                 &geometry,exception);
8042               frame_info.width=geometry.width;
8043               frame_info.height=geometry.height;
8044               frame_info.outer_bevel=geometry.x;
8045               frame_info.inner_bevel=geometry.y;
8046             }
8047           if (attribute_flag[1] != 0)
8048             frame_info.width=argument_list[1].integer_reference;
8049           if (attribute_flag[2] != 0)
8050             frame_info.height=argument_list[2].integer_reference;
8051           if (attribute_flag[3] != 0)
8052             frame_info.inner_bevel=argument_list[3].integer_reference;
8053           if (attribute_flag[4] != 0)
8054             frame_info.outer_bevel=argument_list[4].integer_reference;
8055           if (attribute_flag[5] != 0)
8056             QueryColorCompliance(argument_list[5].string_reference,
8057               AllCompliance,&fill_color,exception);
8058           if (attribute_flag[6] != 0)
8059             QueryColorCompliance(argument_list[6].string_reference,
8060               AllCompliance,&fill_color,exception);
8061           frame_info.x=(ssize_t) frame_info.width;
8062           frame_info.y=(ssize_t) frame_info.height;
8063           frame_info.width=image->columns+2*frame_info.x;
8064           frame_info.height=image->rows+2*frame_info.y;
8065           if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
8066             image->alpha_color=fill_color;
8067           compose=image->compose;
8068           if (attribute_flag[7] != 0)
8069             compose=(CompositeOperator) argument_list[7].integer_reference;
8070           image=FrameImage(image,&frame_info,compose,exception);
8071           break;
8072         }
8073         case 16:  /* Implode */
8074         {
8075           PixelInterpolateMethod
8076             method;
8077 
8078           if (attribute_flag[0] == 0)
8079             argument_list[0].real_reference=0.5;
8080           method=UndefinedInterpolatePixel;
8081           if (attribute_flag[1] != 0)
8082             method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8083           image=ImplodeImage(image,argument_list[0].real_reference,
8084             method,exception);
8085           break;
8086         }
8087         case 17:  /* Magnify */
8088         {
8089           image=MagnifyImage(image,exception);
8090           break;
8091         }
8092         case 18:  /* MedianFilter */
8093         {
8094           if (attribute_flag[0] != 0)
8095             {
8096               flags=ParseGeometry(argument_list[0].string_reference,
8097                 &geometry_info);
8098               if ((flags & SigmaValue) == 0)
8099                 geometry_info.sigma=geometry_info.rho;
8100             }
8101           if (attribute_flag[1] != 0)
8102             geometry_info.rho=argument_list[1].real_reference;
8103           if (attribute_flag[2] != 0)
8104             geometry_info.sigma=argument_list[2].real_reference;
8105           if (attribute_flag[3] != 0)
8106             channel=(ChannelType) argument_list[3].integer_reference;
8107           channel_mask=SetImageChannelMask(image,channel);
8108           image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
8109             (size_t) geometry_info.sigma,exception);
8110           if (image != (Image *) NULL)
8111             (void) SetImageChannelMask(image,channel_mask);
8112           break;
8113         }
8114         case 19:  /* Minify */
8115         {
8116           image=MinifyImage(image,exception);
8117           break;
8118         }
8119         case 20:  /* OilPaint */
8120         {
8121           if (attribute_flag[0] == 0)
8122             argument_list[0].real_reference=0.0;
8123           if (attribute_flag[1] == 0)
8124             argument_list[1].real_reference=1.0;
8125           image=OilPaintImage(image,argument_list[0].real_reference,
8126             argument_list[1].real_reference,exception);
8127           break;
8128         }
8129         case 21:  /* ReduceNoise */
8130         {
8131           if (attribute_flag[0] != 0)
8132             {
8133               flags=ParseGeometry(argument_list[0].string_reference,
8134                 &geometry_info);
8135               if ((flags & SigmaValue) == 0)
8136                 geometry_info.sigma=1.0;
8137             }
8138           if (attribute_flag[1] != 0)
8139             geometry_info.rho=argument_list[1].real_reference;
8140           if (attribute_flag[2] != 0)
8141             geometry_info.sigma=argument_list[2].real_reference;
8142           if (attribute_flag[3] != 0)
8143             channel=(ChannelType) argument_list[3].integer_reference;
8144           channel_mask=SetImageChannelMask(image,channel);
8145           image=StatisticImage(image,NonpeakStatistic,(size_t)
8146             geometry_info.rho,(size_t) geometry_info.sigma,exception);
8147           if (image != (Image *) NULL)
8148             (void) SetImageChannelMask(image,channel_mask);
8149           break;
8150         }
8151         case 22:  /* Roll */
8152         {
8153           if (attribute_flag[0] != 0)
8154             flags=ParsePageGeometry(image,argument_list[0].string_reference,
8155               &geometry,exception);
8156           if (attribute_flag[1] != 0)
8157             geometry.x=argument_list[1].integer_reference;
8158           if (attribute_flag[2] != 0)
8159             geometry.y=argument_list[2].integer_reference;
8160           image=RollImage(image,geometry.x,geometry.y,exception);
8161           break;
8162         }
8163         case 23:  /* Rotate */
8164         {
8165           if (attribute_flag[0] == 0)
8166             argument_list[0].real_reference=90.0;
8167           if (attribute_flag[1] != 0)
8168             {
8169               QueryColorCompliance(argument_list[1].string_reference,
8170                 AllCompliance,&image->background_color,exception);
8171               if ((image->background_color.alpha_trait != UndefinedPixelTrait) &&
8172                   (image->alpha_trait == UndefinedPixelTrait))
8173                 (void) SetImageAlpha(image,OpaqueAlpha,exception);
8174             }
8175           image=RotateImage(image,argument_list[0].real_reference,exception);
8176           break;
8177         }
8178         case 24:  /* Sample */
8179         {
8180           if (attribute_flag[0] != 0)
8181             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8182               &geometry,exception);
8183           if (attribute_flag[1] != 0)
8184             geometry.width=argument_list[1].integer_reference;
8185           if (attribute_flag[2] != 0)
8186             geometry.height=argument_list[2].integer_reference;
8187           image=SampleImage(image,geometry.width,geometry.height,exception);
8188           break;
8189         }
8190         case 25:  /* Scale */
8191         {
8192           if (attribute_flag[0] != 0)
8193             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8194               &geometry,exception);
8195           if (attribute_flag[1] != 0)
8196             geometry.width=argument_list[1].integer_reference;
8197           if (attribute_flag[2] != 0)
8198             geometry.height=argument_list[2].integer_reference;
8199           image=ScaleImage(image,geometry.width,geometry.height,exception);
8200           break;
8201         }
8202         case 26:  /* Shade */
8203         {
8204           if (attribute_flag[0] != 0)
8205             {
8206               flags=ParseGeometry(argument_list[0].string_reference,
8207                 &geometry_info);
8208               if ((flags & SigmaValue) == 0)
8209                 geometry_info.sigma=0.0;
8210             }
8211           if (attribute_flag[1] != 0)
8212             geometry_info.rho=argument_list[1].real_reference;
8213           if (attribute_flag[2] != 0)
8214             geometry_info.sigma=argument_list[2].real_reference;
8215           image=ShadeImage(image,
8216             argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8217             geometry_info.rho,geometry_info.sigma,exception);
8218           break;
8219         }
8220         case 27:  /* Sharpen */
8221         {
8222           if (attribute_flag[0] != 0)
8223             {
8224               flags=ParseGeometry(argument_list[0].string_reference,
8225                 &geometry_info);
8226               if ((flags & SigmaValue) == 0)
8227                 geometry_info.sigma=1.0;
8228             }
8229           if (attribute_flag[1] != 0)
8230             geometry_info.rho=argument_list[1].real_reference;
8231           if (attribute_flag[2] != 0)
8232             geometry_info.sigma=argument_list[2].real_reference;
8233           if (attribute_flag[3] != 0)
8234             channel=(ChannelType) argument_list[3].integer_reference;
8235           channel_mask=SetImageChannelMask(image,channel);
8236           image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8237             exception);
8238           if (image != (Image *) NULL)
8239             (void) SetImageChannelMask(image,channel_mask);
8240           break;
8241         }
8242         case 28:  /* Shear */
8243         {
8244           if (attribute_flag[0] != 0)
8245             {
8246               flags=ParseGeometry(argument_list[0].string_reference,
8247                 &geometry_info);
8248               if ((flags & SigmaValue) == 0)
8249                 geometry_info.sigma=geometry_info.rho;
8250             }
8251           if (attribute_flag[1] != 0)
8252             geometry_info.rho=argument_list[1].real_reference;
8253           if (attribute_flag[2] != 0)
8254             geometry_info.sigma=argument_list[2].real_reference;
8255           if (attribute_flag[3] != 0)
8256             QueryColorCompliance(argument_list[3].string_reference,
8257               AllCompliance,&image->background_color,exception);
8258           if (attribute_flag[4] != 0)
8259             QueryColorCompliance(argument_list[4].string_reference,
8260               AllCompliance,&image->background_color,exception);
8261           image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8262             exception);
8263           break;
8264         }
8265         case 29:  /* Spread */
8266         {
8267           PixelInterpolateMethod
8268             method;
8269 
8270           if (attribute_flag[0] == 0)
8271             argument_list[0].real_reference=1.0;
8272           method=UndefinedInterpolatePixel;
8273           if (attribute_flag[1] != 0)
8274             method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8275           image=SpreadImage(image,method,argument_list[0].real_reference,
8276             exception);
8277           break;
8278         }
8279         case 30:  /* Swirl */
8280         {
8281           PixelInterpolateMethod
8282             method;
8283 
8284           if (attribute_flag[0] == 0)
8285             argument_list[0].real_reference=50.0;
8286           method=UndefinedInterpolatePixel;
8287           if (attribute_flag[1] != 0)
8288             method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8289           image=SwirlImage(image,argument_list[0].real_reference,
8290             method,exception);
8291           break;
8292         }
8293         case 31:  /* Resize */
8294         case 32:  /* Zoom */
8295         {
8296           if (attribute_flag[0] != 0)
8297             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8298               &geometry,exception);
8299           if (attribute_flag[1] != 0)
8300             geometry.width=argument_list[1].integer_reference;
8301           if (attribute_flag[2] != 0)
8302             geometry.height=argument_list[2].integer_reference;
8303           if (attribute_flag[3] == 0)
8304             argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8305           if (attribute_flag[4] != 0)
8306             SetImageArtifact(image,"filter:support",
8307               argument_list[4].string_reference);
8308           image=ResizeImage(image,geometry.width,geometry.height,
8309             (FilterType) argument_list[3].integer_reference,
8310             exception);
8311           break;
8312         }
8313         case 33:  /* Annotate */
8314         {
8315           DrawInfo
8316             *draw_info;
8317 
8318           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8319             (DrawInfo *) NULL);
8320           if (attribute_flag[0] != 0)
8321             {
8322               char
8323                 *text;
8324 
8325               text=InterpretImageProperties(info ? info->image_info :
8326                 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8327                 exception);
8328               (void) CloneString(&draw_info->text,text);
8329               text=DestroyString(text);
8330             }
8331           if (attribute_flag[1] != 0)
8332             (void) CloneString(&draw_info->font,
8333               argument_list[1].string_reference);
8334           if (attribute_flag[2] != 0)
8335             draw_info->pointsize=argument_list[2].real_reference;
8336           if (attribute_flag[3] != 0)
8337             (void) CloneString(&draw_info->density,
8338               argument_list[3].string_reference);
8339           if (attribute_flag[4] != 0)
8340             (void) QueryColorCompliance(argument_list[4].string_reference,
8341               AllCompliance,&draw_info->undercolor,exception);
8342           if (attribute_flag[5] != 0)
8343             {
8344               (void) QueryColorCompliance(argument_list[5].string_reference,
8345                 AllCompliance,&draw_info->stroke,exception);
8346               if (argument_list[5].image_reference != (Image *) NULL)
8347                 draw_info->stroke_pattern=CloneImage(
8348                   argument_list[5].image_reference,0,0,MagickTrue,exception);
8349             }
8350           if (attribute_flag[6] != 0)
8351             {
8352               (void) QueryColorCompliance(argument_list[6].string_reference,
8353                 AllCompliance,&draw_info->fill,exception);
8354               if (argument_list[6].image_reference != (Image *) NULL)
8355                 draw_info->fill_pattern=CloneImage(
8356                   argument_list[6].image_reference,0,0,MagickTrue,exception);
8357             }
8358           if (attribute_flag[7] != 0)
8359             {
8360               (void) CloneString(&draw_info->geometry,
8361                 argument_list[7].string_reference);
8362               flags=ParsePageGeometry(image,argument_list[7].string_reference,
8363                 &geometry,exception);
8364               if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8365                 geometry_info.sigma=geometry_info.xi;
8366             }
8367           if (attribute_flag[8] != 0)
8368             (void) QueryColorCompliance(argument_list[8].string_reference,
8369               AllCompliance,&draw_info->fill,exception);
8370           if (attribute_flag[11] != 0)
8371             draw_info->gravity=(GravityType)
8372               argument_list[11].integer_reference;
8373           if (attribute_flag[25] != 0)
8374             {
8375               AV
8376                 *av;
8377 
8378               av=(AV *) argument_list[25].array_reference;
8379               if ((av_len(av) != 3) && (av_len(av) != 5))
8380                 {
8381                   ThrowPerlException(exception,OptionError,
8382                     "affine matrix must have 4 or 6 elements",PackageName);
8383                   goto PerlException;
8384                 }
8385               draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8386               draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8387               draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8388               draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8389               if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8390                   draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8391                 {
8392                   ThrowPerlException(exception,OptionError,
8393                     "affine matrix is singular",PackageName);
8394                    goto PerlException;
8395                 }
8396               if (av_len(av) == 5)
8397                 {
8398                   draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8399                   draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8400                 }
8401             }
8402           for (j=12; j < 17; j++)
8403           {
8404             if (attribute_flag[j] == 0)
8405               continue;
8406             value=argument_list[j].string_reference;
8407             angle=argument_list[j].real_reference;
8408             current=draw_info->affine;
8409             GetAffineMatrix(&affine);
8410             switch (j)
8411             {
8412               case 12:
8413               {
8414                 /*
8415                   Translate.
8416                 */
8417                 flags=ParseGeometry(value,&geometry_info);
8418                 affine.tx=geometry_info.xi;
8419                 affine.ty=geometry_info.psi;
8420                 if ((flags & PsiValue) == 0)
8421                   affine.ty=affine.tx;
8422                 break;
8423               }
8424               case 13:
8425               {
8426                 /*
8427                   Scale.
8428                 */
8429                 flags=ParseGeometry(value,&geometry_info);
8430                 affine.sx=geometry_info.rho;
8431                 affine.sy=geometry_info.sigma;
8432                 if ((flags & SigmaValue) == 0)
8433                   affine.sy=affine.sx;
8434                 break;
8435               }
8436               case 14:
8437               {
8438                 /*
8439                   Rotate.
8440                 */
8441                 if (angle == 0.0)
8442                   break;
8443                 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8444                 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8445                 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8446                 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8447                 break;
8448               }
8449               case 15:
8450               {
8451                 /*
8452                   SkewX.
8453                 */
8454                 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8455                 break;
8456               }
8457               case 16:
8458               {
8459                 /*
8460                   SkewY.
8461                 */
8462                 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8463                 break;
8464               }
8465             }
8466             draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8467             draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8468             draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8469             draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8470             draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8471               current.tx;
8472             draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8473               current.ty;
8474           }
8475           if (attribute_flag[9] == 0)
8476             argument_list[9].real_reference=0.0;
8477           if (attribute_flag[10] == 0)
8478             argument_list[10].real_reference=0.0;
8479           if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8480             {
8481               char
8482                 geometry[MagickPathExtent];
8483 
8484               (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
8485                 (double) argument_list[9].real_reference+draw_info->affine.tx,
8486                 (double) argument_list[10].real_reference+draw_info->affine.ty);
8487               (void) CloneString(&draw_info->geometry,geometry);
8488             }
8489           if (attribute_flag[17] != 0)
8490             draw_info->stroke_width=argument_list[17].real_reference;
8491           if (attribute_flag[18] != 0)
8492             {
8493               draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8494                 MagickTrue : MagickFalse;
8495               draw_info->stroke_antialias=draw_info->text_antialias;
8496             }
8497           if (attribute_flag[19] != 0)
8498             (void) CloneString(&draw_info->family,
8499               argument_list[19].string_reference);
8500           if (attribute_flag[20] != 0)
8501             draw_info->style=(StyleType) argument_list[20].integer_reference;
8502           if (attribute_flag[21] != 0)
8503             draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8504           if (attribute_flag[22] != 0)
8505             draw_info->weight=argument_list[22].integer_reference;
8506           if (attribute_flag[23] != 0)
8507             draw_info->align=(AlignType) argument_list[23].integer_reference;
8508           if (attribute_flag[24] != 0)
8509             (void) CloneString(&draw_info->encoding,
8510               argument_list[24].string_reference);
8511           if (attribute_flag[25] != 0)
8512             draw_info->fill_pattern=CloneImage(
8513               argument_list[25].image_reference,0,0,MagickTrue,exception);
8514           if (attribute_flag[26] != 0)
8515             draw_info->fill_pattern=CloneImage(
8516               argument_list[26].image_reference,0,0,MagickTrue,exception);
8517           if (attribute_flag[27] != 0)
8518             draw_info->stroke_pattern=CloneImage(
8519               argument_list[27].image_reference,0,0,MagickTrue,exception);
8520           if (attribute_flag[29] != 0)
8521             draw_info->kerning=argument_list[29].real_reference;
8522           if (attribute_flag[30] != 0)
8523             draw_info->interline_spacing=argument_list[30].real_reference;
8524           if (attribute_flag[31] != 0)
8525             draw_info->interword_spacing=argument_list[31].real_reference;
8526           if (attribute_flag[32] != 0)
8527             draw_info->direction=(DirectionType)
8528               argument_list[32].integer_reference;
8529           (void) AnnotateImage(image,draw_info,exception);
8530           draw_info=DestroyDrawInfo(draw_info);
8531           break;
8532         }
8533         case 34:  /* ColorFloodfill */
8534         {
8535           DrawInfo
8536             *draw_info;
8537 
8538           MagickBooleanType
8539             invert;
8540 
8541           PixelInfo
8542             target;
8543 
8544           draw_info=CloneDrawInfo(info ? info->image_info :
8545             (ImageInfo *) NULL,(DrawInfo *) NULL);
8546           if (attribute_flag[0] != 0)
8547             flags=ParsePageGeometry(image,argument_list[0].string_reference,
8548               &geometry,exception);
8549           if (attribute_flag[1] != 0)
8550             geometry.x=argument_list[1].integer_reference;
8551           if (attribute_flag[2] != 0)
8552             geometry.y=argument_list[2].integer_reference;
8553           if (attribute_flag[3] != 0)
8554             (void) QueryColorCompliance(argument_list[3].string_reference,
8555               AllCompliance,&draw_info->fill,exception);
8556           (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8557             geometry.x,geometry.y,&target,exception);
8558           invert=MagickFalse;
8559           if (attribute_flag[4] != 0)
8560             {
8561               QueryColorCompliance(argument_list[4].string_reference,
8562                 AllCompliance,&target,exception);
8563               invert=MagickTrue;
8564             }
8565           if (attribute_flag[5] != 0)
8566             image->fuzz=StringToDoubleInterval(
8567               argument_list[5].string_reference,(double) QuantumRange+1.0);
8568           if (attribute_flag[6] != 0)
8569             invert=(MagickBooleanType) argument_list[6].integer_reference;
8570           (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8571             geometry.y,invert,exception);
8572           draw_info=DestroyDrawInfo(draw_info);
8573           break;
8574         }
8575         case 35:  /* Composite */
8576         {
8577           char
8578             composite_geometry[MagickPathExtent];
8579 
8580           Image
8581             *composite_image,
8582             *rotate_image;
8583 
8584           MagickBooleanType
8585             clip_to_self;
8586 
8587           compose=OverCompositeOp;
8588           if (attribute_flag[0] != 0)
8589             composite_image=argument_list[0].image_reference;
8590           else
8591             {
8592               ThrowPerlException(exception,OptionError,
8593                 "CompositeImageRequired",PackageName);
8594               goto PerlException;
8595             }
8596           /*
8597             Parameter Handling used for BOTH normal and tiled composition.
8598           */
8599           if (attribute_flag[1] != 0) /* compose */
8600             compose=(CompositeOperator) argument_list[1].integer_reference;
8601           if (attribute_flag[6] != 0) /* opacity  */
8602             {
8603               if (compose != DissolveCompositeOp)
8604                 (void) SetImageAlpha(composite_image,(Quantum)
8605                   StringToDoubleInterval(argument_list[6].string_reference,
8606                   (double) QuantumRange+1.0),exception);
8607               else
8608                 {
8609                   CacheView
8610                     *composite_view;
8611 
8612                   double
8613                     opacity;
8614 
8615                   MagickBooleanType
8616                     sync;
8617 
8618                   register ssize_t
8619                     x;
8620 
8621                   register Quantum
8622                     *q;
8623 
8624                   ssize_t
8625                     y;
8626 
8627                   /*
8628                     Handle dissolve composite operator (patch by
8629                     Kevin A. McGrail).
8630                   */
8631                   (void) CloneString(&image->geometry,
8632                     argument_list[6].string_reference);
8633                   opacity=(Quantum) StringToDoubleInterval(
8634                     argument_list[6].string_reference,(double) QuantumRange+
8635                     1.0);
8636                   if (composite_image->alpha_trait != UndefinedPixelTrait)
8637                     (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8638                   composite_view=AcquireAuthenticCacheView(composite_image,exception);
8639                   for (y=0; y < (ssize_t) composite_image->rows ; y++)
8640                   {
8641                     q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8642                       composite_image->columns,1,exception);
8643                     for (x=0; x < (ssize_t) composite_image->columns; x++)
8644                     {
8645                       if (GetPixelAlpha(image,q) == OpaqueAlpha)
8646                         SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8647                           q);
8648                       q+=GetPixelChannels(composite_image);
8649                     }
8650                     sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8651                     if (sync == MagickFalse)
8652                       break;
8653                   }
8654                   composite_view=DestroyCacheView(composite_view);
8655                 }
8656             }
8657           if (attribute_flag[9] != 0)    /* "color=>" */
8658             QueryColorCompliance(argument_list[9].string_reference,
8659               AllCompliance,&composite_image->background_color,exception);
8660           if (attribute_flag[12] != 0) /* "interpolate=>" */
8661             image->interpolate=(PixelInterpolateMethod)
8662               argument_list[12].integer_reference;
8663           if (attribute_flag[13] != 0)   /* "args=>" */
8664             (void) SetImageArtifact(composite_image,"compose:args",
8665               argument_list[13].string_reference);
8666           if (attribute_flag[14] != 0)   /* "blend=>"  depreciated */
8667             (void) SetImageArtifact(composite_image,"compose:args",
8668               argument_list[14].string_reference);
8669           clip_to_self=MagickTrue;
8670           if (attribute_flag[15] != 0)
8671             clip_to_self=(MagickBooleanType)
8672               argument_list[15].integer_reference;
8673           /*
8674             Tiling Composition (with orthogonal rotate).
8675           */
8676           rotate_image=(Image *) NULL;
8677           if (attribute_flag[8] != 0)   /* "rotate=>" */
8678             {
8679                /*
8680                  Rotate image.
8681                */
8682                rotate_image=RotateImage(composite_image,
8683                  argument_list[8].real_reference,exception);
8684                if (rotate_image == (Image *) NULL)
8685                  break;
8686             }
8687           if ((attribute_flag[7] != 0) &&
8688               (argument_list[7].integer_reference != 0)) /* tile */
8689             {
8690               ssize_t
8691                 x,
8692                 y;
8693 
8694               /*
8695                 Tile the composite image.
8696               */
8697              if (attribute_flag[8] != 0)   /* "tile=>" */
8698                (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
8699                  "false");
8700              else
8701                (void) SetImageArtifact(composite_image,
8702                  "compose:outside-overlay","false");
8703              for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8704                 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8705                 {
8706                   if (attribute_flag[8] != 0) /* rotate */
8707                     (void) CompositeImage(image,rotate_image,compose,
8708                       MagickTrue,x,y,exception);
8709                   else
8710                     (void) CompositeImage(image,composite_image,compose,
8711                       MagickTrue,x,y,exception);
8712                 }
8713               if (attribute_flag[8] != 0) /* rotate */
8714                 rotate_image=DestroyImage(rotate_image);
8715               break;
8716             }
8717           /*
8718             Parameter Handling used used ONLY for normal composition.
8719           */
8720           if (attribute_flag[5] != 0) /* gravity */
8721             image->gravity=(GravityType) argument_list[5].integer_reference;
8722           if (attribute_flag[2] != 0) /* geometry offset */
8723             {
8724               SetGeometry(image,&geometry);
8725               (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8726                 &geometry);
8727               GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8728                 &geometry);
8729             }
8730           if (attribute_flag[3] != 0) /* x offset */
8731             geometry.x=argument_list[3].integer_reference;
8732           if (attribute_flag[4] != 0) /* y offset */
8733             geometry.y=argument_list[4].integer_reference;
8734           if (attribute_flag[10] != 0) /* mask */
8735             {
8736               if ((image->compose == DisplaceCompositeOp) ||
8737                   (image->compose == DistortCompositeOp))
8738                 {
8739                   /*
8740                     Merge Y displacement into X displacement image.
8741                   */
8742                   composite_image=CloneImage(composite_image,0,0,MagickTrue,
8743                     exception);
8744                   (void) CompositeImage(composite_image,
8745                     argument_list[10].image_reference,CopyGreenCompositeOp,
8746                     MagickTrue,0,0,exception);
8747                 }
8748               else
8749                 {
8750                   Image
8751                     *mask_image;
8752 
8753                   /*
8754                     Set a blending mask for the composition.
8755                   */
8756                   mask_image=CloneImage(argument_list[10].image_reference,0,0,
8757                     MagickTrue,exception);
8758                   (void) SetImageMask(composite_image,ReadPixelMask,mask_image,
8759                     exception);
8760                   mask_image=DestroyImage(mask_image);
8761                 }
8762             }
8763           if (attribute_flag[11] != 0) /* channel */
8764             channel=(ChannelType) argument_list[11].integer_reference;
8765           /*
8766             Composite two images (normal composition).
8767           */
8768           (void) FormatLocaleString(composite_geometry,MagickPathExtent,
8769             "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8770             (double) composite_image->rows,(double) geometry.x,(double)
8771             geometry.y);
8772           flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8773             exception);
8774           channel_mask=SetImageChannelMask(image,channel);
8775           if (attribute_flag[8] == 0) /* no rotate */
8776             CompositeImage(image,composite_image,compose,clip_to_self,
8777               geometry.x,geometry.y,exception);
8778           else
8779             {
8780               /*
8781                 Position adjust rotated image then composite.
8782               */
8783               geometry.x-=(ssize_t) (rotate_image->columns-
8784                 composite_image->columns)/2;
8785               geometry.y-=(ssize_t) (rotate_image->rows-
8786                 composite_image->rows)/2;
8787               CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8788                 geometry.y,exception);
8789               rotate_image=DestroyImage(rotate_image);
8790             }
8791           if (attribute_flag[10] != 0) /* mask */
8792             {
8793               if ((image->compose == DisplaceCompositeOp) ||
8794                   (image->compose == DistortCompositeOp))
8795                 composite_image=DestroyImage(composite_image);
8796               else
8797                 (void) SetImageMask(image,ReadPixelMask,(Image *) NULL,
8798                   exception);
8799             }
8800           (void) SetImageChannelMask(image,channel_mask);
8801           break;
8802         }
8803         case 36:  /* Contrast */
8804         {
8805           if (attribute_flag[0] == 0)
8806             argument_list[0].integer_reference=0;
8807           (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8808             MagickTrue : MagickFalse,exception);
8809           break;
8810         }
8811         case 37:  /* CycleColormap */
8812         {
8813           if (attribute_flag[0] == 0)
8814             argument_list[0].integer_reference=6;
8815           (void) CycleColormapImage(image,argument_list[0].integer_reference,
8816             exception);
8817           break;
8818         }
8819         case 38:  /* Draw */
8820         {
8821           DrawInfo
8822             *draw_info;
8823 
8824           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8825             (DrawInfo *) NULL);
8826           (void) CloneString(&draw_info->primitive,"point");
8827           if (attribute_flag[0] != 0)
8828             {
8829               if (argument_list[0].integer_reference < 0)
8830                 (void) CloneString(&draw_info->primitive,
8831                   argument_list[0].string_reference);
8832               else
8833                 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8834                   MagickPrimitiveOptions,argument_list[0].integer_reference));
8835             }
8836           if (attribute_flag[1] != 0)
8837             {
8838               if (LocaleCompare(draw_info->primitive,"path") == 0)
8839                 {
8840                   (void) ConcatenateString(&draw_info->primitive," '");
8841                   ConcatenateString(&draw_info->primitive,
8842                     argument_list[1].string_reference);
8843                   (void) ConcatenateString(&draw_info->primitive,"'");
8844                 }
8845               else
8846                 {
8847                   (void) ConcatenateString(&draw_info->primitive," ");
8848                   ConcatenateString(&draw_info->primitive,
8849                     argument_list[1].string_reference);
8850                 }
8851             }
8852           if (attribute_flag[2] != 0)
8853             {
8854               (void) ConcatenateString(&draw_info->primitive," ");
8855               (void) ConcatenateString(&draw_info->primitive,
8856                 CommandOptionToMnemonic(MagickMethodOptions,
8857                 argument_list[2].integer_reference));
8858             }
8859           if (attribute_flag[3] != 0)
8860             {
8861               (void) QueryColorCompliance(argument_list[3].string_reference,
8862                 AllCompliance,&draw_info->stroke,exception);
8863               if (argument_list[3].image_reference != (Image *) NULL)
8864                 draw_info->stroke_pattern=CloneImage(
8865                   argument_list[3].image_reference,0,0,MagickTrue,exception);
8866             }
8867           if (attribute_flag[4] != 0)
8868             {
8869               (void) QueryColorCompliance(argument_list[4].string_reference,
8870                 AllCompliance,&draw_info->fill,exception);
8871               if (argument_list[4].image_reference != (Image *) NULL)
8872                 draw_info->fill_pattern=CloneImage(
8873                   argument_list[4].image_reference,0,0,MagickTrue,exception);
8874             }
8875           if (attribute_flag[5] != 0)
8876             draw_info->stroke_width=argument_list[5].real_reference;
8877           if (attribute_flag[6] != 0)
8878             (void) CloneString(&draw_info->font,
8879               argument_list[6].string_reference);
8880           if (attribute_flag[7] != 0)
8881             (void) QueryColorCompliance(argument_list[7].string_reference,
8882               AllCompliance,&draw_info->border_color,exception);
8883           if (attribute_flag[8] != 0)
8884             draw_info->affine.tx=argument_list[8].real_reference;
8885           if (attribute_flag[9] != 0)
8886             draw_info->affine.ty=argument_list[9].real_reference;
8887           if (attribute_flag[20] != 0)
8888             {
8889               AV
8890                 *av;
8891 
8892               av=(AV *) argument_list[20].array_reference;
8893               if ((av_len(av) != 3) && (av_len(av) != 5))
8894                 {
8895                   ThrowPerlException(exception,OptionError,
8896                     "affine matrix must have 4 or 6 elements",PackageName);
8897                   goto PerlException;
8898                 }
8899               draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8900               draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8901               draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8902               draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8903               if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8904                   draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8905                 {
8906                   ThrowPerlException(exception,OptionError,
8907                     "affine matrix is singular",PackageName);
8908                    goto PerlException;
8909                 }
8910               if (av_len(av) == 5)
8911                 {
8912                   draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8913                   draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8914                 }
8915             }
8916           for (j=10; j < 15; j++)
8917           {
8918             if (attribute_flag[j] == 0)
8919               continue;
8920             value=argument_list[j].string_reference;
8921             angle=argument_list[j].real_reference;
8922             current=draw_info->affine;
8923             GetAffineMatrix(&affine);
8924             switch (j)
8925             {
8926               case 10:
8927               {
8928                 /*
8929                   Translate.
8930                 */
8931                 flags=ParseGeometry(value,&geometry_info);
8932                 affine.tx=geometry_info.xi;
8933                 affine.ty=geometry_info.psi;
8934                 if ((flags & PsiValue) == 0)
8935                   affine.ty=affine.tx;
8936                 break;
8937               }
8938               case 11:
8939               {
8940                 /*
8941                   Scale.
8942                 */
8943                 flags=ParseGeometry(value,&geometry_info);
8944                 affine.sx=geometry_info.rho;
8945                 affine.sy=geometry_info.sigma;
8946                 if ((flags & SigmaValue) == 0)
8947                   affine.sy=affine.sx;
8948                 break;
8949               }
8950               case 12:
8951               {
8952                 /*
8953                   Rotate.
8954                 */
8955                 if (angle == 0.0)
8956                   break;
8957                 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8958                 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8959                 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8960                 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8961                 break;
8962               }
8963               case 13:
8964               {
8965                 /*
8966                   SkewX.
8967                 */
8968                 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8969                 break;
8970               }
8971               case 14:
8972               {
8973                 /*
8974                   SkewY.
8975                 */
8976                 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8977                 break;
8978               }
8979             }
8980             draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8981             draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8982             draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8983             draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8984             draw_info->affine.tx=
8985               current.sx*affine.tx+current.ry*affine.ty+current.tx;
8986             draw_info->affine.ty=
8987               current.rx*affine.tx+current.sy*affine.ty+current.ty;
8988           }
8989           if (attribute_flag[15] != 0)
8990             draw_info->fill_pattern=CloneImage(
8991               argument_list[15].image_reference,0,0,MagickTrue,exception);
8992           if (attribute_flag[16] != 0)
8993             draw_info->pointsize=argument_list[16].real_reference;
8994           if (attribute_flag[17] != 0)
8995             {
8996               draw_info->stroke_antialias=argument_list[17].integer_reference != 0
8997                 ? MagickTrue : MagickFalse;
8998               draw_info->text_antialias=draw_info->stroke_antialias;
8999             }
9000           if (attribute_flag[18] != 0)
9001             (void) CloneString(&draw_info->density,
9002               argument_list[18].string_reference);
9003           if (attribute_flag[19] != 0)
9004             draw_info->stroke_width=argument_list[19].real_reference;
9005           if (attribute_flag[21] != 0)
9006             draw_info->dash_offset=argument_list[21].real_reference;
9007           if (attribute_flag[22] != 0)
9008             {
9009               AV
9010                 *av;
9011 
9012               av=(AV *) argument_list[22].array_reference;
9013               draw_info->dash_pattern=(double *) AcquireQuantumMemory(
9014                 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
9015               if (draw_info->dash_pattern != (double *) NULL)
9016                 {
9017                   for (i=0; i <= av_len(av); i++)
9018                     draw_info->dash_pattern[i]=(double)
9019                       SvNV(*(av_fetch(av,i,0)));
9020                   draw_info->dash_pattern[i]=0.0;
9021                 }
9022             }
9023           if (attribute_flag[23] != 0)
9024             image->interpolate=(PixelInterpolateMethod)
9025               argument_list[23].integer_reference;
9026           if ((attribute_flag[24] != 0) &&
9027               (draw_info->fill_pattern != (Image *) NULL))
9028             flags=ParsePageGeometry(draw_info->fill_pattern,
9029               argument_list[24].string_reference,
9030               &draw_info->fill_pattern->tile_offset,exception);
9031           if (attribute_flag[25] != 0)
9032             {
9033               (void) ConcatenateString(&draw_info->primitive," '");
9034               (void) ConcatenateString(&draw_info->primitive,
9035                 argument_list[25].string_reference);
9036               (void) ConcatenateString(&draw_info->primitive,"'");
9037             }
9038           if (attribute_flag[26] != 0)
9039             draw_info->fill_pattern=CloneImage(
9040               argument_list[26].image_reference,0,0,MagickTrue,exception);
9041           if (attribute_flag[27] != 0)
9042             draw_info->stroke_pattern=CloneImage(
9043               argument_list[27].image_reference,0,0,MagickTrue,exception);
9044           if (attribute_flag[28] != 0)
9045             (void) CloneString(&draw_info->primitive,
9046               argument_list[28].string_reference);
9047           if (attribute_flag[29] != 0)
9048             draw_info->kerning=argument_list[29].real_reference;
9049           if (attribute_flag[30] != 0)
9050             draw_info->interline_spacing=argument_list[30].real_reference;
9051           if (attribute_flag[31] != 0)
9052             draw_info->interword_spacing=argument_list[31].real_reference;
9053           if (attribute_flag[32] != 0)
9054             draw_info->direction=(DirectionType)
9055               argument_list[32].integer_reference;
9056           DrawImage(image,draw_info,exception);
9057           draw_info=DestroyDrawInfo(draw_info);
9058           break;
9059         }
9060         case 39:  /* Equalize */
9061         {
9062           if (attribute_flag[0] != 0)
9063             channel=(ChannelType) argument_list[0].integer_reference;
9064           channel_mask=SetImageChannelMask(image,channel);
9065           EqualizeImage(image,exception);
9066           (void) SetImageChannelMask(image,channel_mask);
9067           break;
9068         }
9069         case 40:  /* Gamma */
9070         {
9071           if (attribute_flag[1] != 0)
9072             channel=(ChannelType) argument_list[1].integer_reference;
9073           if (attribute_flag[2] == 0)
9074             argument_list[2].real_reference=1.0;
9075           if (attribute_flag[3] == 0)
9076             argument_list[3].real_reference=1.0;
9077           if (attribute_flag[4] == 0)
9078             argument_list[4].real_reference=1.0;
9079           if (attribute_flag[0] == 0)
9080             {
9081               (void) FormatLocaleString(message,MagickPathExtent,
9082                 "%.15g,%.15g,%.15g",(double) argument_list[2].real_reference,
9083                 (double) argument_list[3].real_reference,
9084                 (double) argument_list[4].real_reference);
9085               argument_list[0].string_reference=message;
9086             }
9087           (void) GammaImage(image,StringToDouble(
9088             argument_list[0].string_reference,(char **) NULL),exception);
9089           break;
9090         }
9091         case 41:  /* Map */
9092         {
9093           QuantizeInfo
9094             *quantize_info;
9095 
9096           if (attribute_flag[0] == 0)
9097             {
9098               ThrowPerlException(exception,OptionError,"MapImageRequired",
9099                 PackageName);
9100               goto PerlException;
9101             }
9102           quantize_info=AcquireQuantizeInfo(info->image_info);
9103           if (attribute_flag[1] != 0)
9104             quantize_info->dither_method=(DitherMethod)
9105               argument_list[1].integer_reference;
9106           (void) RemapImages(quantize_info,image,
9107             argument_list[0].image_reference,exception);
9108           quantize_info=DestroyQuantizeInfo(quantize_info);
9109           break;
9110         }
9111         case 42:  /* MatteFloodfill */
9112         {
9113           DrawInfo
9114             *draw_info;
9115 
9116           MagickBooleanType
9117             invert;
9118 
9119           PixelInfo
9120             target;
9121 
9122           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9123             (DrawInfo *) NULL);
9124           if (attribute_flag[0] != 0)
9125             flags=ParsePageGeometry(image,argument_list[0].string_reference,
9126               &geometry,exception);
9127           if (attribute_flag[1] != 0)
9128             geometry.x=argument_list[1].integer_reference;
9129           if (attribute_flag[2] != 0)
9130             geometry.y=argument_list[2].integer_reference;
9131           if (image->alpha_trait == UndefinedPixelTrait)
9132             (void) SetImageAlpha(image,OpaqueAlpha,exception);
9133           (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
9134             geometry.x,geometry.y,&target,exception);
9135           if (attribute_flag[4] != 0)
9136             QueryColorCompliance(argument_list[4].string_reference,
9137               AllCompliance,&target,exception);
9138           if (attribute_flag[3] != 0)
9139             target.alpha=StringToDoubleInterval(
9140               argument_list[3].string_reference,(double) (double) QuantumRange+
9141               1.0);
9142           if (attribute_flag[5] != 0)
9143             image->fuzz=StringToDoubleInterval(
9144               argument_list[5].string_reference,(double) QuantumRange+1.0);
9145           invert=MagickFalse;
9146           if (attribute_flag[6] != 0)
9147             invert=(MagickBooleanType) argument_list[6].integer_reference;
9148           channel_mask=SetImageChannelMask(image,AlphaChannel);
9149           (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
9150             geometry.y,invert,exception);
9151           (void) SetImageChannelMask(image,channel_mask);
9152           draw_info=DestroyDrawInfo(draw_info);
9153           break;
9154         }
9155         case 43:  /* Modulate */
9156         {
9157           char
9158             modulate[MagickPathExtent];
9159 
9160           geometry_info.rho=100.0;
9161           geometry_info.sigma=100.0;
9162           geometry_info.xi=100.0;
9163           if (attribute_flag[0] != 0)
9164             (void)ParseGeometry(argument_list[0].string_reference,
9165               &geometry_info);
9166           if (attribute_flag[1] != 0)
9167             geometry_info.xi=argument_list[1].real_reference;
9168           if (attribute_flag[2] != 0)
9169             geometry_info.sigma=argument_list[2].real_reference;
9170           if (attribute_flag[3] != 0)
9171             {
9172               geometry_info.sigma=argument_list[3].real_reference;
9173               SetImageArtifact(image,"modulate:colorspace","HWB");
9174             }
9175           if (attribute_flag[4] != 0)
9176             {
9177               geometry_info.rho=argument_list[4].real_reference;
9178               SetImageArtifact(image,"modulate:colorspace","HSB");
9179             }
9180           if (attribute_flag[5] != 0)
9181             {
9182               geometry_info.sigma=argument_list[5].real_reference;
9183               SetImageArtifact(image,"modulate:colorspace","HSL");
9184             }
9185           if (attribute_flag[6] != 0)
9186             {
9187               geometry_info.rho=argument_list[6].real_reference;
9188               SetImageArtifact(image,"modulate:colorspace","HWB");
9189             }
9190           (void) FormatLocaleString(modulate,MagickPathExtent,"%.15g,%.15g,%.15g",
9191             geometry_info.rho,geometry_info.sigma,geometry_info.xi);
9192           (void) ModulateImage(image,modulate,exception);
9193           break;
9194         }
9195         case 44:  /* Negate */
9196         {
9197           if (attribute_flag[0] == 0)
9198             argument_list[0].integer_reference=0;
9199           if (attribute_flag[1] != 0)
9200             channel=(ChannelType) argument_list[1].integer_reference;
9201           channel_mask=SetImageChannelMask(image,channel);
9202           (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9203             MagickTrue : MagickFalse,exception);
9204           (void) SetImageChannelMask(image,channel_mask);
9205           break;
9206         }
9207         case 45:  /* Normalize */
9208         {
9209           if (attribute_flag[0] != 0)
9210             channel=(ChannelType) argument_list[0].integer_reference;
9211           channel_mask=SetImageChannelMask(image,channel);
9212           NormalizeImage(image,exception);
9213           (void) SetImageChannelMask(image,channel_mask);
9214           break;
9215         }
9216         case 46:  /* NumberColors */
9217           break;
9218         case 47:  /* Opaque */
9219         {
9220           MagickBooleanType
9221             invert;
9222 
9223           PixelInfo
9224             fill_color,
9225             target;
9226 
9227           (void) QueryColorCompliance("none",AllCompliance,&target,
9228              exception);
9229           (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9230             exception);
9231           if (attribute_flag[0] != 0)
9232             (void) QueryColorCompliance(argument_list[0].string_reference,
9233               AllCompliance,&target,exception);
9234           if (attribute_flag[1] != 0)
9235             (void) QueryColorCompliance(argument_list[1].string_reference,
9236               AllCompliance,&fill_color,exception);
9237           if (attribute_flag[2] != 0)
9238             image->fuzz=StringToDoubleInterval(
9239               argument_list[2].string_reference,(double) QuantumRange+1.0);
9240           if (attribute_flag[3] != 0)
9241             channel=(ChannelType) argument_list[3].integer_reference;
9242           invert=MagickFalse;
9243           if (attribute_flag[4] != 0)
9244             invert=(MagickBooleanType) argument_list[4].integer_reference;
9245           channel_mask=SetImageChannelMask(image,channel);
9246           (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9247           (void) SetImageChannelMask(image,channel_mask);
9248           break;
9249         }
9250         case 48:  /* Quantize */
9251         {
9252           QuantizeInfo
9253             *quantize_info;
9254 
9255           quantize_info=AcquireQuantizeInfo(info->image_info);
9256           if (attribute_flag[0] != 0)
9257             quantize_info->number_colors=(size_t)
9258               argument_list[0].integer_reference;
9259           if (attribute_flag[1] != 0)
9260             quantize_info->tree_depth=(size_t)
9261               argument_list[1].integer_reference;
9262           if (attribute_flag[2] != 0)
9263             quantize_info->colorspace=(ColorspaceType)
9264               argument_list[2].integer_reference;
9265           if (attribute_flag[3] != 0)
9266             quantize_info->dither_method=(DitherMethod)
9267               argument_list[3].integer_reference;
9268           if (attribute_flag[4] != 0)
9269             quantize_info->measure_error=
9270               argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
9271           if (attribute_flag[6] != 0)
9272             (void) QueryColorCompliance(argument_list[6].string_reference,
9273               AllCompliance,&image->transparent_color,exception);
9274           if (attribute_flag[7] != 0)
9275             quantize_info->dither_method=(DitherMethod)
9276               argument_list[7].integer_reference;
9277           if (attribute_flag[5] && argument_list[5].integer_reference)
9278             (void) QuantizeImages(quantize_info,image,exception);
9279           else
9280             if ((image->storage_class == DirectClass) ||
9281                (image->colors > quantize_info->number_colors) ||
9282                (quantize_info->colorspace == GRAYColorspace))
9283              (void) QuantizeImage(quantize_info,image,exception);
9284            else
9285              CompressImageColormap(image,exception);
9286           quantize_info=DestroyQuantizeInfo(quantize_info);
9287           break;
9288         }
9289         case 49:  /* Raise */
9290         {
9291           if (attribute_flag[0] != 0)
9292             flags=ParsePageGeometry(image,argument_list[0].string_reference,
9293               &geometry,exception);
9294           if (attribute_flag[1] != 0)
9295             geometry.width=argument_list[1].integer_reference;
9296           if (attribute_flag[2] != 0)
9297             geometry.height=argument_list[2].integer_reference;
9298           if (attribute_flag[3] == 0)
9299             argument_list[3].integer_reference=1;
9300           (void) RaiseImage(image,&geometry,
9301             argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9302             exception);
9303           break;
9304         }
9305         case 50:  /* Segment */
9306         {
9307           ColorspaceType
9308             colorspace;
9309 
9310           double
9311             cluster_threshold,
9312             smoothing_threshold;
9313 
9314           MagickBooleanType
9315             verbose;
9316 
9317           cluster_threshold=1.0;
9318           smoothing_threshold=1.5;
9319           colorspace=sRGBColorspace;
9320           verbose=MagickFalse;
9321           if (attribute_flag[0] != 0)
9322             {
9323               flags=ParseGeometry(argument_list[0].string_reference,
9324                 &geometry_info);
9325               cluster_threshold=geometry_info.rho;
9326               if (flags & SigmaValue)
9327                 smoothing_threshold=geometry_info.sigma;
9328             }
9329           if (attribute_flag[1] != 0)
9330             cluster_threshold=argument_list[1].real_reference;
9331           if (attribute_flag[2] != 0)
9332             smoothing_threshold=argument_list[2].real_reference;
9333           if (attribute_flag[3] != 0)
9334             colorspace=(ColorspaceType) argument_list[3].integer_reference;
9335           if (attribute_flag[4] != 0)
9336             verbose=argument_list[4].integer_reference != 0 ?
9337               MagickTrue : MagickFalse;
9338           (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9339             smoothing_threshold,exception);
9340           break;
9341         }
9342         case 51:  /* Signature */
9343         {
9344           (void) SignatureImage(image,exception);
9345           break;
9346         }
9347         case 52:  /* Solarize */
9348         {
9349           geometry_info.rho=QuantumRange/2.0;
9350           if (attribute_flag[0] != 0)
9351             flags=ParseGeometry(argument_list[0].string_reference,
9352               &geometry_info);
9353           if (attribute_flag[1] != 0)
9354             geometry_info.rho=StringToDoubleInterval(
9355               argument_list[1].string_reference,(double) QuantumRange+1.0);
9356           (void) SolarizeImage(image,geometry_info.rho,exception);
9357           break;
9358         }
9359         case 53:  /* Sync */
9360         {
9361           (void) SyncImage(image,exception);
9362           break;
9363         }
9364         case 54:  /* Texture */
9365         {
9366           if (attribute_flag[0] == 0)
9367             break;
9368           TextureImage(image,argument_list[0].image_reference,exception);
9369           break;
9370         }
9371         case 55:  /* Evalute */
9372         {
9373           MagickEvaluateOperator
9374             op;
9375 
9376           op=SetEvaluateOperator;
9377           if (attribute_flag[0] == MagickFalse)
9378             argument_list[0].real_reference=0.0;
9379           if (attribute_flag[1] != MagickFalse)
9380             op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9381           if (attribute_flag[2] != MagickFalse)
9382             channel=(ChannelType) argument_list[2].integer_reference;
9383           channel_mask=SetImageChannelMask(image,channel);
9384           (void) EvaluateImage(image,op,argument_list[0].real_reference,
9385             exception);
9386           (void) SetImageChannelMask(image,channel_mask);
9387           break;
9388         }
9389         case 56:  /* Transparent */
9390         {
9391           double
9392             opacity;
9393 
9394           MagickBooleanType
9395             invert;
9396 
9397           PixelInfo
9398             target;
9399 
9400           (void) QueryColorCompliance("none",AllCompliance,&target,
9401             exception);
9402           if (attribute_flag[0] != 0)
9403             (void) QueryColorCompliance(argument_list[0].string_reference,
9404               AllCompliance,&target,exception);
9405           opacity=TransparentAlpha;
9406           if (attribute_flag[1] != 0)
9407             opacity=StringToDoubleInterval(argument_list[1].string_reference,
9408               (double) QuantumRange+1.0);
9409           if (attribute_flag[2] != 0)
9410             image->fuzz=StringToDoubleInterval(
9411               argument_list[2].string_reference,(double) QuantumRange+1.0);
9412           if (attribute_flag[3] == 0)
9413             argument_list[3].integer_reference=0;
9414           invert=MagickFalse;
9415           if (attribute_flag[3] != 0)
9416             invert=(MagickBooleanType) argument_list[3].integer_reference;
9417           (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9418             invert,exception);
9419           break;
9420         }
9421         case 57:  /* Threshold */
9422         {
9423           double
9424             threshold;
9425 
9426           if (attribute_flag[0] == 0)
9427             argument_list[0].string_reference="50%";
9428           if (attribute_flag[1] != 0)
9429             channel=(ChannelType) argument_list[1].integer_reference;
9430           threshold=StringToDoubleInterval(argument_list[0].string_reference,
9431             (double) QuantumRange+1.0);
9432           channel_mask=SetImageChannelMask(image,channel);
9433           (void) BilevelImage(image,threshold,exception);
9434           (void) SetImageChannelMask(image,channel_mask);
9435           break;
9436         }
9437         case 58:  /* Charcoal */
9438         {
9439           if (attribute_flag[0] != 0)
9440             {
9441               flags=ParseGeometry(argument_list[0].string_reference,
9442                 &geometry_info);
9443               if ((flags & SigmaValue) == 0)
9444                 geometry_info.sigma=1.0;
9445             }
9446           if (attribute_flag[1] != 0)
9447             geometry_info.rho=argument_list[1].real_reference;
9448           if (attribute_flag[2] != 0)
9449             geometry_info.sigma=argument_list[2].real_reference;
9450           image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9451             exception);
9452           break;
9453         }
9454         case 59:  /* Trim */
9455         {
9456           if (attribute_flag[0] != 0)
9457             image->fuzz=StringToDoubleInterval(
9458               argument_list[0].string_reference,(double) QuantumRange+1.0);
9459           image=TrimImage(image,exception);
9460           break;
9461         }
9462         case 60:  /* Wave */
9463         {
9464           PixelInterpolateMethod
9465             method;
9466 
9467           if (attribute_flag[0] != 0)
9468             {
9469               flags=ParseGeometry(argument_list[0].string_reference,
9470                 &geometry_info);
9471               if ((flags & SigmaValue) == 0)
9472                 geometry_info.sigma=1.0;
9473             }
9474           if (attribute_flag[1] != 0)
9475             geometry_info.rho=argument_list[1].real_reference;
9476           if (attribute_flag[2] != 0)
9477             geometry_info.sigma=argument_list[2].real_reference;
9478           method=UndefinedInterpolatePixel;
9479           if (attribute_flag[3] != 0)
9480             method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9481           image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9482             method,exception);
9483           break;
9484         }
9485         case 61:  /* Separate */
9486         {
9487           if (attribute_flag[0] != 0)
9488             channel=(ChannelType) argument_list[0].integer_reference;
9489           image=SeparateImage(image,channel,exception);
9490           break;
9491         }
9492         case 63:  /* Stereo */
9493         {
9494           if (attribute_flag[0] == 0)
9495             {
9496               ThrowPerlException(exception,OptionError,"StereoImageRequired",
9497                 PackageName);
9498               goto PerlException;
9499             }
9500           if (attribute_flag[1] != 0)
9501             geometry.x=argument_list[1].integer_reference;
9502           if (attribute_flag[2] != 0)
9503             geometry.y=argument_list[2].integer_reference;
9504           image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9505             geometry.x,geometry.y,exception);
9506           break;
9507         }
9508         case 64:  /* Stegano */
9509         {
9510           if (attribute_flag[0] == 0)
9511             {
9512               ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9513                 PackageName);
9514               goto PerlException;
9515             }
9516           if (attribute_flag[1] == 0)
9517             argument_list[1].integer_reference=0;
9518           image->offset=argument_list[1].integer_reference;
9519           image=SteganoImage(image,argument_list[0].image_reference,exception);
9520           break;
9521         }
9522         case 65:  /* Deconstruct */
9523         {
9524           image=CompareImagesLayers(image,CompareAnyLayer,exception);
9525           break;
9526         }
9527         case 66:  /* GaussianBlur */
9528         {
9529           if (attribute_flag[0] != 0)
9530             {
9531               flags=ParseGeometry(argument_list[0].string_reference,
9532                 &geometry_info);
9533               if ((flags & SigmaValue) == 0)
9534                 geometry_info.sigma=1.0;
9535             }
9536           if (attribute_flag[1] != 0)
9537             geometry_info.rho=argument_list[1].real_reference;
9538           if (attribute_flag[2] != 0)
9539             geometry_info.sigma=argument_list[2].real_reference;
9540           if (attribute_flag[3] != 0)
9541             channel=(ChannelType) argument_list[3].integer_reference;
9542           channel_mask=SetImageChannelMask(image,channel);
9543           image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9544             exception);
9545           if (image != (Image *) NULL)
9546             (void) SetImageChannelMask(image,channel_mask);
9547           break;
9548         }
9549         case 67:  /* Convolve */
9550         {
9551           KernelInfo
9552             *kernel;
9553 
9554           kernel=(KernelInfo *) NULL;
9555           if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9556             break;
9557           if (attribute_flag[0] != 0)
9558             {
9559               AV
9560                 *av;
9561 
9562               size_t
9563                 order;
9564 
9565               kernel=AcquireKernelInfo((const char *) NULL,exception);
9566               if (kernel == (KernelInfo *) NULL)
9567                 break;
9568               av=(AV *) argument_list[0].array_reference;
9569               order=(size_t) sqrt(av_len(av)+1);
9570               kernel->width=order;
9571               kernel->height=order;
9572               kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9573                 order*sizeof(*kernel->values));
9574               if (kernel->values == (MagickRealType *) NULL)
9575                 {
9576                   kernel=DestroyKernelInfo(kernel);
9577                   ThrowPerlException(exception,ResourceLimitFatalError,
9578                     "MemoryAllocationFailed",PackageName);
9579                   goto PerlException;
9580                 }
9581               for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9582                 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9583               for ( ; j < (ssize_t) (order*order); j++)
9584                 kernel->values[j]=0.0;
9585             }
9586           if (attribute_flag[1] != 0)
9587             channel=(ChannelType) argument_list[1].integer_reference;
9588           if (attribute_flag[2] != 0)
9589             SetImageArtifact(image,"filter:blur",
9590               argument_list[2].string_reference);
9591           if (attribute_flag[3] != 0)
9592             {
9593               kernel=AcquireKernelInfo(argument_list[3].string_reference,
9594                 exception);
9595               if (kernel == (KernelInfo *) NULL)
9596                 break;
9597             }
9598           channel_mask=SetImageChannelMask(image,channel);
9599           image=ConvolveImage(image,kernel,exception);
9600           if (image != (Image *) NULL)
9601             (void) SetImageChannelMask(image,channel_mask);
9602           kernel=DestroyKernelInfo(kernel);
9603           break;
9604         }
9605         case 68:  /* Profile */
9606         {
9607           const char
9608             *name;
9609 
9610           Image
9611             *profile_image;
9612 
9613           ImageInfo
9614             *profile_info;
9615 
9616           StringInfo
9617             *profile;
9618 
9619           name="*";
9620           if (attribute_flag[0] != 0)
9621             name=argument_list[0].string_reference;
9622           if (attribute_flag[2] != 0)
9623             image->rendering_intent=(RenderingIntent)
9624               argument_list[2].integer_reference;
9625           if (attribute_flag[3] != 0)
9626             image->black_point_compensation=
9627               argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9628           if (attribute_flag[1] != 0)
9629             {
9630               if (argument_list[1].length == 0)
9631                 {
9632                   /*
9633                     Remove a profile from the image.
9634                   */
9635                   (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9636                     exception);
9637                   break;
9638                 }
9639               /*
9640                 Associate user supplied profile with the image.
9641               */
9642               profile=AcquireStringInfo(argument_list[1].length);
9643               SetStringInfoDatum(profile,(const unsigned char *)
9644                 argument_list[1].string_reference);
9645               (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9646                 (size_t) GetStringInfoLength(profile),exception);
9647               profile=DestroyStringInfo(profile);
9648               break;
9649             }
9650           /*
9651             Associate a profile with the image.
9652           */
9653           profile_info=CloneImageInfo(info ? info->image_info :
9654             (ImageInfo *) NULL);
9655           profile_image=ReadImages(profile_info,name,exception);
9656           if (profile_image == (Image *) NULL)
9657             break;
9658           ResetImageProfileIterator(profile_image);
9659           name=GetNextImageProfile(profile_image);
9660           while (name != (const char *) NULL)
9661           {
9662             const StringInfo
9663               *profile;
9664 
9665             profile=GetImageProfile(profile_image,name);
9666             if (profile != (const StringInfo *) NULL)
9667               (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9668                 (size_t) GetStringInfoLength(profile),exception);
9669             name=GetNextImageProfile(profile_image);
9670           }
9671           profile_image=DestroyImage(profile_image);
9672           profile_info=DestroyImageInfo(profile_info);
9673           break;
9674         }
9675         case 69:  /* UnsharpMask */
9676         {
9677           if (attribute_flag[0] != 0)
9678             {
9679               flags=ParseGeometry(argument_list[0].string_reference,
9680                 &geometry_info);
9681               if ((flags & SigmaValue) == 0)
9682                 geometry_info.sigma=1.0;
9683               if ((flags & XiValue) == 0)
9684                 geometry_info.xi=1.0;
9685               if ((flags & PsiValue) == 0)
9686                 geometry_info.psi=0.5;
9687             }
9688           if (attribute_flag[1] != 0)
9689             geometry_info.rho=argument_list[1].real_reference;
9690           if (attribute_flag[2] != 0)
9691             geometry_info.sigma=argument_list[2].real_reference;
9692           if (attribute_flag[3] != 0)
9693             geometry_info.xi=argument_list[3].real_reference;
9694           if (attribute_flag[4] != 0)
9695             geometry_info.psi=argument_list[4].real_reference;
9696           if (attribute_flag[5] != 0)
9697             channel=(ChannelType) argument_list[5].integer_reference;
9698           channel_mask=SetImageChannelMask(image,channel);
9699           image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9700             geometry_info.xi,geometry_info.psi,exception);
9701           if (image != (Image *) NULL)
9702             (void) SetImageChannelMask(image,channel_mask);
9703           break;
9704         }
9705         case 70:  /* MotionBlur */
9706         {
9707           if (attribute_flag[0] != 0)
9708             {
9709               flags=ParseGeometry(argument_list[0].string_reference,
9710                 &geometry_info);
9711               if ((flags & SigmaValue) == 0)
9712                 geometry_info.sigma=1.0;
9713               if ((flags & XiValue) == 0)
9714                 geometry_info.xi=1.0;
9715             }
9716           if (attribute_flag[1] != 0)
9717             geometry_info.rho=argument_list[1].real_reference;
9718           if (attribute_flag[2] != 0)
9719             geometry_info.sigma=argument_list[2].real_reference;
9720           if (attribute_flag[3] != 0)
9721             geometry_info.xi=argument_list[3].real_reference;
9722           if (attribute_flag[4] != 0)
9723             channel=(ChannelType) argument_list[4].integer_reference;
9724           channel_mask=SetImageChannelMask(image,channel);
9725           image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9726             geometry_info.xi,exception);
9727           if (image != (Image *) NULL)
9728             (void) SetImageChannelMask(image,channel_mask);
9729           break;
9730         }
9731         case 71:  /* OrderedDither */
9732         {
9733           if (attribute_flag[0] == 0)
9734             argument_list[0].string_reference="o8x8";
9735           if (attribute_flag[1] != 0)
9736             channel=(ChannelType) argument_list[1].integer_reference;
9737           channel_mask=SetImageChannelMask(image,channel);
9738           (void) OrderedDitherImage(image,argument_list[0].string_reference,
9739             exception);
9740           (void) SetImageChannelMask(image,channel_mask);
9741           break;
9742         }
9743         case 72:  /* Shave */
9744         {
9745           if (attribute_flag[0] != 0)
9746             flags=ParsePageGeometry(image,argument_list[0].string_reference,
9747               &geometry,exception);
9748           if (attribute_flag[1] != 0)
9749             geometry.width=argument_list[1].integer_reference;
9750           if (attribute_flag[2] != 0)
9751             geometry.height=argument_list[2].integer_reference;
9752           image=ShaveImage(image,&geometry,exception);
9753           break;
9754         }
9755         case 73:  /* Level */
9756         {
9757           double
9758             black_point,
9759             gamma,
9760             white_point;
9761 
9762           black_point=0.0;
9763           white_point=(double) image->columns*image->rows;
9764           gamma=1.0;
9765           if (attribute_flag[0] != 0)
9766             {
9767               flags=ParseGeometry(argument_list[0].string_reference,
9768                 &geometry_info);
9769               black_point=geometry_info.rho;
9770               if ((flags & SigmaValue) != 0)
9771                 white_point=geometry_info.sigma;
9772               if ((flags & XiValue) != 0)
9773                 gamma=geometry_info.xi;
9774               if ((flags & PercentValue) != 0)
9775                 {
9776                   black_point*=(double) (QuantumRange/100.0);
9777                   white_point*=(double) (QuantumRange/100.0);
9778                 }
9779               if ((flags & SigmaValue) == 0)
9780                 white_point=(double) QuantumRange-black_point;
9781             }
9782           if (attribute_flag[1] != 0)
9783             black_point=argument_list[1].real_reference;
9784           if (attribute_flag[2] != 0)
9785             white_point=argument_list[2].real_reference;
9786           if (attribute_flag[3] != 0)
9787             gamma=argument_list[3].real_reference;
9788           if (attribute_flag[4] != 0)
9789             channel=(ChannelType) argument_list[4].integer_reference;
9790           if (attribute_flag[5] != 0)
9791             {
9792               argument_list[0].real_reference=argument_list[5].real_reference;
9793               attribute_flag[0]=attribute_flag[5];
9794             }
9795           channel_mask=SetImageChannelMask(image,channel);
9796           (void) LevelImage(image,black_point,white_point,gamma,exception);
9797           (void) SetImageChannelMask(image,channel_mask);
9798           break;
9799         }
9800         case 74:  /* Clip */
9801         {
9802           if (attribute_flag[0] == 0)
9803             argument_list[0].string_reference="#1";
9804           if (attribute_flag[1] == 0)
9805             argument_list[1].integer_reference=MagickTrue;
9806           (void) ClipImagePath(image,argument_list[0].string_reference,
9807             argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9808             exception);
9809           break;
9810         }
9811         case 75:  /* AffineTransform */
9812         {
9813           DrawInfo
9814             *draw_info;
9815 
9816           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9817             (DrawInfo *) NULL);
9818           if (attribute_flag[0] != 0)
9819             {
9820               AV
9821                 *av;
9822 
9823               av=(AV *) argument_list[0].array_reference;
9824               if ((av_len(av) != 3) && (av_len(av) != 5))
9825                 {
9826                   ThrowPerlException(exception,OptionError,
9827                     "affine matrix must have 4 or 6 elements",PackageName);
9828                   goto PerlException;
9829                 }
9830               draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9831               draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9832               draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9833               draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9834               if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9835                   draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9836                 {
9837                   ThrowPerlException(exception,OptionError,
9838                     "affine matrix is singular",PackageName);
9839                    goto PerlException;
9840                 }
9841               if (av_len(av) == 5)
9842                 {
9843                   draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9844                   draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9845                 }
9846             }
9847           for (j=1; j < 6; j++)
9848           {
9849             if (attribute_flag[j] == 0)
9850               continue;
9851             value=argument_list[j].string_reference;
9852             angle=argument_list[j].real_reference;
9853             current=draw_info->affine;
9854             GetAffineMatrix(&affine);
9855             switch (j)
9856             {
9857               case 1:
9858               {
9859                 /*
9860                   Translate.
9861                 */
9862                 flags=ParseGeometry(value,&geometry_info);
9863                 affine.tx=geometry_info.xi;
9864                 affine.ty=geometry_info.psi;
9865                 if ((flags & PsiValue) == 0)
9866                   affine.ty=affine.tx;
9867                 break;
9868               }
9869               case 2:
9870               {
9871                 /*
9872                   Scale.
9873                 */
9874                 flags=ParseGeometry(value,&geometry_info);
9875                 affine.sx=geometry_info.rho;
9876                 affine.sy=geometry_info.sigma;
9877                 if ((flags & SigmaValue) == 0)
9878                   affine.sy=affine.sx;
9879                 break;
9880               }
9881               case 3:
9882               {
9883                 /*
9884                   Rotate.
9885                 */
9886                 if (angle == 0.0)
9887                   break;
9888                 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9889                 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9890                 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9891                 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9892                 break;
9893               }
9894               case 4:
9895               {
9896                 /*
9897                   SkewX.
9898                 */
9899                 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9900                 break;
9901               }
9902               case 5:
9903               {
9904                 /*
9905                   SkewY.
9906                 */
9907                 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9908                 break;
9909               }
9910             }
9911             draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9912             draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9913             draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9914             draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9915             draw_info->affine.tx=
9916               current.sx*affine.tx+current.ry*affine.ty+current.tx;
9917             draw_info->affine.ty=
9918               current.rx*affine.tx+current.sy*affine.ty+current.ty;
9919           }
9920           if (attribute_flag[6] != 0)
9921             image->interpolate=(PixelInterpolateMethod)
9922               argument_list[6].integer_reference;
9923           if (attribute_flag[7] != 0)
9924             QueryColorCompliance(argument_list[7].string_reference,
9925               AllCompliance,&image->background_color,exception);
9926           image=AffineTransformImage(image,&draw_info->affine,exception);
9927           draw_info=DestroyDrawInfo(draw_info);
9928           break;
9929         }
9930         case 76:  /* Difference */
9931         {
9932           if (attribute_flag[0] == 0)
9933             {
9934               ThrowPerlException(exception,OptionError,
9935                 "ReferenceImageRequired",PackageName);
9936               goto PerlException;
9937             }
9938           if (attribute_flag[1] != 0)
9939             image->fuzz=StringToDoubleInterval(
9940               argument_list[1].string_reference,(double) QuantumRange+1.0);
9941           (void) SetImageColorMetric(image,argument_list[0].image_reference,
9942             exception);
9943           break;
9944         }
9945         case 77:  /* AdaptiveThreshold */
9946         {
9947           if (attribute_flag[0] != 0)
9948             {
9949               flags=ParseGeometry(argument_list[0].string_reference,
9950                 &geometry_info);
9951               if ((flags & PercentValue) != 0)
9952                 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
9953             }
9954           if (attribute_flag[1] != 0)
9955             geometry_info.rho=argument_list[1].integer_reference;
9956           if (attribute_flag[2] != 0)
9957             geometry_info.sigma=argument_list[2].integer_reference;
9958           if (attribute_flag[3] != 0)
9959             geometry_info.xi=argument_list[3].integer_reference;;
9960           image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
9961             (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
9962           break;
9963         }
9964         case 78:  /* Resample */
9965         {
9966           size_t
9967             height,
9968             width;
9969 
9970           if (attribute_flag[0] != 0)
9971             {
9972               flags=ParseGeometry(argument_list[0].string_reference,
9973                 &geometry_info);
9974               if ((flags & SigmaValue) == 0)
9975                 geometry_info.sigma=geometry_info.rho;
9976             }
9977           if (attribute_flag[1] != 0)
9978             geometry_info.rho=argument_list[1].real_reference;
9979           if (attribute_flag[2] != 0)
9980             geometry_info.sigma=argument_list[2].real_reference;
9981           if (attribute_flag[3] == 0)
9982             argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
9983           if (attribute_flag[4] == 0)
9984             SetImageArtifact(image,"filter:support",
9985               argument_list[4].string_reference);
9986           width=(size_t) (geometry_info.rho*image->columns/
9987             (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
9988           height=(size_t) (geometry_info.sigma*image->rows/
9989             (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
9990           image=ResizeImage(image,width,height,(FilterType)
9991             argument_list[3].integer_reference,exception);
9992           if (image != (Image *) NULL)
9993             {
9994               image->resolution.x=geometry_info.rho;
9995               image->resolution.y=geometry_info.sigma;
9996             }
9997           break;
9998         }
9999         case 79:  /* Describe */
10000         {
10001           if (attribute_flag[0] == 0)
10002             argument_list[0].file_reference=(FILE *) NULL;
10003           if (attribute_flag[1] != 0)
10004             (void) SetImageArtifact(image,"identify:features",
10005               argument_list[1].string_reference);
10006           (void) IdentifyImage(image,argument_list[0].file_reference,
10007             MagickTrue,exception);
10008           break;
10009         }
10010         case 80:  /* BlackThreshold */
10011         {
10012           if (attribute_flag[0] == 0)
10013             argument_list[0].string_reference="50%";
10014           if (attribute_flag[2] != 0)
10015             channel=(ChannelType) argument_list[2].integer_reference;
10016           channel_mask=SetImageChannelMask(image,channel);
10017           BlackThresholdImage(image,argument_list[0].string_reference,
10018             exception);
10019           (void) SetImageChannelMask(image,channel_mask);
10020           break;
10021         }
10022         case 81:  /* WhiteThreshold */
10023         {
10024           if (attribute_flag[0] == 0)
10025             argument_list[0].string_reference="50%";
10026           if (attribute_flag[2] != 0)
10027             channel=(ChannelType) argument_list[2].integer_reference;
10028           channel_mask=SetImageChannelMask(image,channel);
10029           WhiteThresholdImage(image,argument_list[0].string_reference,
10030             exception);
10031           (void) SetImageChannelMask(image,channel_mask);
10032           break;
10033         }
10034         case 82:  /* RotationalBlur */
10035         {
10036           if (attribute_flag[0] != 0)
10037             {
10038               flags=ParseGeometry(argument_list[0].string_reference,
10039                 &geometry_info);
10040             }
10041           if (attribute_flag[1] != 0)
10042             geometry_info.rho=argument_list[1].real_reference;
10043           if (attribute_flag[2] != 0)
10044             channel=(ChannelType) argument_list[2].integer_reference;
10045           channel_mask=SetImageChannelMask(image,channel);
10046           image=RotationalBlurImage(image,geometry_info.rho,exception);
10047           if (image != (Image *) NULL)
10048             (void) SetImageChannelMask(image,channel_mask);
10049           break;
10050         }
10051         case 83:  /* Thumbnail */
10052         {
10053           if (attribute_flag[0] != 0)
10054             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10055               &geometry,exception);
10056           if (attribute_flag[1] != 0)
10057             geometry.width=argument_list[1].integer_reference;
10058           if (attribute_flag[2] != 0)
10059             geometry.height=argument_list[2].integer_reference;
10060           image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10061           break;
10062         }
10063         case 84:  /* Strip */
10064         {
10065           (void) StripImage(image,exception);
10066           break;
10067         }
10068         case 85:  /* Tint */
10069         {
10070           PixelInfo
10071             tint;
10072 
10073           GetPixelInfo(image,&tint);
10074           if (attribute_flag[0] != 0)
10075             (void) QueryColorCompliance(argument_list[0].string_reference,
10076               AllCompliance,&tint,exception);
10077           if (attribute_flag[1] == 0)
10078             argument_list[1].string_reference="100";
10079           image=TintImage(image,argument_list[1].string_reference,&tint,
10080             exception);
10081           break;
10082         }
10083         case 86:  /* Channel */
10084         {
10085           if (attribute_flag[0] != 0)
10086             channel=(ChannelType) argument_list[0].integer_reference;
10087           image=SeparateImage(image,channel,exception);
10088           break;
10089         }
10090         case 87:  /* Splice */
10091         {
10092           if (attribute_flag[7] != 0)
10093             image->gravity=(GravityType) argument_list[7].integer_reference;
10094           if (attribute_flag[0] != 0)
10095             flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10096               &geometry,exception);
10097           if (attribute_flag[1] != 0)
10098             geometry.width=argument_list[1].integer_reference;
10099           if (attribute_flag[2] != 0)
10100             geometry.height=argument_list[2].integer_reference;
10101           if (attribute_flag[3] != 0)
10102             geometry.x=argument_list[3].integer_reference;
10103           if (attribute_flag[4] != 0)
10104             geometry.y=argument_list[4].integer_reference;
10105           if (attribute_flag[5] != 0)
10106             image->fuzz=StringToDoubleInterval(
10107               argument_list[5].string_reference,(double) QuantumRange+1.0);
10108           if (attribute_flag[6] != 0)
10109             (void) QueryColorCompliance(argument_list[6].string_reference,
10110               AllCompliance,&image->background_color,exception);
10111           image=SpliceImage(image,&geometry,exception);
10112           break;
10113         }
10114         case 88:  /* Posterize */
10115         {
10116           if (attribute_flag[0] == 0)
10117             argument_list[0].integer_reference=3;
10118           if (attribute_flag[1] == 0)
10119             argument_list[1].integer_reference=0;
10120           (void) PosterizeImage(image,argument_list[0].integer_reference,
10121             argument_list[1].integer_reference ? RiemersmaDitherMethod :
10122             NoDitherMethod,exception);
10123           break;
10124         }
10125         case 89:  /* Shadow */
10126         {
10127           if (attribute_flag[0] != 0)
10128             {
10129               flags=ParseGeometry(argument_list[0].string_reference,
10130                 &geometry_info);
10131               if ((flags & SigmaValue) == 0)
10132                 geometry_info.sigma=1.0;
10133               if ((flags & XiValue) == 0)
10134                 geometry_info.xi=4.0;
10135               if ((flags & PsiValue) == 0)
10136                 geometry_info.psi=4.0;
10137             }
10138           if (attribute_flag[1] != 0)
10139             geometry_info.rho=argument_list[1].real_reference;
10140           if (attribute_flag[2] != 0)
10141             geometry_info.sigma=argument_list[2].real_reference;
10142           if (attribute_flag[3] != 0)
10143             geometry_info.xi=argument_list[3].integer_reference;
10144           if (attribute_flag[4] != 0)
10145             geometry_info.psi=argument_list[4].integer_reference;
10146           image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10147             (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10148             ceil(geometry_info.psi-0.5),exception);
10149           break;
10150         }
10151         case 90:  /* Identify */
10152         {
10153           if (attribute_flag[0] == 0)
10154             argument_list[0].file_reference=(FILE *) NULL;
10155           if (attribute_flag[1] != 0)
10156             (void) SetImageArtifact(image,"identify:features",
10157               argument_list[1].string_reference);
10158           if ((attribute_flag[2] != 0) &&
10159               (argument_list[2].integer_reference != 0))
10160             (void) SetImageArtifact(image,"identify:unique","true");
10161           (void) IdentifyImage(image,argument_list[0].file_reference,
10162             MagickTrue,exception);
10163           break;
10164         }
10165         case 91:  /* SepiaTone */
10166         {
10167           if (attribute_flag[0] == 0)
10168             argument_list[0].real_reference=80.0*QuantumRange/100.0;
10169           image=SepiaToneImage(image,argument_list[0].real_reference,
10170             exception);
10171           break;
10172         }
10173         case 92:  /* SigmoidalContrast */
10174         {
10175           MagickBooleanType
10176             sharpen;
10177 
10178           if (attribute_flag[0] != 0)
10179             {
10180               flags=ParseGeometry(argument_list[0].string_reference,
10181                 &geometry_info);
10182               if ((flags & SigmaValue) == 0)
10183                 geometry_info.sigma=QuantumRange/2.0;
10184               if ((flags & PercentValue) != 0)
10185                 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10186             }
10187           if (attribute_flag[1] != 0)
10188             geometry_info.rho=argument_list[1].real_reference;
10189           if (attribute_flag[2] != 0)
10190             geometry_info.sigma=argument_list[2].real_reference;
10191           if (attribute_flag[3] != 0)
10192             channel=(ChannelType) argument_list[3].integer_reference;
10193           sharpen=MagickTrue;
10194           if (attribute_flag[4] != 0)
10195             sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10196               MagickFalse;
10197           channel_mask=SetImageChannelMask(image,channel);
10198           (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10199             geometry_info.sigma,exception);
10200           (void) SetImageChannelMask(image,channel_mask);
10201           break;
10202         }
10203         case 93:  /* Extent */
10204         {
10205           if (attribute_flag[7] != 0)
10206             image->gravity=(GravityType) argument_list[7].integer_reference;
10207           if (attribute_flag[0] != 0)
10208             {
10209               int
10210                 flags;
10211 
10212               flags=ParseGravityGeometry(image,
10213                 argument_list[0].string_reference,&geometry,exception);
10214               (void) flags;
10215               if (geometry.width == 0)
10216                 geometry.width=image->columns;
10217               if (geometry.height == 0)
10218                 geometry.height=image->rows;
10219             }
10220           if (attribute_flag[1] != 0)
10221             geometry.width=argument_list[1].integer_reference;
10222           if (attribute_flag[2] != 0)
10223             geometry.height=argument_list[2].integer_reference;
10224           if (attribute_flag[3] != 0)
10225             geometry.x=argument_list[3].integer_reference;
10226           if (attribute_flag[4] != 0)
10227             geometry.y=argument_list[4].integer_reference;
10228           if (attribute_flag[5] != 0)
10229             image->fuzz=StringToDoubleInterval(
10230               argument_list[5].string_reference,(double) QuantumRange+1.0);
10231           if (attribute_flag[6] != 0)
10232             (void) QueryColorCompliance(argument_list[6].string_reference,
10233               AllCompliance,&image->background_color,exception);
10234           image=ExtentImage(image,&geometry,exception);
10235           break;
10236         }
10237         case 94:  /* Vignette */
10238         {
10239           if (attribute_flag[0] != 0)
10240             {
10241               flags=ParseGeometry(argument_list[0].string_reference,
10242                 &geometry_info);
10243               if ((flags & SigmaValue) == 0)
10244                 geometry_info.sigma=1.0;
10245               if ((flags & XiValue) == 0)
10246                 geometry_info.xi=0.1*image->columns;
10247               if ((flags & PsiValue) == 0)
10248                 geometry_info.psi=0.1*image->rows;
10249             }
10250           if (attribute_flag[1] != 0)
10251             geometry_info.rho=argument_list[1].real_reference;
10252           if (attribute_flag[2] != 0)
10253             geometry_info.sigma=argument_list[2].real_reference;
10254           if (attribute_flag[3] != 0)
10255             geometry_info.xi=argument_list[3].integer_reference;
10256           if (attribute_flag[4] != 0)
10257             geometry_info.psi=argument_list[4].integer_reference;
10258           if (attribute_flag[5] != 0)
10259             (void) QueryColorCompliance(argument_list[5].string_reference,
10260               AllCompliance,&image->background_color,exception);
10261           image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10262             (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10263             ceil(geometry_info.psi-0.5),exception);
10264           break;
10265         }
10266         case 95:  /* ContrastStretch */
10267         {
10268           double
10269             black_point,
10270             white_point;
10271 
10272           black_point=0.0;
10273           white_point=(double) image->columns*image->rows;
10274           if (attribute_flag[0] != 0)
10275             {
10276               flags=ParseGeometry(argument_list[0].string_reference,
10277                 &geometry_info);
10278               black_point=geometry_info.rho;
10279               white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10280                 black_point;
10281               if ((flags & PercentValue) != 0)
10282                 {
10283                   black_point*=(double) image->columns*image->rows/100.0;
10284                   white_point*=(double) image->columns*image->rows/100.0;
10285                 }
10286               white_point=(double) image->columns*image->rows-
10287                 white_point;
10288             }
10289           if (attribute_flag[1] != 0)
10290             black_point=argument_list[1].real_reference;
10291           if (attribute_flag[2] != 0)
10292             white_point=argument_list[2].real_reference;
10293           if (attribute_flag[4] != 0)
10294             channel=(ChannelType) argument_list[4].integer_reference;
10295           channel_mask=SetImageChannelMask(image,channel);
10296           (void) ContrastStretchImage(image,black_point,white_point,exception);
10297           (void) SetImageChannelMask(image,channel_mask);
10298           break;
10299         }
10300         case 96:  /* Sans0 */
10301         {
10302           break;
10303         }
10304         case 97:  /* Sans1 */
10305         {
10306           break;
10307         }
10308         case 98:  /* AdaptiveSharpen */
10309         {
10310           if (attribute_flag[0] != 0)
10311             {
10312               flags=ParseGeometry(argument_list[0].string_reference,
10313                 &geometry_info);
10314               if ((flags & SigmaValue) == 0)
10315                 geometry_info.sigma=1.0;
10316               if ((flags & XiValue) == 0)
10317                 geometry_info.xi=0.0;
10318             }
10319           if (attribute_flag[1] != 0)
10320             geometry_info.rho=argument_list[1].real_reference;
10321           if (attribute_flag[2] != 0)
10322             geometry_info.sigma=argument_list[2].real_reference;
10323           if (attribute_flag[3] != 0)
10324             geometry_info.xi=argument_list[3].real_reference;
10325           if (attribute_flag[4] != 0)
10326             channel=(ChannelType) argument_list[4].integer_reference;
10327           channel_mask=SetImageChannelMask(image,channel);
10328           image=AdaptiveSharpenImage(image,geometry_info.rho,
10329             geometry_info.sigma,exception);
10330           if (image != (Image *) NULL)
10331             (void) SetImageChannelMask(image,channel_mask);
10332           break;
10333         }
10334         case 99:  /* Transpose */
10335         {
10336           image=TransposeImage(image,exception);
10337           break;
10338         }
10339         case 100:  /* Tranverse */
10340         {
10341           image=TransverseImage(image,exception);
10342           break;
10343         }
10344         case 101:  /* AutoOrient */
10345         {
10346           image=AutoOrientImage(image,image->orientation,exception);
10347           break;
10348         }
10349         case 102:  /* AdaptiveBlur */
10350         {
10351           if (attribute_flag[0] != 0)
10352             {
10353               flags=ParseGeometry(argument_list[0].string_reference,
10354                 &geometry_info);
10355               if ((flags & SigmaValue) == 0)
10356                 geometry_info.sigma=1.0;
10357               if ((flags & XiValue) == 0)
10358                 geometry_info.xi=0.0;
10359             }
10360           if (attribute_flag[1] != 0)
10361             geometry_info.rho=argument_list[1].real_reference;
10362           if (attribute_flag[2] != 0)
10363             geometry_info.sigma=argument_list[2].real_reference;
10364           if (attribute_flag[3] != 0)
10365             channel=(ChannelType) argument_list[3].integer_reference;
10366           channel_mask=SetImageChannelMask(image,channel);
10367           image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10368             exception);
10369           if (image != (Image *) NULL)
10370             (void) SetImageChannelMask(image,channel_mask);
10371           break;
10372         }
10373         case 103:  /* Sketch */
10374         {
10375           if (attribute_flag[0] != 0)
10376             {
10377               flags=ParseGeometry(argument_list[0].string_reference,
10378                 &geometry_info);
10379               if ((flags & SigmaValue) == 0)
10380                 geometry_info.sigma=1.0;
10381               if ((flags & XiValue) == 0)
10382                 geometry_info.xi=1.0;
10383             }
10384           if (attribute_flag[1] != 0)
10385             geometry_info.rho=argument_list[1].real_reference;
10386           if (attribute_flag[2] != 0)
10387             geometry_info.sigma=argument_list[2].real_reference;
10388           if (attribute_flag[3] != 0)
10389             geometry_info.xi=argument_list[3].real_reference;
10390           image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10391             geometry_info.xi,exception);
10392           break;
10393         }
10394         case 104:  /* UniqueColors */
10395         {
10396           image=UniqueImageColors(image,exception);
10397           break;
10398         }
10399         case 105:  /* AdaptiveResize */
10400         {
10401           if (attribute_flag[0] != 0)
10402             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10403               &geometry,exception);
10404           if (attribute_flag[1] != 0)
10405             geometry.width=argument_list[1].integer_reference;
10406           if (attribute_flag[2] != 0)
10407             geometry.height=argument_list[2].integer_reference;
10408           if (attribute_flag[3] != 0)
10409             image->filter=(FilterType) argument_list[4].integer_reference;
10410           if (attribute_flag[4] != 0)
10411             SetImageArtifact(image,"filter:support",
10412               argument_list[4].string_reference);
10413           image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10414             exception);
10415           break;
10416         }
10417         case 106:  /* ClipMask */
10418         {
10419           Image
10420             *mask_image;
10421 
10422           if (attribute_flag[0] == 0)
10423             {
10424               ThrowPerlException(exception,OptionError,"MaskImageRequired",
10425                 PackageName);
10426               goto PerlException;
10427             }
10428           mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10429             exception);
10430           (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
10431           mask_image=DestroyImage(mask_image);
10432           break;
10433         }
10434         case 107:  /* LinearStretch */
10435         {
10436            double
10437              black_point,
10438              white_point;
10439 
10440            black_point=0.0;
10441            white_point=(double) image->columns*image->rows;
10442            if (attribute_flag[0] != 0)
10443              {
10444                flags=ParseGeometry(argument_list[0].string_reference,
10445                  &geometry_info);
10446                if ((flags & SigmaValue) != 0)
10447                   white_point=geometry_info.sigma;
10448                if ((flags & PercentValue) != 0)
10449                  {
10450                    black_point*=(double) image->columns*image->rows/100.0;
10451                    white_point*=(double) image->columns*image->rows/100.0;
10452                  }
10453                if ((flags & SigmaValue) == 0)
10454                  white_point=(double) image->columns*image->rows-black_point;
10455              }
10456           if (attribute_flag[1] != 0)
10457             black_point=argument_list[1].real_reference;
10458           if (attribute_flag[2] != 0)
10459             white_point=argument_list[2].real_reference;
10460           (void) LinearStretchImage(image,black_point,white_point,exception);
10461           break;
10462         }
10463         case 108:  /* ColorMatrix */
10464         {
10465           AV
10466             *av;
10467 
10468           double
10469             *color_matrix;
10470 
10471           KernelInfo
10472             *kernel_info;
10473 
10474           size_t
10475             order;
10476 
10477           if (attribute_flag[0] == 0)
10478             break;
10479           av=(AV *) argument_list[0].array_reference;
10480           order=(size_t) sqrt(av_len(av)+1);
10481           color_matrix=(double *) AcquireQuantumMemory(order,order*
10482             sizeof(*color_matrix));
10483           if (color_matrix == (double *) NULL)
10484             {
10485               ThrowPerlException(exception,ResourceLimitFatalError,
10486                 "MemoryAllocationFailed",PackageName);
10487               goto PerlException;
10488            }
10489           for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10490             color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10491           for ( ; j < (ssize_t) (order*order); j++)
10492             color_matrix[j]=0.0;
10493           kernel_info=AcquireKernelInfo((const char *) NULL,exception);
10494           if (kernel_info == (KernelInfo *) NULL)
10495             break;
10496           kernel_info->width=order;
10497           kernel_info->height=order;
10498           kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10499             order*sizeof(*kernel_info->values));
10500           if (kernel_info->values != (MagickRealType *) NULL)
10501             {
10502               for (i=0; i < (ssize_t) (order*order); i++)
10503                 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10504               image=ColorMatrixImage(image,kernel_info,exception);
10505             }
10506           kernel_info=DestroyKernelInfo(kernel_info);
10507           color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10508           break;
10509         }
10510         case 109:  /* Mask */
10511         {
10512           Image
10513             *mask_image;
10514 
10515           if (attribute_flag[0] == 0)
10516             {
10517               ThrowPerlException(exception,OptionError,"MaskImageRequired",
10518                 PackageName);
10519               goto PerlException;
10520             }
10521           mask_image=CloneImage(argument_list[0].image_reference,0,0,
10522             MagickTrue,exception);
10523           (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
10524           mask_image=DestroyImage(mask_image);
10525           break;
10526         }
10527         case 110:  /* Polaroid */
10528         {
10529           char
10530             *caption;
10531 
10532           DrawInfo
10533             *draw_info;
10534 
10535           double
10536             angle;
10537 
10538           PixelInterpolateMethod
10539             method;
10540 
10541           draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10542             (DrawInfo *) NULL);
10543           caption=(char *) NULL;
10544           if (attribute_flag[0] != 0)
10545             caption=InterpretImageProperties(info ? info->image_info :
10546               (ImageInfo *) NULL,image,argument_list[0].string_reference,
10547               exception);
10548           angle=0.0;
10549           if (attribute_flag[1] != 0)
10550             angle=argument_list[1].real_reference;
10551           if (attribute_flag[2] != 0)
10552             (void) CloneString(&draw_info->font,
10553               argument_list[2].string_reference);
10554           if (attribute_flag[3] != 0)
10555             (void) QueryColorCompliance(argument_list[3].string_reference,
10556               AllCompliance,&draw_info->stroke,exception);
10557           if (attribute_flag[4] != 0)
10558             (void) QueryColorCompliance(argument_list[4].string_reference,
10559               AllCompliance,&draw_info->fill,exception);
10560           if (attribute_flag[5] != 0)
10561             draw_info->stroke_width=argument_list[5].real_reference;
10562           if (attribute_flag[6] != 0)
10563             draw_info->pointsize=argument_list[6].real_reference;
10564           if (attribute_flag[7] != 0)
10565             draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10566           if (attribute_flag[8] != 0)
10567             (void) QueryColorCompliance(argument_list[8].string_reference,
10568               AllCompliance,&image->background_color,exception);
10569           method=UndefinedInterpolatePixel;
10570           if (attribute_flag[9] != 0)
10571             method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10572           image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10573           draw_info=DestroyDrawInfo(draw_info);
10574           if (caption != (char *) NULL)
10575             caption=DestroyString(caption);
10576           break;
10577         }
10578         case 111:  /* FloodfillPaint */
10579         {
10580           DrawInfo
10581             *draw_info;
10582 
10583           MagickBooleanType
10584             invert;
10585 
10586           PixelInfo
10587             target;
10588 
10589           draw_info=CloneDrawInfo(info ? info->image_info :
10590             (ImageInfo *) NULL,(DrawInfo *) NULL);
10591           if (attribute_flag[0] != 0)
10592             flags=ParsePageGeometry(image,argument_list[0].string_reference,
10593               &geometry,exception);
10594           if (attribute_flag[1] != 0)
10595             geometry.x=argument_list[1].integer_reference;
10596           if (attribute_flag[2] != 0)
10597             geometry.y=argument_list[2].integer_reference;
10598           if (attribute_flag[3] != 0)
10599             (void) QueryColorCompliance(argument_list[3].string_reference,
10600               AllCompliance,&draw_info->fill,exception);
10601           (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10602             geometry.x,geometry.y,&target,exception);
10603           if (attribute_flag[4] != 0)
10604             QueryColorCompliance(argument_list[4].string_reference,
10605               AllCompliance,&target,exception);
10606           if (attribute_flag[5] != 0)
10607             image->fuzz=StringToDoubleInterval(
10608               argument_list[5].string_reference,(double) QuantumRange+1.0);
10609           if (attribute_flag[6] != 0)
10610             channel=(ChannelType) argument_list[6].integer_reference;
10611           invert=MagickFalse;
10612           if (attribute_flag[7] != 0)
10613             invert=(MagickBooleanType) argument_list[7].integer_reference;
10614           channel_mask=SetImageChannelMask(image,channel);
10615           (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10616             geometry.y,invert,exception);
10617           (void) SetImageChannelMask(image,channel_mask);
10618           draw_info=DestroyDrawInfo(draw_info);
10619           break;
10620         }
10621         case 112:  /* Distort */
10622         {
10623           AV
10624             *av;
10625 
10626           double
10627             *coordinates;
10628 
10629           DistortMethod
10630             method;
10631 
10632           size_t
10633             number_coordinates;
10634 
10635           VirtualPixelMethod
10636             virtual_pixel;
10637 
10638           if (attribute_flag[0] == 0)
10639             break;
10640           method=UndefinedDistortion;
10641           if (attribute_flag[1] != 0)
10642             method=(DistortMethod) argument_list[1].integer_reference;
10643           av=(AV *) argument_list[0].array_reference;
10644           number_coordinates=(size_t) av_len(av)+1;
10645           coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10646             sizeof(*coordinates));
10647           if (coordinates == (double *) NULL)
10648             {
10649               ThrowPerlException(exception,ResourceLimitFatalError,
10650                 "MemoryAllocationFailed",PackageName);
10651               goto PerlException;
10652             }
10653           for (j=0; j < (ssize_t) number_coordinates; j++)
10654             coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10655           virtual_pixel=UndefinedVirtualPixelMethod;
10656           if (attribute_flag[2] != 0)
10657             virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10658               argument_list[2].integer_reference,exception);
10659           image=DistortImage(image,method,number_coordinates,coordinates,
10660             argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10661             exception);
10662           if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10663             virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10664               exception);
10665           coordinates=(double *) RelinquishMagickMemory(coordinates);
10666           break;
10667         }
10668         case 113:  /* Clut */
10669         {
10670           PixelInterpolateMethod
10671             method;
10672 
10673           if (attribute_flag[0] == 0)
10674             {
10675               ThrowPerlException(exception,OptionError,"ClutImageRequired",
10676                 PackageName);
10677               goto PerlException;
10678             }
10679           method=UndefinedInterpolatePixel;
10680           if (attribute_flag[1] != 0)
10681             method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10682           if (attribute_flag[2] != 0)
10683             channel=(ChannelType) argument_list[2].integer_reference;
10684           channel_mask=SetImageChannelMask(image,channel);
10685           (void) ClutImage(image,argument_list[0].image_reference,method,
10686             exception);
10687           (void) SetImageChannelMask(image,channel_mask);
10688           break;
10689         }
10690         case 114:  /* LiquidRescale */
10691         {
10692           if (attribute_flag[0] != 0)
10693             flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10694               &geometry,exception);
10695           if (attribute_flag[1] != 0)
10696             geometry.width=argument_list[1].integer_reference;
10697           if (attribute_flag[2] != 0)
10698             geometry.height=argument_list[2].integer_reference;
10699           if (attribute_flag[3] == 0)
10700             argument_list[3].real_reference=1.0;
10701           if (attribute_flag[4] == 0)
10702             argument_list[4].real_reference=0.0;
10703           image=LiquidRescaleImage(image,geometry.width,geometry.height,
10704             argument_list[3].real_reference,argument_list[4].real_reference,
10705             exception);
10706           break;
10707         }
10708         case 115:  /* EncipherImage */
10709         {
10710           (void) EncipherImage(image,argument_list[0].string_reference,
10711             exception);
10712           break;
10713         }
10714         case 116:  /* DecipherImage */
10715         {
10716           (void) DecipherImage(image,argument_list[0].string_reference,
10717             exception);
10718           break;
10719         }
10720         case 117:  /* Deskew */
10721         {
10722           geometry_info.rho=QuantumRange/2.0;
10723           if (attribute_flag[0] != 0)
10724             flags=ParseGeometry(argument_list[0].string_reference,
10725               &geometry_info);
10726           if (attribute_flag[1] != 0)
10727             geometry_info.rho=StringToDoubleInterval(
10728               argument_list[1].string_reference,(double) QuantumRange+1.0);
10729           image=DeskewImage(image,geometry_info.rho,exception);
10730           break;
10731         }
10732         case 118:  /* Remap */
10733         {
10734           QuantizeInfo
10735             *quantize_info;
10736 
10737           if (attribute_flag[0] == 0)
10738             {
10739               ThrowPerlException(exception,OptionError,"RemapImageRequired",
10740                 PackageName);
10741               goto PerlException;
10742             }
10743           quantize_info=AcquireQuantizeInfo(info->image_info);
10744           if (attribute_flag[1] != 0)
10745             quantize_info->dither_method=(DitherMethod)
10746               argument_list[1].integer_reference;
10747           (void) RemapImages(quantize_info,image,
10748             argument_list[0].image_reference,exception);
10749           quantize_info=DestroyQuantizeInfo(quantize_info);
10750           break;
10751         }
10752         case 119:  /* SparseColor */
10753         {
10754           AV
10755             *av;
10756 
10757           double
10758             *coordinates;
10759 
10760           SparseColorMethod
10761             method;
10762 
10763           size_t
10764             number_coordinates;
10765 
10766           VirtualPixelMethod
10767             virtual_pixel;
10768 
10769           if (attribute_flag[0] == 0)
10770             break;
10771           method=UndefinedColorInterpolate;
10772           if (attribute_flag[1] != 0)
10773             method=(SparseColorMethod) argument_list[1].integer_reference;
10774           av=(AV *) argument_list[0].array_reference;
10775           number_coordinates=(size_t) av_len(av)+1;
10776           coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10777             sizeof(*coordinates));
10778           if (coordinates == (double *) NULL)
10779             {
10780               ThrowPerlException(exception,ResourceLimitFatalError,
10781                 "MemoryAllocationFailed",PackageName);
10782               goto PerlException;
10783             }
10784           for (j=0; j < (ssize_t) number_coordinates; j++)
10785             coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10786           virtual_pixel=UndefinedVirtualPixelMethod;
10787           if (attribute_flag[2] != 0)
10788             virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10789               argument_list[2].integer_reference,exception);
10790           if (attribute_flag[3] != 0)
10791             channel=(ChannelType) argument_list[3].integer_reference;
10792           channel_mask=SetImageChannelMask(image,channel);
10793           image=SparseColorImage(image,method,number_coordinates,coordinates,
10794             exception);
10795           if (image != (Image *) NULL)
10796             (void) SetImageChannelMask(image,channel_mask);
10797           if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10798             virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10799               exception);
10800           coordinates=(double *) RelinquishMagickMemory(coordinates);
10801           break;
10802         }
10803         case 120:  /* Function */
10804         {
10805           AV
10806             *av;
10807 
10808           double
10809             *parameters;
10810 
10811           MagickFunction
10812             function;
10813 
10814           size_t
10815             number_parameters;
10816 
10817           VirtualPixelMethod
10818             virtual_pixel;
10819 
10820           if (attribute_flag[0] == 0)
10821             break;
10822           function=UndefinedFunction;
10823           if (attribute_flag[1] != 0)
10824             function=(MagickFunction) argument_list[1].integer_reference;
10825           av=(AV *) argument_list[0].array_reference;
10826           number_parameters=(size_t) av_len(av)+1;
10827           parameters=(double *) AcquireQuantumMemory(number_parameters,
10828             sizeof(*parameters));
10829           if (parameters == (double *) NULL)
10830             {
10831               ThrowPerlException(exception,ResourceLimitFatalError,
10832                 "MemoryAllocationFailed",PackageName);
10833               goto PerlException;
10834             }
10835           for (j=0; j < (ssize_t) number_parameters; j++)
10836             parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10837           virtual_pixel=UndefinedVirtualPixelMethod;
10838           if (attribute_flag[2] != 0)
10839             virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10840               argument_list[2].integer_reference,exception);
10841           (void) FunctionImage(image,function,number_parameters,parameters,
10842             exception);
10843           if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10844             virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10845               exception);
10846           parameters=(double *) RelinquishMagickMemory(parameters);
10847           break;
10848         }
10849         case 121:  /* SelectiveBlur */
10850         {
10851           if (attribute_flag[0] != 0)
10852             {
10853               flags=ParseGeometry(argument_list[0].string_reference,
10854                 &geometry_info);
10855               if ((flags & SigmaValue) == 0)
10856                 geometry_info.sigma=1.0;
10857               if ((flags & PercentValue) != 0)
10858                 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10859             }
10860           if (attribute_flag[1] != 0)
10861             geometry_info.rho=argument_list[1].real_reference;
10862           if (attribute_flag[2] != 0)
10863             geometry_info.sigma=argument_list[2].real_reference;
10864           if (attribute_flag[3] != 0)
10865             geometry_info.xi=argument_list[3].integer_reference;;
10866           if (attribute_flag[5] != 0)
10867             channel=(ChannelType) argument_list[5].integer_reference;
10868           channel_mask=SetImageChannelMask(image,channel);
10869           image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10870             geometry_info.xi,exception);
10871           if (image != (Image *) NULL)
10872             (void) SetImageChannelMask(image,channel_mask);
10873           break;
10874         }
10875         case 122:  /* HaldClut */
10876         {
10877           if (attribute_flag[0] == 0)
10878             {
10879               ThrowPerlException(exception,OptionError,"ClutImageRequired",
10880                 PackageName);
10881               goto PerlException;
10882             }
10883           if (attribute_flag[1] != 0)
10884             channel=(ChannelType) argument_list[1].integer_reference;
10885           channel_mask=SetImageChannelMask(image,channel);
10886           (void) HaldClutImage(image,argument_list[0].image_reference,
10887             exception);
10888           (void) SetImageChannelMask(image,channel_mask);
10889           break;
10890         }
10891         case 123:  /* BlueShift */
10892         {
10893           if (attribute_flag[0] != 0)
10894             (void) ParseGeometry(argument_list[0].string_reference,
10895               &geometry_info);
10896           image=BlueShiftImage(image,geometry_info.rho,exception);
10897           break;
10898         }
10899         case 124:  /* ForwardFourierTransformImage */
10900         {
10901           image=ForwardFourierTransformImage(image,
10902             argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10903             exception);
10904           break;
10905         }
10906         case 125:  /* InverseFourierTransformImage */
10907         {
10908           image=InverseFourierTransformImage(image,image->next,
10909             argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10910             exception);
10911           break;
10912         }
10913         case 126:  /* ColorDecisionList */
10914         {
10915           if (attribute_flag[0] == 0)
10916             argument_list[0].string_reference=(char *) NULL;
10917           (void) ColorDecisionListImage(image,
10918             argument_list[0].string_reference,exception);
10919           break;
10920         }
10921         case 127:  /* AutoGamma */
10922         {
10923           if (attribute_flag[0] != 0)
10924             channel=(ChannelType) argument_list[0].integer_reference;
10925           channel_mask=SetImageChannelMask(image,channel);
10926           (void) AutoGammaImage(image,exception);
10927           (void) SetImageChannelMask(image,channel_mask);
10928           break;
10929         }
10930         case 128:  /* AutoLevel */
10931         {
10932           if (attribute_flag[0] != 0)
10933             channel=(ChannelType) argument_list[0].integer_reference;
10934           channel_mask=SetImageChannelMask(image,channel);
10935           (void) AutoLevelImage(image,exception);
10936           (void) SetImageChannelMask(image,channel_mask);
10937           break;
10938         }
10939         case 129:  /* LevelColors */
10940         {
10941           PixelInfo
10942             black_point,
10943             white_point;
10944 
10945           (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
10946             exception);
10947           (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
10948             exception);
10949           if (attribute_flag[1] != 0)
10950              (void) QueryColorCompliance(
10951                argument_list[1].string_reference,AllCompliance,&black_point,
10952                exception);
10953           if (attribute_flag[2] != 0)
10954              (void) QueryColorCompliance(
10955                argument_list[2].string_reference,AllCompliance,&white_point,
10956                exception);
10957           if (attribute_flag[3] != 0)
10958             channel=(ChannelType) argument_list[3].integer_reference;
10959           channel_mask=SetImageChannelMask(image,channel);
10960           (void) LevelImageColors(image,&black_point,&white_point,
10961             argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10962             exception);
10963           (void) SetImageChannelMask(image,channel_mask);
10964           break;
10965         }
10966         case 130:  /* Clamp */
10967         {
10968           if (attribute_flag[0] != 0)
10969             channel=(ChannelType) argument_list[0].integer_reference;
10970           channel_mask=SetImageChannelMask(image,channel);
10971           (void) ClampImage(image,exception);
10972           (void) SetImageChannelMask(image,channel_mask);
10973           break;
10974         }
10975         case 131:  /* BrightnessContrast */
10976         {
10977           double
10978             brightness,
10979             contrast;
10980 
10981           brightness=0.0;
10982           contrast=0.0;
10983           if (attribute_flag[0] != 0)
10984             {
10985               flags=ParseGeometry(argument_list[0].string_reference,
10986                 &geometry_info);
10987               brightness=geometry_info.rho;
10988               if ((flags & SigmaValue) == 0)
10989                 contrast=geometry_info.sigma;
10990             }
10991           if (attribute_flag[1] != 0)
10992             brightness=argument_list[1].real_reference;
10993           if (attribute_flag[2] != 0)
10994             contrast=argument_list[2].real_reference;
10995           if (attribute_flag[4] != 0)
10996             channel=(ChannelType) argument_list[4].integer_reference;
10997           channel_mask=SetImageChannelMask(image,channel);
10998           (void) BrightnessContrastImage(image,brightness,contrast,exception);
10999           (void) SetImageChannelMask(image,channel_mask);
11000           break;
11001         }
11002         case 132:  /* Morphology */
11003         {
11004           KernelInfo
11005             *kernel;
11006 
11007           MorphologyMethod
11008             method;
11009 
11010           ssize_t
11011             iterations;
11012 
11013           if (attribute_flag[0] == 0)
11014             break;
11015           kernel=AcquireKernelInfo(argument_list[0].string_reference,exception);
11016           if (kernel == (KernelInfo *) NULL)
11017             break;
11018           if (attribute_flag[1] != 0)
11019             channel=(ChannelType) argument_list[1].integer_reference;
11020           method=UndefinedMorphology;
11021           if (attribute_flag[2] != 0)
11022             method=argument_list[2].integer_reference;
11023           iterations=1;
11024           if (attribute_flag[3] != 0)
11025             iterations=argument_list[3].integer_reference;
11026           channel_mask=SetImageChannelMask(image,channel);
11027           image=MorphologyImage(image,method,iterations,kernel,exception);
11028           if (image != (Image *) NULL)
11029             (void) SetImageChannelMask(image,channel_mask);
11030           kernel=DestroyKernelInfo(kernel);
11031           break;
11032         }
11033         case 133:  /* Mode */
11034         {
11035           if (attribute_flag[0] != 0)
11036             {
11037               flags=ParseGeometry(argument_list[0].string_reference,
11038                 &geometry_info);
11039               if ((flags & SigmaValue) == 0)
11040                 geometry_info.sigma=1.0;
11041             }
11042           if (attribute_flag[1] != 0)
11043             geometry_info.rho=argument_list[1].real_reference;
11044           if (attribute_flag[2] != 0)
11045             geometry_info.sigma=argument_list[2].real_reference;
11046           if (attribute_flag[3] != 0)
11047             channel=(ChannelType) argument_list[3].integer_reference;
11048           channel_mask=SetImageChannelMask(image,channel);
11049           image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11050             (size_t) geometry_info.sigma,exception);
11051           if (image != (Image *) NULL)
11052             (void) SetImageChannelMask(image,channel_mask);
11053           break;
11054         }
11055         case 134:  /* Statistic */
11056         {
11057           StatisticType
11058             statistic;
11059 
11060           statistic=UndefinedStatistic;
11061           if (attribute_flag[0] != 0)
11062             {
11063               flags=ParseGeometry(argument_list[0].string_reference,
11064                 &geometry_info);
11065               if ((flags & SigmaValue) == 0)
11066                 geometry_info.sigma=1.0;
11067             }
11068           if (attribute_flag[1] != 0)
11069             geometry_info.rho=argument_list[1].real_reference;
11070           if (attribute_flag[2] != 0)
11071             geometry_info.sigma=argument_list[2].real_reference;
11072           if (attribute_flag[3] != 0)
11073             channel=(ChannelType) argument_list[3].integer_reference;
11074           if (attribute_flag[4] != 0)
11075             statistic=(StatisticType) argument_list[4].integer_reference;
11076           channel_mask=SetImageChannelMask(image,channel);
11077           image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11078             (size_t) geometry_info.sigma,exception);
11079           if (image != (Image *) NULL)
11080             (void) SetImageChannelMask(image,channel_mask);
11081           break;
11082         }
11083         case 135:  /* Perceptible */
11084         {
11085           double
11086             epsilon;
11087 
11088           epsilon=MagickEpsilon;
11089           if (attribute_flag[0] != 0)
11090             epsilon=argument_list[0].real_reference;
11091           if (attribute_flag[1] != 0)
11092             channel=(ChannelType) argument_list[1].integer_reference;
11093           channel_mask=SetImageChannelMask(image,channel);
11094           (void) PerceptibleImage(image,epsilon,exception);
11095           (void) SetImageChannelMask(image,channel_mask);
11096           break;
11097         }
11098         case 136:  /* Poly */
11099         {
11100           AV
11101             *av;
11102 
11103           double
11104             *terms;
11105 
11106           size_t
11107             number_terms;
11108 
11109           if (attribute_flag[0] == 0)
11110             break;
11111           if (attribute_flag[1] != 0)
11112             channel=(ChannelType) argument_list[1].integer_reference;
11113           av=(AV *) argument_list[0].array_reference;
11114           number_terms=(size_t) av_len(av);
11115           terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11116           if (terms == (double *) NULL)
11117             {
11118               ThrowPerlException(exception,ResourceLimitFatalError,
11119                 "MemoryAllocationFailed",PackageName);
11120               goto PerlException;
11121             }
11122           for (j=0; j < av_len(av); j++)
11123             terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11124           image=PolynomialImage(image,number_terms >> 1,terms,exception);
11125           terms=(double *) RelinquishMagickMemory(terms);
11126           break;
11127         }
11128         case 137:  /* Grayscale */
11129         {
11130           PixelIntensityMethod
11131             method;
11132 
11133           method=UndefinedPixelIntensityMethod;
11134           if (attribute_flag[0] != 0)
11135             method=(PixelIntensityMethod) argument_list[0].integer_reference;
11136           (void) GrayscaleImage(image,method,exception);
11137           break;
11138         }
11139         case 138:  /* Canny */
11140         {
11141           if (attribute_flag[0] != 0)
11142             {
11143               flags=ParseGeometry(argument_list[0].string_reference,
11144                 &geometry_info);
11145               if ((flags & SigmaValue) == 0)
11146                 geometry_info.sigma=1.0;
11147               if ((flags & XiValue) == 0)
11148                 geometry_info.xi=0.10;
11149               if ((flags & PsiValue) == 0)
11150                 geometry_info.psi=0.30;
11151               if ((flags & PercentValue) != 0)
11152                 {
11153                   geometry_info.xi/=100.0;
11154                   geometry_info.psi/=100.0;
11155                 }
11156             }
11157           if (attribute_flag[1] != 0)
11158             geometry_info.rho=argument_list[1].real_reference;
11159           if (attribute_flag[2] != 0)
11160             geometry_info.sigma=argument_list[2].real_reference;
11161           if (attribute_flag[3] != 0)
11162             geometry_info.xi=argument_list[3].real_reference;
11163           if (attribute_flag[4] != 0)
11164             geometry_info.psi=argument_list[4].real_reference;
11165           if (attribute_flag[5] != 0)
11166             channel=(ChannelType) argument_list[5].integer_reference;
11167           channel_mask=SetImageChannelMask(image,channel);
11168           image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11169             geometry_info.xi,geometry_info.psi,exception);
11170           if (image != (Image *) NULL)
11171             (void) SetImageChannelMask(image,channel_mask);
11172           break;
11173         }
11174         case 139:  /* HoughLine */
11175         {
11176           if (attribute_flag[0] != 0)
11177             {
11178               flags=ParseGeometry(argument_list[0].string_reference,
11179                 &geometry_info);
11180               if ((flags & SigmaValue) == 0)
11181                 geometry_info.sigma=geometry_info.rho;
11182               if ((flags & XiValue) == 0)
11183                 geometry_info.xi=40;
11184             }
11185           if (attribute_flag[1] != 0)
11186             geometry_info.rho=(double) argument_list[1].integer_reference;
11187           if (attribute_flag[2] != 0)
11188             geometry_info.sigma=(double) argument_list[2].integer_reference;
11189           if (attribute_flag[3] != 0)
11190             geometry_info.xi=(double) argument_list[3].integer_reference;
11191           image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t)
11192             geometry_info.sigma,(size_t) geometry_info.xi,exception);
11193           break;
11194         }
11195         case 140:  /* MeanShift */
11196         {
11197           if (attribute_flag[0] != 0)
11198             {
11199               flags=ParseGeometry(argument_list[0].string_reference,
11200                 &geometry_info);
11201               if ((flags & SigmaValue) == 0)
11202                 geometry_info.sigma=geometry_info.rho;
11203               if ((flags & XiValue) == 0)
11204                 geometry_info.xi=0.10*QuantumRange;
11205               if ((flags & PercentValue) != 0)
11206                 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
11207             }
11208           if (attribute_flag[1] != 0)
11209             geometry_info.rho=(double) argument_list[1].integer_reference;
11210           if (attribute_flag[2] != 0)
11211             geometry_info.sigma=(double) argument_list[2].integer_reference;
11212           if (attribute_flag[3] != 0)
11213             geometry_info.xi=(double) argument_list[3].integer_reference;
11214           image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t)
11215             geometry_info.sigma,geometry_info.xi,exception);
11216           break;
11217         }
11218         case 141:  /* Kuwahara */
11219         {
11220           if (attribute_flag[0] != 0)
11221             {
11222               flags=ParseGeometry(argument_list[0].string_reference,
11223                 &geometry_info);
11224               if ((flags & SigmaValue) == 0)
11225                 geometry_info.sigma=geometry_info.rho-0.5;
11226             }
11227           if (attribute_flag[1] != 0)
11228             geometry_info.rho=argument_list[1].real_reference;
11229           if (attribute_flag[2] != 0)
11230             geometry_info.sigma=argument_list[2].real_reference;
11231           if (attribute_flag[3] != 0)
11232             channel=(ChannelType) argument_list[3].integer_reference;
11233           channel_mask=SetImageChannelMask(image,channel);
11234           image=KuwaharaImage(image,geometry_info.rho,geometry_info.sigma,
11235             exception);
11236           if (image != (Image *) NULL)
11237             (void) SetImageChannelMask(image,channel_mask);
11238           break;
11239         }
11240         case 142:  /* ConnectedComponent */
11241         {
11242           size_t
11243             connectivity;
11244 
11245           connectivity=4;
11246           if (attribute_flag[0] != 0)
11247             connectivity=argument_list[0].integer_reference;
11248           image=ConnectedComponentsImage(image,connectivity,
11249             (CCObjectInfo **) NULL,exception);
11250           break;
11251         }
11252         case 143:  /* Copy */
11253         {
11254           Image
11255             *source_image;
11256 
11257           OffsetInfo
11258             offset;
11259 
11260           RectangleInfo
11261             offset_geometry;
11262 
11263           source_image=image;
11264           if (attribute_flag[0] != 0)
11265             source_image=argument_list[0].image_reference;
11266           SetGeometry(source_image,&geometry);
11267           if (attribute_flag[1] != 0)
11268             flags=ParseGravityGeometry(source_image,
11269               argument_list[1].string_reference,&geometry,exception);
11270           if (attribute_flag[2] != 0)
11271             geometry.width=argument_list[2].integer_reference;
11272           if (attribute_flag[3] != 0)
11273             geometry.height=argument_list[3].integer_reference;
11274           if (attribute_flag[4] != 0)
11275             geometry.x=argument_list[4].integer_reference;
11276           if (attribute_flag[5] != 0)
11277             geometry.y=argument_list[5].integer_reference;
11278           if (attribute_flag[6] != 0)
11279             image->gravity=(GravityType) argument_list[6].integer_reference;
11280           SetGeometry(image,&offset_geometry);
11281           if (attribute_flag[7] != 0)
11282             flags=ParseGravityGeometry(image,argument_list[7].string_reference,
11283               &offset_geometry,exception);
11284           offset.x=offset_geometry.x;
11285           offset.y=offset_geometry.y;
11286           if (attribute_flag[8] != 0)
11287             offset.x=argument_list[8].integer_reference;
11288           if (attribute_flag[9] != 0)
11289             offset.y=argument_list[9].integer_reference;
11290           (void) CopyImagePixels(image,source_image,&geometry,&offset,
11291             exception);
11292           break;
11293         }
11294         case 144:  /* Color */
11295         {
11296           PixelInfo
11297             color;
11298 
11299           (void) QueryColorCompliance("none",AllCompliance,&color,exception);
11300           if (attribute_flag[0] != 0)
11301             (void) QueryColorCompliance(argument_list[0].string_reference,
11302               AllCompliance,&color,exception);
11303           (void) SetImageColor(image,&color,exception);
11304           break;
11305         }
11306         case 145:  /* WaveletDenoise */
11307         {
11308           if (attribute_flag[0] != 0)
11309             {
11310               flags=ParseGeometry(argument_list[0].string_reference,
11311                 &geometry_info);
11312               if ((flags & PercentValue) != 0)
11313                 {
11314                   geometry_info.rho=QuantumRange*geometry_info.rho/100.0;
11315                   geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
11316                 }
11317               if ((flags & SigmaValue) == 0)
11318                 geometry_info.sigma=0.0;
11319             }
11320           if (attribute_flag[1] != 0)
11321             geometry_info.rho=argument_list[1].real_reference;
11322           if (attribute_flag[2] != 0)
11323             geometry_info.sigma=argument_list[2].real_reference;
11324           if (attribute_flag[3] != 0)
11325             channel=(ChannelType) argument_list[3].integer_reference;
11326           channel_mask=SetImageChannelMask(image,channel);
11327           image=WaveletDenoiseImage(image,geometry_info.rho,geometry_info.sigma,
11328             exception);
11329           if (image != (Image *) NULL)
11330             (void) SetImageChannelMask(image,channel_mask);
11331           break;
11332         }
11333       }
11334       if (next != (Image *) NULL)
11335         (void) CatchImageException(next);
11336       if (region_image != (Image *) NULL)
11337         {
11338           /*
11339             Composite region.
11340           */
11341           status=CompositeImage(region_image,image,CopyCompositeOp,MagickTrue,
11342             region_info.x,region_info.y,exception);
11343           (void) status;
11344           (void) CatchImageException(region_image);
11345           image=DestroyImage(image);
11346           image=region_image;
11347         }
11348       if (image != (Image *) NULL)
11349         {
11350           number_images++;
11351           if (next && (next != image))
11352             {
11353               image->next=next->next;
11354               if (image->next != (Image *) NULL)
11355                 image->next->previous=image;
11356               DeleteImageFromRegistry(*pv,next);
11357             }
11358           sv_setiv(*pv,PTR2IV(image));
11359           next=image;
11360         }
11361       if (*pv)
11362         pv++;
11363     }
11364 
11365   PerlException:
11366     if (reference_vector)
11367       reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11368     InheritPerlException(exception,perl_exception);
11369     exception=DestroyExceptionInfo(exception);
11370     sv_setiv(perl_exception,(IV) number_images);
11371     SvPOK_on(perl_exception);
11372     ST(0)=sv_2mortal(perl_exception);
11373     XSRETURN(1);
11374   }
11375 
11376 #
11377 ###############################################################################
11378 #                                                                             #
11379 #                                                                             #
11380 #                                                                             #
11381 #   M o n t a g e                                                             #
11382 #                                                                             #
11383 #                                                                             #
11384 #                                                                             #
11385 ###############################################################################
11386 #
11387 #
11388 void
Montage(ref,...)11389 Montage(ref,...)
11390   Image::Magick ref=NO_INIT
11391   ALIAS:
11392     MontageImage  = 1
11393     montage       = 2
11394     montageimage  = 3
11395   PPCODE:
11396   {
11397     AV
11398       *av;
11399 
11400     char
11401       *attribute;
11402 
11403     ExceptionInfo
11404       *exception;
11405 
11406     HV
11407       *hv;
11408 
11409     Image
11410       *image,
11411       *next;
11412 
11413     PixelInfo
11414       transparent_color;
11415 
11416     MontageInfo
11417       *montage_info;
11418 
11419     register ssize_t
11420       i;
11421 
11422     ssize_t
11423       sp;
11424 
11425     struct PackageInfo
11426       *info;
11427 
11428     SV
11429       *av_reference,
11430       *perl_exception,
11431       *reference,
11432       *rv,
11433       *sv;
11434 
11435     PERL_UNUSED_VAR(ref);
11436     PERL_UNUSED_VAR(ix);
11437     exception=AcquireExceptionInfo();
11438     perl_exception=newSVpv("",0);
11439     sv=NULL;
11440     attribute=NULL;
11441     if (sv_isobject(ST(0)) == 0)
11442       {
11443         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11444           PackageName);
11445         goto PerlException;
11446       }
11447     reference=SvRV(ST(0));
11448     hv=SvSTASH(reference);
11449     av=newAV();
11450     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11451     SvREFCNT_dec(av);
11452     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11453     if (image == (Image *) NULL)
11454       {
11455         ThrowPerlException(exception,OptionError,"NoImagesDefined",
11456           PackageName);
11457         goto PerlException;
11458       }
11459     /*
11460       Get options.
11461     */
11462     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11463     montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11464     (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11465       exception);
11466     for (i=2; i < items; i+=2)
11467     {
11468       attribute=(char *) SvPV(ST(i-1),na);
11469       switch (*attribute)
11470       {
11471         case 'B':
11472         case 'b':
11473         {
11474           if (LocaleCompare(attribute,"background") == 0)
11475             {
11476               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11477                 &montage_info->background_color,exception);
11478               for (next=image; next; next=next->next)
11479                 next->background_color=montage_info->background_color;
11480               break;
11481             }
11482           if (LocaleCompare(attribute,"border") == 0)
11483             {
11484               montage_info->border_width=SvIV(ST(i));
11485               break;
11486             }
11487           if (LocaleCompare(attribute,"bordercolor") == 0)
11488             {
11489               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11490                 &montage_info->border_color,exception);
11491               for (next=image; next; next=next->next)
11492                 next->border_color=montage_info->border_color;
11493               break;
11494             }
11495           if (LocaleCompare(attribute,"borderwidth") == 0)
11496             {
11497               montage_info->border_width=SvIV(ST(i));
11498               break;
11499             }
11500           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11501             attribute);
11502           break;
11503         }
11504         case 'C':
11505         case 'c':
11506         {
11507           if (LocaleCompare(attribute,"compose") == 0)
11508             {
11509               sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11510                 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11511               if (sp < 0)
11512                 {
11513                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
11514                     SvPV(ST(i),na));
11515                   break;
11516                 }
11517               for (next=image; next; next=next->next)
11518                 next->compose=(CompositeOperator) sp;
11519               break;
11520             }
11521           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11522             attribute);
11523           break;
11524         }
11525         case 'F':
11526         case 'f':
11527         {
11528           if (LocaleCompare(attribute,"fill") == 0)
11529             {
11530               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11531                 &montage_info->fill,exception);
11532               break;
11533             }
11534           if (LocaleCompare(attribute,"font") == 0)
11535             {
11536               (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11537               break;
11538             }
11539           if (LocaleCompare(attribute,"frame") == 0)
11540             {
11541               char
11542                 *p;
11543 
11544               p=SvPV(ST(i),na);
11545               if (IsGeometry(p) == MagickFalse)
11546                 {
11547                   ThrowPerlException(exception,OptionError,"MissingGeometry",
11548                     p);
11549                   break;
11550                 }
11551               (void) CloneString(&montage_info->frame,p);
11552               if (*p == '\0')
11553                 montage_info->frame=(char *) NULL;
11554               break;
11555             }
11556           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11557             attribute);
11558           break;
11559         }
11560         case 'G':
11561         case 'g':
11562         {
11563           if (LocaleCompare(attribute,"geometry") == 0)
11564             {
11565               char
11566                 *p;
11567 
11568               p=SvPV(ST(i),na);
11569               if (IsGeometry(p) == MagickFalse)
11570                 {
11571                   ThrowPerlException(exception,OptionError,"MissingGeometry",
11572                     p);
11573                   break;
11574                 }
11575              (void) CloneString(&montage_info->geometry,p);
11576              if (*p == '\0')
11577                montage_info->geometry=(char *) NULL;
11578              break;
11579            }
11580          if (LocaleCompare(attribute,"gravity") == 0)
11581            {
11582              ssize_t
11583                in;
11584 
11585              in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11586                MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11587              if (in < 0)
11588                {
11589                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
11590                    SvPV(ST(i),na));
11591                  return;
11592                }
11593              montage_info->gravity=(GravityType) in;
11594              for (next=image; next; next=next->next)
11595                next->gravity=(GravityType) in;
11596              break;
11597            }
11598           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11599             attribute);
11600           break;
11601         }
11602         case 'L':
11603         case 'l':
11604         {
11605           if (LocaleCompare(attribute,"label") == 0)
11606             {
11607               for (next=image; next; next=next->next)
11608                 (void) SetImageProperty(next,"label",InterpretImageProperties(
11609                   info ? info->image_info : (ImageInfo *) NULL,next,
11610                   SvPV(ST(i),na),exception),exception);
11611               break;
11612             }
11613           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11614             attribute);
11615           break;
11616         }
11617         case 'M':
11618         case 'm':
11619         {
11620           if (LocaleCompare(attribute,"mattecolor") == 0)
11621             {
11622               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11623                 &montage_info->alpha_color,exception);
11624               for (next=image; next; next=next->next)
11625                 next->alpha_color=montage_info->alpha_color;
11626               break;
11627             }
11628           if (LocaleCompare(attribute,"mode") == 0)
11629             {
11630               ssize_t
11631                 in;
11632 
11633               in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11634                 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11635               switch (in)
11636               {
11637                 default:
11638                 {
11639                   ThrowPerlException(exception,OptionError,
11640                     "UnrecognizedModeType",SvPV(ST(i),na));
11641                   break;
11642                 }
11643                 case FrameMode:
11644                 {
11645                   (void) CloneString(&montage_info->frame,"15x15+3+3");
11646                   montage_info->shadow=MagickTrue;
11647                   break;
11648                 }
11649                 case UnframeMode:
11650                 {
11651                   montage_info->frame=(char *) NULL;
11652                   montage_info->shadow=MagickFalse;
11653                   montage_info->border_width=0;
11654                   break;
11655                 }
11656                 case ConcatenateMode:
11657                 {
11658                   montage_info->frame=(char *) NULL;
11659                   montage_info->shadow=MagickFalse;
11660                   (void) CloneString(&montage_info->geometry,"+0+0");
11661                   montage_info->border_width=0;
11662                 }
11663               }
11664               break;
11665             }
11666           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11667             attribute);
11668           break;
11669         }
11670         case 'P':
11671         case 'p':
11672         {
11673           if (LocaleCompare(attribute,"pointsize") == 0)
11674             {
11675               montage_info->pointsize=SvIV(ST(i));
11676               break;
11677             }
11678           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11679             attribute);
11680           break;
11681         }
11682         case 'S':
11683         case 's':
11684         {
11685           if (LocaleCompare(attribute,"shadow") == 0)
11686             {
11687               sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11688                 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11689               if (sp < 0)
11690                 {
11691                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
11692                     SvPV(ST(i),na));
11693                   break;
11694                 }
11695              montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11696              break;
11697             }
11698           if (LocaleCompare(attribute,"stroke") == 0)
11699             {
11700               (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11701                 &montage_info->stroke,exception);
11702               break;
11703             }
11704           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11705             attribute);
11706           break;
11707         }
11708         case 'T':
11709         case 't':
11710         {
11711           if (LocaleCompare(attribute,"texture") == 0)
11712             {
11713               (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11714               break;
11715             }
11716           if (LocaleCompare(attribute,"tile") == 0)
11717             {
11718               char *p=SvPV(ST(i),na);
11719               if (IsGeometry(p) == MagickFalse)
11720                 {
11721                   ThrowPerlException(exception,OptionError,"MissingGeometry",
11722                     p);
11723                   break;
11724                 }
11725               (void) CloneString(&montage_info->tile,p);
11726               if (*p == '\0')
11727                 montage_info->tile=(char *) NULL;
11728               break;
11729             }
11730           if (LocaleCompare(attribute,"title") == 0)
11731             {
11732               (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11733               break;
11734             }
11735           if (LocaleCompare(attribute,"transparent") == 0)
11736             {
11737               PixelInfo
11738                 transparent_color;
11739 
11740               QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11741                 &transparent_color,exception);
11742               for (next=image; next; next=next->next)
11743                 (void) TransparentPaintImage(next,&transparent_color,
11744                   TransparentAlpha,MagickFalse,exception);
11745               break;
11746             }
11747           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11748             attribute);
11749           break;
11750         }
11751         default:
11752         {
11753           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11754             attribute);
11755           break;
11756         }
11757       }
11758     }
11759     image=MontageImageList(info->image_info,montage_info,image,exception);
11760     montage_info=DestroyMontageInfo(montage_info);
11761     if (image == (Image *) NULL)
11762       goto PerlException;
11763     if (transparent_color.alpha != TransparentAlpha)
11764       for (next=image; next; next=next->next)
11765         (void) TransparentPaintImage(next,&transparent_color,
11766           TransparentAlpha,MagickFalse,exception);
11767     for (  ; image; image=image->next)
11768     {
11769       AddImageToRegistry(sv,image);
11770       rv=newRV(sv);
11771       av_push(av,sv_bless(rv,hv));
11772       SvREFCNT_dec(sv);
11773     }
11774     exception=DestroyExceptionInfo(exception);
11775     ST(0)=av_reference;
11776     SvREFCNT_dec(perl_exception);
11777     XSRETURN(1);
11778 
11779   PerlException:
11780     InheritPerlException(exception,perl_exception);
11781     exception=DestroyExceptionInfo(exception);
11782     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11783     SvPOK_on(perl_exception);
11784     ST(0)=sv_2mortal(perl_exception);
11785     XSRETURN(1);
11786   }
11787 
11788 #
11789 ###############################################################################
11790 #                                                                             #
11791 #                                                                             #
11792 #                                                                             #
11793 #   M o r p h                                                                 #
11794 #                                                                             #
11795 #                                                                             #
11796 #                                                                             #
11797 ###############################################################################
11798 #
11799 #
11800 void
Morph(ref,...)11801 Morph(ref,...)
11802   Image::Magick ref=NO_INIT
11803   ALIAS:
11804     MorphImage  = 1
11805     morph       = 2
11806     morphimage  = 3
11807   PPCODE:
11808   {
11809     AV
11810       *av;
11811 
11812     char
11813       *attribute;
11814 
11815     ExceptionInfo
11816       *exception;
11817 
11818     HV
11819       *hv;
11820 
11821     Image
11822       *image;
11823 
11824     register ssize_t
11825       i;
11826 
11827     ssize_t
11828       number_frames;
11829 
11830     struct PackageInfo
11831       *info;
11832 
11833     SV
11834       *av_reference,
11835       *perl_exception,
11836       *reference,
11837       *rv,
11838       *sv;
11839 
11840     PERL_UNUSED_VAR(ref);
11841     PERL_UNUSED_VAR(ix);
11842     exception=AcquireExceptionInfo();
11843     perl_exception=newSVpv("",0);
11844     sv=NULL;
11845     av=NULL;
11846     attribute=NULL;
11847     if (sv_isobject(ST(0)) == 0)
11848       {
11849         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11850           PackageName);
11851         goto PerlException;
11852       }
11853     reference=SvRV(ST(0));
11854     hv=SvSTASH(reference);
11855     av=newAV();
11856     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11857     SvREFCNT_dec(av);
11858     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11859     if (image == (Image *) NULL)
11860       {
11861         ThrowPerlException(exception,OptionError,"NoImagesDefined",
11862           PackageName);
11863         goto PerlException;
11864       }
11865     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11866     /*
11867       Get attribute.
11868     */
11869     number_frames=30;
11870     for (i=2; i < items; i+=2)
11871     {
11872       attribute=(char *) SvPV(ST(i-1),na);
11873       switch (*attribute)
11874       {
11875         case 'F':
11876         case 'f':
11877         {
11878           if (LocaleCompare(attribute,"frames") == 0)
11879             {
11880               number_frames=SvIV(ST(i));
11881               break;
11882             }
11883           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11884             attribute);
11885           break;
11886         }
11887         default:
11888         {
11889           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11890             attribute);
11891           break;
11892         }
11893       }
11894     }
11895     image=MorphImages(image,number_frames,exception);
11896     if (image == (Image *) NULL)
11897       goto PerlException;
11898     for ( ; image; image=image->next)
11899     {
11900       AddImageToRegistry(sv,image);
11901       rv=newRV(sv);
11902       av_push(av,sv_bless(rv,hv));
11903       SvREFCNT_dec(sv);
11904     }
11905     exception=DestroyExceptionInfo(exception);
11906     ST(0)=av_reference;
11907     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
11908     XSRETURN(1);
11909 
11910   PerlException:
11911     InheritPerlException(exception,perl_exception);
11912     exception=DestroyExceptionInfo(exception);
11913     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11914     SvPOK_on(perl_exception);
11915     ST(0)=sv_2mortal(perl_exception);
11916     XSRETURN(1);
11917   }
11918 
11919 #
11920 ###############################################################################
11921 #                                                                             #
11922 #                                                                             #
11923 #                                                                             #
11924 #   M o s a i c                                                               #
11925 #                                                                             #
11926 #                                                                             #
11927 #                                                                             #
11928 ###############################################################################
11929 #
11930 #
11931 void
Mosaic(ref)11932 Mosaic(ref)
11933   Image::Magick ref=NO_INIT
11934   ALIAS:
11935     MosaicImage   = 1
11936     mosaic        = 2
11937     mosaicimage   = 3
11938   PPCODE:
11939   {
11940     AV
11941       *av;
11942 
11943     ExceptionInfo
11944       *exception;
11945 
11946     HV
11947       *hv;
11948 
11949     Image
11950       *image;
11951 
11952     struct PackageInfo
11953       *info;
11954 
11955     SV
11956       *perl_exception,
11957       *reference,
11958       *rv,
11959       *sv;
11960 
11961     PERL_UNUSED_VAR(ref);
11962     PERL_UNUSED_VAR(ix);
11963     exception=AcquireExceptionInfo();
11964     perl_exception=newSVpv("",0);
11965     sv=NULL;
11966     if (sv_isobject(ST(0)) == 0)
11967       {
11968         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11969           PackageName);
11970         goto PerlException;
11971       }
11972     reference=SvRV(ST(0));
11973     hv=SvSTASH(reference);
11974     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11975     if (image == (Image *) NULL)
11976       {
11977         ThrowPerlException(exception,OptionError,"NoImagesDefined",
11978           PackageName);
11979         goto PerlException;
11980       }
11981     image=MergeImageLayers(image,MosaicLayer,exception);
11982     /*
11983       Create blessed Perl array for the returned image.
11984     */
11985     av=newAV();
11986     ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11987     SvREFCNT_dec(av);
11988     AddImageToRegistry(sv,image);
11989     rv=newRV(sv);
11990     av_push(av,sv_bless(rv,hv));
11991     SvREFCNT_dec(sv);
11992     (void) CopyMagickString(info->image_info->filename,image->filename,
11993       MagickPathExtent);
11994     SetImageInfo(info->image_info,0,exception);
11995     exception=DestroyExceptionInfo(exception);
11996     SvREFCNT_dec(perl_exception);
11997     XSRETURN(1);
11998 
11999   PerlException:
12000     InheritPerlException(exception,perl_exception);
12001     exception=DestroyExceptionInfo(exception);
12002     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12003     SvPOK_on(perl_exception);  /* return messages in string context */
12004     ST(0)=sv_2mortal(perl_exception);
12005     XSRETURN(1);
12006   }
12007 
12008 #
12009 ###############################################################################
12010 #                                                                             #
12011 #                                                                             #
12012 #                                                                             #
12013 #   P i n g                                                                   #
12014 #                                                                             #
12015 #                                                                             #
12016 #                                                                             #
12017 ###############################################################################
12018 #
12019 #
12020 void
Ping(ref,...)12021 Ping(ref,...)
12022   Image::Magick ref=NO_INIT
12023   ALIAS:
12024     PingImage  = 1
12025     ping       = 2
12026     pingimage  = 3
12027   PPCODE:
12028   {
12029     AV
12030       *av;
12031 
12032     char
12033       **keep,
12034       **list;
12035 
12036     ExceptionInfo
12037       *exception;
12038 
12039     Image
12040       *image,
12041       *next;
12042 
12043     int
12044       n;
12045 
12046     MagickBooleanType
12047       status;
12048 
12049     register char
12050       **p;
12051 
12052     register ssize_t
12053       i;
12054 
12055     ssize_t
12056       ac;
12057 
12058     STRLEN
12059       *length;
12060 
12061     struct PackageInfo
12062       *info,
12063       *package_info;
12064 
12065     SV
12066       *perl_exception,
12067       *reference;
12068 
12069     size_t
12070       count;
12071 
12072     PERL_UNUSED_VAR(ref);
12073     PERL_UNUSED_VAR(ix);
12074     exception=AcquireExceptionInfo();
12075     perl_exception=newSVpv("",0);
12076     package_info=(struct PackageInfo *) NULL;
12077     ac=(items < 2) ? 1 : items-1;
12078     list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12079     keep=list;
12080     length=(STRLEN *) NULL;
12081     if (list == (char **) NULL)
12082       {
12083         ThrowPerlException(exception,ResourceLimitError,
12084           "MemoryAllocationFailed",PackageName);
12085         goto PerlException;
12086       }
12087     keep=list;
12088     length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12089     if (length == (STRLEN *) NULL)
12090       {
12091         ThrowPerlException(exception,ResourceLimitError,
12092           "MemoryAllocationFailed",PackageName);
12093         goto PerlException;
12094       }
12095     if (sv_isobject(ST(0)) == 0)
12096       {
12097         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12098           PackageName);
12099         goto PerlException;
12100       }
12101     reference=SvRV(ST(0));
12102     if (SvTYPE(reference) != SVt_PVAV)
12103       {
12104         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12105           PackageName);
12106         goto PerlException;
12107       }
12108     av=(AV *) reference;
12109     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12110       exception);
12111     package_info=ClonePackageInfo(info,exception);
12112     n=1;
12113     if (items <= 1)
12114       *list=(char *) (*package_info->image_info->filename ?
12115         package_info->image_info->filename : "XC:black");
12116     else
12117       for (n=0, i=0; i < ac; i++)
12118       {
12119         list[n]=(char *) SvPV(ST(i+1),length[n]);
12120         if ((items >= 3) && strEQcase(list[n],"blob"))
12121           {
12122             void
12123               *blob;
12124 
12125             i++;
12126             blob=(void *) (SvPV(ST(i+1),length[n]));
12127             SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12128           }
12129         if ((items >= 3) && strEQcase(list[n],"filename"))
12130           continue;
12131         if ((items >= 3) && strEQcase(list[n],"file"))
12132           {
12133             FILE
12134               *file;
12135 
12136             PerlIO
12137               *io_info;
12138 
12139             i++;
12140             io_info=IoIFP(sv_2io(ST(i+1)));
12141             if (io_info == (PerlIO *) NULL)
12142               {
12143                 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12144                   PackageName);
12145                 continue;
12146               }
12147             file=PerlIO_findFILE(io_info);
12148             if (file == (FILE *) NULL)
12149               {
12150                 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12151                   PackageName);
12152                 continue;
12153               }
12154             SetImageInfoFile(package_info->image_info,file);
12155           }
12156         if ((items >= 3) && strEQcase(list[n],"magick"))
12157           continue;
12158         n++;
12159       }
12160     list[n]=(char *) NULL;
12161     keep=list;
12162     status=ExpandFilenames(&n,&list);
12163     if (status == MagickFalse)
12164       {
12165         ThrowPerlException(exception,ResourceLimitError,
12166           "MemoryAllocationFailed",PackageName);
12167         goto PerlException;
12168       }
12169     count=0;
12170     for (i=0; i < n; i++)
12171     {
12172       (void) CopyMagickString(package_info->image_info->filename,list[i],
12173         MagickPathExtent);
12174       image=PingImage(package_info->image_info,exception);
12175       if (image == (Image *) NULL)
12176         break;
12177       if ((package_info->image_info->file != (FILE *) NULL) ||
12178           (package_info->image_info->blob != (void *) NULL))
12179         DisassociateImageStream(image);
12180       count+=GetImageListLength(image);
12181       EXTEND(sp,4*count);
12182       for (next=image; next; next=next->next)
12183       {
12184         PUSHs(sv_2mortal(newSViv(next->columns)));
12185         PUSHs(sv_2mortal(newSViv(next->rows)));
12186         PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
12187         PUSHs(sv_2mortal(newSVpv(next->magick,0)));
12188       }
12189       image=DestroyImageList(image);
12190     }
12191     /*
12192       Free resources.
12193     */
12194     for (i=0; i < n; i++)
12195       if (list[i] != (char *) NULL)
12196         for (p=keep; list[i] != *p++; )
12197           if (*p == NULL)
12198             {
12199               list[i]=(char *) RelinquishMagickMemory(list[i]);
12200               break;
12201             }
12202 
12203   PerlException:
12204     if (package_info != (struct PackageInfo *) NULL)
12205       DestroyPackageInfo(package_info);
12206     if (list && (list != keep))
12207       list=(char **) RelinquishMagickMemory(list);
12208     if (keep)
12209       keep=(char **) RelinquishMagickMemory(keep);
12210     if (length)
12211       length=(STRLEN *) RelinquishMagickMemory(length);
12212     InheritPerlException(exception,perl_exception);
12213     exception=DestroyExceptionInfo(exception);
12214     SvREFCNT_dec(perl_exception);  /* throw away all errors */
12215   }
12216 
12217 #
12218 ###############################################################################
12219 #                                                                             #
12220 #                                                                             #
12221 #                                                                             #
12222 #   P r e v i e w                                                             #
12223 #                                                                             #
12224 #                                                                             #
12225 #                                                                             #
12226 ###############################################################################
12227 #
12228 #
12229 void
Preview(ref,...)12230 Preview(ref,...)
12231   Image::Magick ref=NO_INIT
12232   ALIAS:
12233     PreviewImage = 1
12234     preview      = 2
12235     previewimage = 3
12236   PPCODE:
12237   {
12238     AV
12239       *av;
12240 
12241     ExceptionInfo
12242       *exception;
12243 
12244     HV
12245       *hv;
12246 
12247     Image
12248       *image,
12249       *preview_image;
12250 
12251     PreviewType
12252       preview_type;
12253 
12254     struct PackageInfo
12255       *info;
12256 
12257     SV
12258       *av_reference,
12259       *perl_exception,
12260       *reference,
12261       *rv,
12262       *sv;
12263 
12264     PERL_UNUSED_VAR(ref);
12265     PERL_UNUSED_VAR(ix);
12266     exception=AcquireExceptionInfo();
12267     perl_exception=newSVpv("",0);
12268     sv=NULL;
12269     av=NULL;
12270     if (sv_isobject(ST(0)) == 0)
12271       {
12272         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12273           PackageName);
12274         goto PerlException;
12275       }
12276     reference=SvRV(ST(0));
12277     hv=SvSTASH(reference);
12278     av=newAV();
12279     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12280     SvREFCNT_dec(av);
12281     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12282     if (image == (Image *) NULL)
12283       {
12284         ThrowPerlException(exception,OptionError,"NoImagesDefined",
12285           PackageName);
12286         goto PerlException;
12287       }
12288     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12289     preview_type=GammaPreview;
12290     if (items > 1)
12291       preview_type=(PreviewType)
12292         ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12293     for ( ; image; image=image->next)
12294     {
12295       preview_image=PreviewImage(image,preview_type,exception);
12296       if (preview_image == (Image *) NULL)
12297         goto PerlException;
12298       AddImageToRegistry(sv,preview_image);
12299       rv=newRV(sv);
12300       av_push(av,sv_bless(rv,hv));
12301       SvREFCNT_dec(sv);
12302     }
12303     exception=DestroyExceptionInfo(exception);
12304     ST(0)=av_reference;
12305     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
12306     XSRETURN(1);
12307 
12308   PerlException:
12309     InheritPerlException(exception,perl_exception);
12310     exception=DestroyExceptionInfo(exception);
12311     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12312     SvPOK_on(perl_exception);
12313     ST(0)=sv_2mortal(perl_exception);
12314     XSRETURN(1);
12315   }
12316 
12317 #
12318 ###############################################################################
12319 #                                                                             #
12320 #                                                                             #
12321 #                                                                             #
12322 #   Q u e r y C o l o r                                                       #
12323 #                                                                             #
12324 #                                                                             #
12325 #                                                                             #
12326 ###############################################################################
12327 #
12328 #
12329 void
QueryColor(ref,...)12330 QueryColor(ref,...)
12331   Image::Magick ref=NO_INIT
12332   ALIAS:
12333     querycolor = 1
12334   PPCODE:
12335   {
12336     char
12337       *name;
12338 
12339     ExceptionInfo
12340       *exception;
12341 
12342     PixelInfo
12343       color;
12344 
12345     register ssize_t
12346       i;
12347 
12348     SV
12349       *perl_exception;
12350 
12351     PERL_UNUSED_VAR(ref);
12352     PERL_UNUSED_VAR(ix);
12353     exception=AcquireExceptionInfo();
12354     perl_exception=newSVpv("",0);
12355     if (items == 1)
12356       {
12357         const ColorInfo
12358           **colorlist;
12359 
12360         size_t
12361           colors;
12362 
12363         colorlist=GetColorInfoList("*",&colors,exception);
12364         EXTEND(sp,colors);
12365         for (i=0; i < (ssize_t) colors; i++)
12366         {
12367           PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12368         }
12369         colorlist=(const ColorInfo **)
12370           RelinquishMagickMemory((ColorInfo **) colorlist);
12371         goto PerlException;
12372       }
12373     EXTEND(sp,5*items);
12374     for (i=1; i < items; i++)
12375     {
12376       name=(char *) SvPV(ST(i),na);
12377       if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12378         {
12379           PUSHs(&sv_undef);
12380           continue;
12381         }
12382       PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12383       PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12384       PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12385       if (color.colorspace == CMYKColorspace)
12386         PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
12387       if (color.alpha_trait != UndefinedPixelTrait)
12388         PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12389     }
12390 
12391   PerlException:
12392     InheritPerlException(exception,perl_exception);
12393     exception=DestroyExceptionInfo(exception);
12394     SvREFCNT_dec(perl_exception);
12395   }
12396 
12397 #
12398 ###############################################################################
12399 #                                                                             #
12400 #                                                                             #
12401 #                                                                             #
12402 #   Q u e r y C o l o r N a m e                                               #
12403 #                                                                             #
12404 #                                                                             #
12405 #                                                                             #
12406 ###############################################################################
12407 #
12408 #
12409 void
QueryColorname(ref,...)12410 QueryColorname(ref,...)
12411   Image::Magick ref=NO_INIT
12412   ALIAS:
12413     querycolorname = 1
12414   PPCODE:
12415   {
12416     AV
12417       *av;
12418 
12419     char
12420       message[MagickPathExtent];
12421 
12422     ExceptionInfo
12423       *exception;
12424 
12425     Image
12426       *image;
12427 
12428     PixelInfo
12429       target_color;
12430 
12431     register ssize_t
12432       i;
12433 
12434     struct PackageInfo
12435       *info;
12436 
12437     SV
12438       *perl_exception,
12439       *reference;  /* reference is the SV* of ref=SvIV(reference) */
12440 
12441     PERL_UNUSED_VAR(ref);
12442     PERL_UNUSED_VAR(ix);
12443     exception=AcquireExceptionInfo();
12444     perl_exception=newSVpv("",0);
12445     reference=SvRV(ST(0));
12446     av=(AV *) reference;
12447     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12448       exception);
12449     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12450     if (image == (Image *) NULL)
12451       {
12452         ThrowPerlException(exception,OptionError,"NoImagesDefined",
12453           PackageName);
12454         goto PerlException;
12455       }
12456     EXTEND(sp,items);
12457     for (i=1; i < items; i++)
12458     {
12459       (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12460         exception);
12461       (void) QueryColorname(image,&target_color,SVGCompliance,message,
12462         exception);
12463       PUSHs(sv_2mortal(newSVpv(message,0)));
12464     }
12465 
12466   PerlException:
12467     InheritPerlException(exception,perl_exception);
12468     exception=DestroyExceptionInfo(exception);
12469     SvREFCNT_dec(perl_exception);
12470   }
12471 
12472 #
12473 ###############################################################################
12474 #                                                                             #
12475 #                                                                             #
12476 #                                                                             #
12477 #   Q u e r y F o n t                                                         #
12478 #                                                                             #
12479 #                                                                             #
12480 #                                                                             #
12481 ###############################################################################
12482 #
12483 #
12484 void
QueryFont(ref,...)12485 QueryFont(ref,...)
12486   Image::Magick ref=NO_INIT
12487   ALIAS:
12488     queryfont = 1
12489   PPCODE:
12490   {
12491     char
12492       *name,
12493       message[MagickPathExtent];
12494 
12495     ExceptionInfo
12496       *exception;
12497 
12498     register ssize_t
12499       i;
12500 
12501     SV
12502       *perl_exception;
12503 
12504     volatile const TypeInfo
12505       *type_info;
12506 
12507     PERL_UNUSED_VAR(ref);
12508     PERL_UNUSED_VAR(ix);
12509     exception=AcquireExceptionInfo();
12510     perl_exception=newSVpv("",0);
12511     if (items == 1)
12512       {
12513         const TypeInfo
12514           **typelist;
12515 
12516         size_t
12517           types;
12518 
12519         typelist=GetTypeInfoList("*",&types,exception);
12520         EXTEND(sp,types);
12521         for (i=0; i < (ssize_t) types; i++)
12522         {
12523           PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12524         }
12525         typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12526           typelist);
12527         goto PerlException;
12528       }
12529     EXTEND(sp,10*items);
12530     for (i=1; i < items; i++)
12531     {
12532       name=(char *) SvPV(ST(i),na);
12533       type_info=GetTypeInfo(name,exception);
12534       if (type_info == (TypeInfo *) NULL)
12535         {
12536           PUSHs(&sv_undef);
12537           continue;
12538         }
12539       if (type_info->name == (char *) NULL)
12540         PUSHs(&sv_undef);
12541       else
12542         PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12543       if (type_info->description == (char *) NULL)
12544         PUSHs(&sv_undef);
12545       else
12546         PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12547       if (type_info->family == (char *) NULL)
12548         PUSHs(&sv_undef);
12549       else
12550         PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12551       if (type_info->style == UndefinedStyle)
12552         PUSHs(&sv_undef);
12553       else
12554         PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12555           type_info->style),0)));
12556       if (type_info->stretch == UndefinedStretch)
12557         PUSHs(&sv_undef);
12558       else
12559         PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12560           type_info->stretch),0)));
12561       (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
12562         type_info->weight);
12563       PUSHs(sv_2mortal(newSVpv(message,0)));
12564       if (type_info->encoding == (char *) NULL)
12565         PUSHs(&sv_undef);
12566       else
12567         PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12568       if (type_info->foundry == (char *) NULL)
12569         PUSHs(&sv_undef);
12570       else
12571         PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12572       if (type_info->format == (char *) NULL)
12573         PUSHs(&sv_undef);
12574       else
12575         PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12576       if (type_info->metrics == (char *) NULL)
12577         PUSHs(&sv_undef);
12578       else
12579         PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12580       if (type_info->glyphs == (char *) NULL)
12581         PUSHs(&sv_undef);
12582       else
12583         PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12584     }
12585 
12586   PerlException:
12587     InheritPerlException(exception,perl_exception);
12588     exception=DestroyExceptionInfo(exception);
12589     SvREFCNT_dec(perl_exception);
12590   }
12591 
12592 #
12593 ###############################################################################
12594 #                                                                             #
12595 #                                                                             #
12596 #                                                                             #
12597 #   Q u e r y F o n t M e t r i c s                                           #
12598 #                                                                             #
12599 #                                                                             #
12600 #                                                                             #
12601 ###############################################################################
12602 #
12603 #
12604 void
QueryFontMetrics(ref,...)12605 QueryFontMetrics(ref,...)
12606   Image::Magick ref=NO_INIT
12607   ALIAS:
12608     queryfontmetrics = 1
12609   PPCODE:
12610   {
12611     AffineMatrix
12612       affine,
12613       current;
12614 
12615     AV
12616       *av;
12617 
12618     char
12619       *attribute;
12620 
12621     double
12622       x,
12623       y;
12624 
12625     DrawInfo
12626       *draw_info;
12627 
12628     ExceptionInfo
12629       *exception;
12630 
12631     GeometryInfo
12632       geometry_info;
12633 
12634     Image
12635       *image;
12636 
12637     MagickBooleanType
12638       status;
12639 
12640     MagickStatusType
12641       flags;
12642 
12643     register ssize_t
12644       i;
12645 
12646     ssize_t
12647       type;
12648 
12649     struct PackageInfo
12650       *info,
12651       *package_info;
12652 
12653     SV
12654       *perl_exception,
12655       *reference;  /* reference is the SV* of ref=SvIV(reference) */
12656 
12657     TypeMetric
12658       metrics;
12659 
12660     PERL_UNUSED_VAR(ref);
12661     PERL_UNUSED_VAR(ix);
12662     exception=AcquireExceptionInfo();
12663     package_info=(struct PackageInfo *) NULL;
12664     perl_exception=newSVpv("",0);
12665     reference=SvRV(ST(0));
12666     av=(AV *) reference;
12667     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12668       exception);
12669     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12670     if (image == (Image *) NULL)
12671       {
12672         ThrowPerlException(exception,OptionError,"NoImagesDefined",
12673           PackageName);
12674         goto PerlException;
12675       }
12676     package_info=ClonePackageInfo(info,exception);
12677     draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12678     CloneString(&draw_info->text,"");
12679     current=draw_info->affine;
12680     GetAffineMatrix(&affine);
12681     x=0.0;
12682     y=0.0;
12683     EXTEND(sp,7*items);
12684     for (i=2; i < items; i+=2)
12685     {
12686       attribute=(char *) SvPV(ST(i-1),na);
12687       switch (*attribute)
12688       {
12689         case 'A':
12690         case 'a':
12691         {
12692           if (LocaleCompare(attribute,"antialias") == 0)
12693             {
12694               type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12695                 SvPV(ST(i),na));
12696               if (type < 0)
12697                 {
12698                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
12699                     SvPV(ST(i),na));
12700                   break;
12701                 }
12702               draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12703               break;
12704             }
12705           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12706             attribute);
12707           break;
12708         }
12709         case 'd':
12710         case 'D':
12711         {
12712           if (LocaleCompare(attribute,"density") == 0)
12713             {
12714               CloneString(&draw_info->density,SvPV(ST(i),na));
12715               break;
12716             }
12717           if (LocaleCompare(attribute,"direction") == 0)
12718             {
12719               draw_info->direction=(DirectionType) ParseCommandOption(
12720                 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12721               break;
12722             }
12723           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12724             attribute);
12725           break;
12726         }
12727         case 'e':
12728         case 'E':
12729         {
12730           if (LocaleCompare(attribute,"encoding") == 0)
12731             {
12732               CloneString(&draw_info->encoding,SvPV(ST(i),na));
12733               break;
12734             }
12735           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12736             attribute);
12737           break;
12738         }
12739         case 'f':
12740         case 'F':
12741         {
12742           if (LocaleCompare(attribute,"family") == 0)
12743             {
12744               CloneString(&draw_info->family,SvPV(ST(i),na));
12745               break;
12746             }
12747           if (LocaleCompare(attribute,"fill") == 0)
12748             {
12749               if (info)
12750                 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12751                   &draw_info->fill,exception);
12752               break;
12753             }
12754           if (LocaleCompare(attribute,"font") == 0)
12755             {
12756               CloneString(&draw_info->font,SvPV(ST(i),na));
12757               break;
12758             }
12759           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12760             attribute);
12761           break;
12762         }
12763         case 'g':
12764         case 'G':
12765         {
12766           if (LocaleCompare(attribute,"geometry") == 0)
12767             {
12768               CloneString(&draw_info->geometry,SvPV(ST(i),na));
12769               break;
12770             }
12771           if (LocaleCompare(attribute,"gravity") == 0)
12772             {
12773               draw_info->gravity=(GravityType) ParseCommandOption(
12774                 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12775               break;
12776             }
12777           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12778             attribute);
12779           break;
12780         }
12781         case 'i':
12782         case 'I':
12783         {
12784           if (LocaleCompare(attribute,"interline-spacing") == 0)
12785             {
12786               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12787               draw_info->interline_spacing=geometry_info.rho;
12788               break;
12789             }
12790           if (LocaleCompare(attribute,"interword-spacing") == 0)
12791             {
12792               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12793               draw_info->interword_spacing=geometry_info.rho;
12794               break;
12795             }
12796           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12797             attribute);
12798           break;
12799         }
12800         case 'k':
12801         case 'K':
12802         {
12803           if (LocaleCompare(attribute,"kerning") == 0)
12804             {
12805               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12806               draw_info->kerning=geometry_info.rho;
12807               break;
12808             }
12809           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12810             attribute);
12811           break;
12812         }
12813         case 'p':
12814         case 'P':
12815         {
12816           if (LocaleCompare(attribute,"pointsize") == 0)
12817             {
12818               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12819               draw_info->pointsize=geometry_info.rho;
12820               break;
12821             }
12822           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12823             attribute);
12824           break;
12825         }
12826         case 'r':
12827         case 'R':
12828         {
12829           if (LocaleCompare(attribute,"rotate") == 0)
12830             {
12831               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12832               affine.rx=geometry_info.rho;
12833               affine.ry=geometry_info.sigma;
12834               if ((flags & SigmaValue) == 0)
12835                 affine.ry=affine.rx;
12836               break;
12837             }
12838           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12839             attribute);
12840           break;
12841         }
12842         case 's':
12843         case 'S':
12844         {
12845           if (LocaleCompare(attribute,"scale") == 0)
12846             {
12847               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12848               affine.sx=geometry_info.rho;
12849               affine.sy=geometry_info.sigma;
12850               if ((flags & SigmaValue) == 0)
12851                 affine.sy=affine.sx;
12852               break;
12853             }
12854           if (LocaleCompare(attribute,"skew") == 0)
12855             {
12856               double
12857                 x_angle,
12858                 y_angle;
12859 
12860               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12861               x_angle=geometry_info.rho;
12862               y_angle=geometry_info.sigma;
12863               if ((flags & SigmaValue) == 0)
12864                 y_angle=x_angle;
12865               affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
12866               affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
12867               break;
12868             }
12869           if (LocaleCompare(attribute,"stroke") == 0)
12870             {
12871               if (info)
12872                 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12873                   &draw_info->stroke,exception);
12874               break;
12875             }
12876           if (LocaleCompare(attribute,"style") == 0)
12877             {
12878               type=ParseCommandOption(MagickStyleOptions,MagickFalse,
12879                 SvPV(ST(i),na));
12880               if (type < 0)
12881                 {
12882                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
12883                     SvPV(ST(i),na));
12884                   break;
12885                 }
12886               draw_info->style=(StyleType) type;
12887               break;
12888             }
12889           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12890             attribute);
12891           break;
12892         }
12893         case 't':
12894         case 'T':
12895         {
12896           if (LocaleCompare(attribute,"text") == 0)
12897             {
12898               CloneString(&draw_info->text,SvPV(ST(i),na));
12899               break;
12900             }
12901           if (LocaleCompare(attribute,"translate") == 0)
12902             {
12903               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12904               affine.tx=geometry_info.rho;
12905               affine.ty=geometry_info.sigma;
12906               if ((flags & SigmaValue) == 0)
12907                 affine.ty=affine.tx;
12908               break;
12909             }
12910           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12911             attribute);
12912           break;
12913         }
12914         case 'w':
12915         case 'W':
12916         {
12917           if (LocaleCompare(attribute,"weight") == 0)
12918             {
12919               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12920               draw_info->weight=(size_t) geometry_info.rho;
12921               break;
12922             }
12923           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12924             attribute);
12925           break;
12926         }
12927         case 'x':
12928         case 'X':
12929         {
12930           if (LocaleCompare(attribute,"x") == 0)
12931             {
12932               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12933               x=geometry_info.rho;
12934               break;
12935             }
12936           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12937             attribute);
12938           break;
12939         }
12940         case 'y':
12941         case 'Y':
12942         {
12943           if (LocaleCompare(attribute,"y") == 0)
12944             {
12945               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12946               y=geometry_info.rho;
12947               break;
12948             }
12949           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12950             attribute);
12951           break;
12952         }
12953         default:
12954         {
12955           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12956             attribute);
12957           break;
12958         }
12959       }
12960     }
12961     draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
12962     draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
12963     draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
12964     draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
12965     draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
12966     draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
12967     if (draw_info->geometry == (char *) NULL)
12968       {
12969         draw_info->geometry=AcquireString((char *) NULL);
12970         (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
12971           "%.15g,%.15g",x,y);
12972       }
12973     status=GetTypeMetrics(image,draw_info,&metrics,exception);
12974     (void) CatchImageException(image);
12975     if (status == MagickFalse)
12976       PUSHs(&sv_undef);
12977     else
12978       {
12979         PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
12980         PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
12981         PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
12982         PUSHs(sv_2mortal(newSVnv(metrics.descent)));
12983         PUSHs(sv_2mortal(newSVnv(metrics.width)));
12984         PUSHs(sv_2mortal(newSVnv(metrics.height)));
12985         PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
12986         PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
12987         PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
12988         PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
12989         PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
12990         PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
12991         PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
12992       }
12993     draw_info=DestroyDrawInfo(draw_info);
12994 
12995   PerlException:
12996     if (package_info != (struct PackageInfo *) NULL)
12997       DestroyPackageInfo(package_info);
12998     InheritPerlException(exception,perl_exception);
12999     exception=DestroyExceptionInfo(exception);
13000     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
13001   }
13002 
13003 #
13004 ###############################################################################
13005 #                                                                             #
13006 #                                                                             #
13007 #                                                                             #
13008 #   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                         #
13009 #                                                                             #
13010 #                                                                             #
13011 #                                                                             #
13012 ###############################################################################
13013 #
13014 #
13015 void
QueryMultilineFontMetrics(ref,...)13016 QueryMultilineFontMetrics(ref,...)
13017   Image::Magick ref=NO_INIT
13018   ALIAS:
13019     querymultilinefontmetrics = 1
13020   PPCODE:
13021   {
13022     AffineMatrix
13023       affine,
13024       current;
13025 
13026     AV
13027       *av;
13028 
13029     char
13030       *attribute;
13031 
13032     double
13033       x,
13034       y;
13035 
13036     DrawInfo
13037       *draw_info;
13038 
13039     ExceptionInfo
13040       *exception;
13041 
13042     GeometryInfo
13043       geometry_info;
13044 
13045     Image
13046       *image;
13047 
13048     MagickBooleanType
13049       status;
13050 
13051     MagickStatusType
13052       flags;
13053 
13054     register ssize_t
13055       i;
13056 
13057     ssize_t
13058       type;
13059 
13060     struct PackageInfo
13061       *info,
13062       *package_info;
13063 
13064     SV
13065       *perl_exception,
13066       *reference;  /* reference is the SV* of ref=SvIV(reference) */
13067 
13068     TypeMetric
13069       metrics;
13070 
13071     PERL_UNUSED_VAR(ref);
13072     PERL_UNUSED_VAR(ix);
13073     exception=AcquireExceptionInfo();
13074     package_info=(struct PackageInfo *) NULL;
13075     perl_exception=newSVpv("",0);
13076     reference=SvRV(ST(0));
13077     av=(AV *) reference;
13078     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13079       exception);
13080     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13081     if (image == (Image *) NULL)
13082       {
13083         ThrowPerlException(exception,OptionError,"NoImagesDefined",
13084           PackageName);
13085         goto PerlException;
13086       }
13087     package_info=ClonePackageInfo(info,exception);
13088     draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
13089     CloneString(&draw_info->text,"");
13090     current=draw_info->affine;
13091     GetAffineMatrix(&affine);
13092     x=0.0;
13093     y=0.0;
13094     EXTEND(sp,7*items);
13095     for (i=2; i < items; i+=2)
13096     {
13097       attribute=(char *) SvPV(ST(i-1),na);
13098       switch (*attribute)
13099       {
13100         case 'A':
13101         case 'a':
13102         {
13103           if (LocaleCompare(attribute,"antialias") == 0)
13104             {
13105               type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13106                 SvPV(ST(i),na));
13107               if (type < 0)
13108                 {
13109                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
13110                     SvPV(ST(i),na));
13111                   break;
13112                 }
13113               draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
13114               break;
13115             }
13116           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13117             attribute);
13118           break;
13119         }
13120         case 'd':
13121         case 'D':
13122         {
13123           if (LocaleCompare(attribute,"density") == 0)
13124             {
13125               CloneString(&draw_info->density,SvPV(ST(i),na));
13126               break;
13127             }
13128           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13129             attribute);
13130           break;
13131         }
13132         case 'e':
13133         case 'E':
13134         {
13135           if (LocaleCompare(attribute,"encoding") == 0)
13136             {
13137               CloneString(&draw_info->encoding,SvPV(ST(i),na));
13138               break;
13139             }
13140           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13141             attribute);
13142           break;
13143         }
13144         case 'f':
13145         case 'F':
13146         {
13147           if (LocaleCompare(attribute,"family") == 0)
13148             {
13149               CloneString(&draw_info->family,SvPV(ST(i),na));
13150               break;
13151             }
13152           if (LocaleCompare(attribute,"fill") == 0)
13153             {
13154               if (info)
13155                 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13156                   &draw_info->fill,exception);
13157               break;
13158             }
13159           if (LocaleCompare(attribute,"font") == 0)
13160             {
13161               CloneString(&draw_info->font,SvPV(ST(i),na));
13162               break;
13163             }
13164           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13165             attribute);
13166           break;
13167         }
13168         case 'g':
13169         case 'G':
13170         {
13171           if (LocaleCompare(attribute,"geometry") == 0)
13172             {
13173               CloneString(&draw_info->geometry,SvPV(ST(i),na));
13174               break;
13175             }
13176           if (LocaleCompare(attribute,"gravity") == 0)
13177             {
13178               draw_info->gravity=(GravityType) ParseCommandOption(
13179                 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13180               break;
13181             }
13182           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13183             attribute);
13184           break;
13185         }
13186         case 'p':
13187         case 'P':
13188         {
13189           if (LocaleCompare(attribute,"pointsize") == 0)
13190             {
13191               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13192               draw_info->pointsize=geometry_info.rho;
13193               break;
13194             }
13195           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13196             attribute);
13197           break;
13198         }
13199         case 'r':
13200         case 'R':
13201         {
13202           if (LocaleCompare(attribute,"rotate") == 0)
13203             {
13204               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13205               affine.rx=geometry_info.rho;
13206               affine.ry=geometry_info.sigma;
13207               if ((flags & SigmaValue) == 0)
13208                 affine.ry=affine.rx;
13209               break;
13210             }
13211           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13212             attribute);
13213           break;
13214         }
13215         case 's':
13216         case 'S':
13217         {
13218           if (LocaleCompare(attribute,"scale") == 0)
13219             {
13220               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13221               affine.sx=geometry_info.rho;
13222               affine.sy=geometry_info.sigma;
13223               if ((flags & SigmaValue) == 0)
13224                 affine.sy=affine.sx;
13225               break;
13226             }
13227           if (LocaleCompare(attribute,"skew") == 0)
13228             {
13229               double
13230                 x_angle,
13231                 y_angle;
13232 
13233               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13234               x_angle=geometry_info.rho;
13235               y_angle=geometry_info.sigma;
13236               if ((flags & SigmaValue) == 0)
13237                 y_angle=x_angle;
13238               affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13239               affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13240               break;
13241             }
13242           if (LocaleCompare(attribute,"stroke") == 0)
13243             {
13244               if (info)
13245                 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13246                   &draw_info->stroke,exception);
13247               break;
13248             }
13249           if (LocaleCompare(attribute,"style") == 0)
13250             {
13251               type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13252                 SvPV(ST(i),na));
13253               if (type < 0)
13254                 {
13255                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
13256                     SvPV(ST(i),na));
13257                   break;
13258                 }
13259               draw_info->style=(StyleType) type;
13260               break;
13261             }
13262           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13263             attribute);
13264           break;
13265         }
13266         case 't':
13267         case 'T':
13268         {
13269           if (LocaleCompare(attribute,"text") == 0)
13270             {
13271               CloneString(&draw_info->text,SvPV(ST(i),na));
13272               break;
13273             }
13274           if (LocaleCompare(attribute,"translate") == 0)
13275             {
13276               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13277               affine.tx=geometry_info.rho;
13278               affine.ty=geometry_info.sigma;
13279               if ((flags & SigmaValue) == 0)
13280                 affine.ty=affine.tx;
13281               break;
13282             }
13283           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13284             attribute);
13285           break;
13286         }
13287         case 'w':
13288         case 'W':
13289         {
13290           if (LocaleCompare(attribute,"weight") == 0)
13291             {
13292               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13293               draw_info->weight=(size_t) geometry_info.rho;
13294               break;
13295             }
13296           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13297             attribute);
13298           break;
13299         }
13300         case 'x':
13301         case 'X':
13302         {
13303           if (LocaleCompare(attribute,"x") == 0)
13304             {
13305               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13306               x=geometry_info.rho;
13307               break;
13308             }
13309           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13310             attribute);
13311           break;
13312         }
13313         case 'y':
13314         case 'Y':
13315         {
13316           if (LocaleCompare(attribute,"y") == 0)
13317             {
13318               flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13319               y=geometry_info.rho;
13320               break;
13321             }
13322           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13323             attribute);
13324           break;
13325         }
13326         default:
13327         {
13328           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13329             attribute);
13330           break;
13331         }
13332       }
13333     }
13334     draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13335     draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13336     draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13337     draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13338     draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13339     draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13340     if (draw_info->geometry == (char *) NULL)
13341       {
13342         draw_info->geometry=AcquireString((char *) NULL);
13343         (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
13344           "%.15g,%.15g",x,y);
13345       }
13346     status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13347     (void) CatchException(exception);
13348     if (status == MagickFalse)
13349       PUSHs(&sv_undef);
13350     else
13351       {
13352         PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13353         PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13354         PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13355         PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13356         PUSHs(sv_2mortal(newSVnv(metrics.width)));
13357         PUSHs(sv_2mortal(newSVnv(metrics.height)));
13358         PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13359         PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13360         PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13361         PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13362         PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13363         PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13364         PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13365       }
13366     draw_info=DestroyDrawInfo(draw_info);
13367 
13368   PerlException:
13369     if (package_info != (struct PackageInfo *) NULL)
13370       DestroyPackageInfo(package_info);
13371     InheritPerlException(exception,perl_exception);
13372     exception=DestroyExceptionInfo(exception);
13373     SvREFCNT_dec(perl_exception);  /* can't return warning messages */
13374   }
13375 
13376 #
13377 ###############################################################################
13378 #                                                                             #
13379 #                                                                             #
13380 #                                                                             #
13381 #   Q u e r y F o r m a t                                                     #
13382 #                                                                             #
13383 #                                                                             #
13384 #                                                                             #
13385 ###############################################################################
13386 #
13387 #
13388 void
QueryFormat(ref,...)13389 QueryFormat(ref,...)
13390   Image::Magick ref=NO_INIT
13391   ALIAS:
13392     queryformat = 1
13393   PPCODE:
13394   {
13395     char
13396       *name;
13397 
13398     ExceptionInfo
13399       *exception;
13400 
13401     register ssize_t
13402       i;
13403 
13404     SV
13405       *perl_exception;
13406 
13407     volatile const MagickInfo
13408       *magick_info;
13409 
13410     PERL_UNUSED_VAR(ref);
13411     PERL_UNUSED_VAR(ix);
13412     exception=AcquireExceptionInfo();
13413     perl_exception=newSVpv("",0);
13414     if (items == 1)
13415       {
13416         char
13417           format[MagickPathExtent];
13418 
13419         const MagickInfo
13420           **format_list;
13421 
13422         size_t
13423           types;
13424 
13425         format_list=GetMagickInfoList("*",&types,exception);
13426         EXTEND(sp,types);
13427         for (i=0; i < (ssize_t) types; i++)
13428         {
13429           (void) CopyMagickString(format,format_list[i]->name,MagickPathExtent);
13430           LocaleLower(format);
13431           PUSHs(sv_2mortal(newSVpv(format,0)));
13432         }
13433         format_list=(const MagickInfo **)
13434           RelinquishMagickMemory((MagickInfo *) format_list);
13435         goto PerlException;
13436       }
13437     EXTEND(sp,8*items);
13438     for (i=1; i < items; i++)
13439     {
13440       name=(char *) SvPV(ST(i),na);
13441       magick_info=GetMagickInfo(name,exception);
13442       if (magick_info == (const MagickInfo *) NULL)
13443         {
13444           PUSHs(&sv_undef);
13445           continue;
13446         }
13447       if (magick_info->description == (char *) NULL)
13448         PUSHs(&sv_undef);
13449       else
13450         PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13451       if (magick_info->module == (char *) NULL)
13452         PUSHs(&sv_undef);
13453       else
13454         PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
13455     }
13456 
13457   PerlException:
13458     InheritPerlException(exception,perl_exception);
13459     exception=DestroyExceptionInfo(exception);
13460     SvREFCNT_dec(perl_exception);
13461   }
13462 
13463 #
13464 ###############################################################################
13465 #                                                                             #
13466 #                                                                             #
13467 #                                                                             #
13468 #   Q u e r y O p t i o n                                                     #
13469 #                                                                             #
13470 #                                                                             #
13471 #                                                                             #
13472 ###############################################################################
13473 #
13474 #
13475 void
QueryOption(ref,...)13476 QueryOption(ref,...)
13477   Image::Magick ref=NO_INIT
13478   ALIAS:
13479     queryoption = 1
13480   PPCODE:
13481   {
13482     char
13483       **options;
13484 
13485     ExceptionInfo
13486       *exception;
13487 
13488     register ssize_t
13489       i;
13490 
13491     ssize_t
13492       j,
13493       option;
13494 
13495     SV
13496       *perl_exception;
13497 
13498     PERL_UNUSED_VAR(ref);
13499     PERL_UNUSED_VAR(ix);
13500     exception=AcquireExceptionInfo();
13501     perl_exception=newSVpv("",0);
13502     EXTEND(sp,8*items);
13503     for (i=1; i < items; i++)
13504     {
13505       option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13506         SvPV(ST(i),na));
13507       options=GetCommandOptions((CommandOption) option);
13508       if (options == (char **) NULL)
13509         PUSHs(&sv_undef);
13510       else
13511         {
13512           for (j=0; options[j] != (char *) NULL; j++)
13513             PUSHs(sv_2mortal(newSVpv(options[j],0)));
13514           options=DestroyStringList(options);
13515         }
13516     }
13517 
13518     InheritPerlException(exception,perl_exception);
13519     exception=DestroyExceptionInfo(exception);
13520     SvREFCNT_dec(perl_exception);
13521   }
13522 
13523 #
13524 ###############################################################################
13525 #                                                                             #
13526 #                                                                             #
13527 #                                                                             #
13528 #   R e a d                                                                   #
13529 #                                                                             #
13530 #                                                                             #
13531 #                                                                             #
13532 ###############################################################################
13533 #
13534 #
13535 void
Read(ref,...)13536 Read(ref,...)
13537   Image::Magick ref=NO_INIT
13538   ALIAS:
13539     ReadImage  = 1
13540     read       = 2
13541     readimage  = 3
13542   PPCODE:
13543   {
13544     AV
13545       *av;
13546 
13547     char
13548       **keep,
13549       **list;
13550 
13551     ExceptionInfo
13552       *exception;
13553 
13554     HV
13555       *hv;
13556 
13557     Image
13558       *image;
13559 
13560     int
13561       n;
13562 
13563     MagickBooleanType
13564       status;
13565 
13566     register char
13567       **p;
13568 
13569     register ssize_t
13570       i;
13571 
13572     ssize_t
13573       ac,
13574       number_images;
13575 
13576     STRLEN
13577       *length;
13578 
13579     struct PackageInfo
13580       *info,
13581       *package_info;
13582 
13583     SV
13584       *perl_exception,  /* Perl variable for storing messages */
13585       *reference,
13586       *rv,
13587       *sv;
13588 
13589     PERL_UNUSED_VAR(ref);
13590     PERL_UNUSED_VAR(ix);
13591     exception=AcquireExceptionInfo();
13592     perl_exception=newSVpv("",0);
13593     sv=NULL;
13594     package_info=(struct PackageInfo *) NULL;
13595     number_images=0;
13596     ac=(items < 2) ? 1 : items-1;
13597     list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13598     keep=list;
13599     length=(STRLEN *) NULL;
13600     if (list == (char **) NULL)
13601       {
13602         ThrowPerlException(exception,ResourceLimitError,
13603           "MemoryAllocationFailed",PackageName);
13604         goto PerlException;
13605       }
13606     length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13607     if (length == (STRLEN *) NULL)
13608       {
13609         ThrowPerlException(exception,ResourceLimitError,
13610           "MemoryAllocationFailed",PackageName);
13611         goto PerlException;
13612       }
13613     if (sv_isobject(ST(0)) == 0)
13614       {
13615         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13616           PackageName);
13617         goto PerlException;
13618       }
13619     reference=SvRV(ST(0));
13620     hv=SvSTASH(reference);
13621     if (SvTYPE(reference) != SVt_PVAV)
13622       {
13623         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13624           PackageName);
13625         goto PerlException;
13626       }
13627     av=(AV *) reference;
13628     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13629       exception);
13630     package_info=ClonePackageInfo(info,exception);
13631     n=1;
13632     if (items <= 1)
13633       *list=(char *) (*package_info->image_info->filename ?
13634         package_info->image_info->filename : "XC:black");
13635     else
13636       for (n=0, i=0; i < ac; i++)
13637       {
13638         list[n]=(char *) SvPV(ST(i+1),length[n]);
13639         if ((items >= 3) && strEQcase(list[n],"blob"))
13640           {
13641             void
13642               *blob;
13643 
13644             i++;
13645             blob=(void *) (SvPV(ST(i+1),length[n]));
13646             SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13647           }
13648         if ((items >= 3) && strEQcase(list[n],"filename"))
13649           continue;
13650         if ((items >= 3) && strEQcase(list[n],"file"))
13651           {
13652             FILE
13653               *file;
13654 
13655             PerlIO
13656               *io_info;
13657 
13658             i++;
13659             io_info=IoIFP(sv_2io(ST(i+1)));
13660             if (io_info == (PerlIO *) NULL)
13661               {
13662                 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13663                   PackageName);
13664                 continue;
13665               }
13666             file=PerlIO_findFILE(io_info);
13667             if (file == (FILE *) NULL)
13668               {
13669                 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13670                   PackageName);
13671                 continue;
13672               }
13673             SetImageInfoFile(package_info->image_info,file);
13674           }
13675         if ((items >= 3) && strEQcase(list[n],"magick"))
13676           continue;
13677         n++;
13678       }
13679     list[n]=(char *) NULL;
13680     keep=list;
13681     status=ExpandFilenames(&n,&list);
13682     if (status == MagickFalse)
13683       {
13684         ThrowPerlException(exception,ResourceLimitError,
13685           "MemoryAllocationFailed",PackageName);
13686         goto PerlException;
13687       }
13688     number_images=0;
13689     for (i=0; i < n; i++)
13690     {
13691       if ((package_info->image_info->file == (FILE *) NULL) &&
13692           (package_info->image_info->blob == (void *) NULL))
13693         image=ReadImages(package_info->image_info,list[i],exception);
13694       else
13695         {
13696           image=ReadImages(package_info->image_info,
13697             package_info->image_info->filename,exception);
13698           if (image != (Image *) NULL)
13699             DisassociateImageStream(image);
13700         }
13701       if (image == (Image *) NULL)
13702         break;
13703       for ( ; image; image=image->next)
13704       {
13705         AddImageToRegistry(sv,image);
13706         rv=newRV(sv);
13707         av_push(av,sv_bless(rv,hv));
13708         SvREFCNT_dec(sv);
13709         number_images++;
13710       }
13711     }
13712     /*
13713       Free resources.
13714     */
13715     for (i=0; i < n; i++)
13716       if (list[i] != (char *) NULL)
13717         for (p=keep; list[i] != *p++; )
13718           if (*p == (char *) NULL)
13719             {
13720               list[i]=(char *) RelinquishMagickMemory(list[i]);
13721               break;
13722             }
13723 
13724   PerlException:
13725     if (package_info != (struct PackageInfo *) NULL)
13726       DestroyPackageInfo(package_info);
13727     if (list && (list != keep))
13728       list=(char **) RelinquishMagickMemory(list);
13729     if (keep)
13730       keep=(char **) RelinquishMagickMemory(keep);
13731     if (length)
13732       length=(STRLEN *) RelinquishMagickMemory(length);
13733     InheritPerlException(exception,perl_exception);
13734     exception=DestroyExceptionInfo(exception);
13735     sv_setiv(perl_exception,(IV) number_images);
13736     SvPOK_on(perl_exception);
13737     ST(0)=sv_2mortal(perl_exception);
13738     XSRETURN(1);
13739   }
13740 
13741 #
13742 ###############################################################################
13743 #                                                                             #
13744 #                                                                             #
13745 #                                                                             #
13746 #   R e m o t e                                                               #
13747 #                                                                             #
13748 #                                                                             #
13749 #                                                                             #
13750 ###############################################################################
13751 #
13752 #
13753 void
Remote(ref,...)13754 Remote(ref,...)
13755   Image::Magick ref=NO_INIT
13756   ALIAS:
13757     RemoteCommand  = 1
13758     remote         = 2
13759     remoteCommand  = 3
13760   PPCODE:
13761   {
13762     AV
13763       *av;
13764 
13765     ExceptionInfo
13766       *exception;
13767 
13768     register ssize_t
13769       i;
13770 
13771     SV
13772       *perl_exception,
13773       *reference;
13774 
13775     struct PackageInfo
13776       *info;
13777 
13778     PERL_UNUSED_VAR(ref);
13779     PERL_UNUSED_VAR(ix);
13780     exception=AcquireExceptionInfo();
13781     perl_exception=newSVpv("",0);
13782     reference=SvRV(ST(0));
13783     av=(AV *) reference;
13784     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13785       exception);
13786     for (i=1; i < items; i++)
13787       (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13788         SvPV(ST(i),na),exception);
13789     InheritPerlException(exception,perl_exception);
13790     exception=DestroyExceptionInfo(exception);
13791     SvREFCNT_dec(perl_exception);    /* throw away all errors */
13792   }
13793 
13794 #
13795 ###############################################################################
13796 #                                                                             #
13797 #                                                                             #
13798 #                                                                             #
13799 #   S e t                                                                     #
13800 #                                                                             #
13801 #                                                                             #
13802 #                                                                             #
13803 ###############################################################################
13804 #
13805 #
13806 void
Set(ref,...)13807 Set(ref,...)
13808   Image::Magick ref=NO_INIT
13809   ALIAS:
13810     SetAttributes  = 1
13811     SetAttribute   = 2
13812     set            = 3
13813     setattributes  = 4
13814     setattribute   = 5
13815   PPCODE:
13816   {
13817     ExceptionInfo
13818       *exception;
13819 
13820     Image
13821       *image;
13822 
13823     register ssize_t
13824       i;
13825 
13826     struct PackageInfo
13827       *info;
13828 
13829     SV
13830       *perl_exception,
13831       *reference;  /* reference is the SV* of ref=SvIV(reference) */
13832 
13833     PERL_UNUSED_VAR(ref);
13834     PERL_UNUSED_VAR(ix);
13835     exception=AcquireExceptionInfo();
13836     perl_exception=newSVpv("",0);
13837     if (sv_isobject(ST(0)) == 0)
13838       {
13839         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13840           PackageName);
13841         goto PerlException;
13842       }
13843     reference=SvRV(ST(0));
13844     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13845     if (items == 2)
13846       SetAttribute(aTHX_ info,image,"size",ST(1),exception);
13847     else
13848       for (i=2; i < items; i+=2)
13849         SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
13850 
13851   PerlException:
13852     InheritPerlException(exception,perl_exception);
13853     exception=DestroyExceptionInfo(exception);
13854     sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
13855     SvPOK_on(perl_exception);
13856     ST(0)=sv_2mortal(perl_exception);
13857     XSRETURN(1);
13858   }
13859 
13860 #
13861 ###############################################################################
13862 #                                                                             #
13863 #                                                                             #
13864 #                                                                             #
13865 #   S e t P i x e l                                                           #
13866 #                                                                             #
13867 #                                                                             #
13868 #                                                                             #
13869 ###############################################################################
13870 #
13871 #
13872 void
SetPixel(ref,...)13873 SetPixel(ref,...)
13874   Image::Magick ref=NO_INIT
13875   ALIAS:
13876     setpixel = 1
13877     setPixel = 2
13878   PPCODE:
13879   {
13880     AV
13881       *av;
13882 
13883     char
13884       *attribute;
13885 
13886     ChannelType
13887       channel,
13888       channel_mask;
13889 
13890     ExceptionInfo
13891       *exception;
13892 
13893     Image
13894       *image;
13895 
13896     MagickBooleanType
13897       normalize;
13898 
13899     RectangleInfo
13900       region;
13901 
13902     register ssize_t
13903       i;
13904 
13905     register Quantum
13906       *q;
13907 
13908     ssize_t
13909       option;
13910 
13911     struct PackageInfo
13912       *info;
13913 
13914     SV
13915       *perl_exception,
13916       *reference;  /* reference is the SV* of ref=SvIV(reference) */
13917 
13918     PERL_UNUSED_VAR(ref);
13919     PERL_UNUSED_VAR(ix);
13920     exception=AcquireExceptionInfo();
13921     perl_exception=newSVpv("",0);
13922     reference=SvRV(ST(0));
13923     av=(AV *) reference;
13924     info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13925       exception);
13926     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13927     if (image == (Image *) NULL)
13928       {
13929         ThrowPerlException(exception,OptionError,"NoImagesDefined",
13930           PackageName);
13931         goto PerlException;
13932       }
13933     av=(AV *) NULL;
13934     normalize=MagickTrue;
13935     region.x=0;
13936     region.y=0;
13937     region.width=image->columns;
13938     region.height=1;
13939     if (items == 1)
13940       (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
13941     channel=DefaultChannels;
13942     for (i=2; i < items; i+=2)
13943     {
13944       attribute=(char *) SvPV(ST(i-1),na);
13945       switch (*attribute)
13946       {
13947         case 'C':
13948         case 'c':
13949         {
13950           if (LocaleCompare(attribute,"channel") == 0)
13951             {
13952               ssize_t
13953                 option;
13954 
13955               option=ParseChannelOption(SvPV(ST(i),na));
13956               if (option < 0)
13957                 {
13958                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
13959                     SvPV(ST(i),na));
13960                   return;
13961                 }
13962               channel=(ChannelType) option;
13963               break;
13964             }
13965           if (LocaleCompare(attribute,"color") == 0)
13966             {
13967               if (SvTYPE(ST(i)) != SVt_RV)
13968                 {
13969                   char
13970                     message[MagickPathExtent];
13971 
13972                   (void) FormatLocaleString(message,MagickPathExtent,
13973                     "invalid %.60s value",attribute);
13974                   ThrowPerlException(exception,OptionError,message,
13975                     SvPV(ST(i),na));
13976                 }
13977               av=(AV *) SvRV(ST(i));
13978               break;
13979             }
13980           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13981             attribute);
13982           break;
13983         }
13984         case 'g':
13985         case 'G':
13986         {
13987           if (LocaleCompare(attribute,"geometry") == 0)
13988             {
13989               (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
13990               break;
13991             }
13992           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13993             attribute);
13994           break;
13995         }
13996         case 'N':
13997         case 'n':
13998         {
13999           if (LocaleCompare(attribute,"normalize") == 0)
14000             {
14001               option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14002                 SvPV(ST(i),na));
14003               if (option < 0)
14004                 {
14005                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
14006                     SvPV(ST(i),na));
14007                   break;
14008                 }
14009              normalize=option != 0 ? MagickTrue : MagickFalse;
14010              break;
14011             }
14012           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14013             attribute);
14014           break;
14015         }
14016         case 'x':
14017         case 'X':
14018         {
14019           if (LocaleCompare(attribute,"x") == 0)
14020             {
14021               region.x=SvIV(ST(i));
14022               break;
14023             }
14024           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14025             attribute);
14026           break;
14027         }
14028         case 'y':
14029         case 'Y':
14030         {
14031           if (LocaleCompare(attribute,"y") == 0)
14032             {
14033               region.y=SvIV(ST(i));
14034               break;
14035             }
14036           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14037             attribute);
14038           break;
14039         }
14040         default:
14041         {
14042           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14043             attribute);
14044           break;
14045         }
14046       }
14047     }
14048     (void) SetImageStorageClass(image,DirectClass,exception);
14049     channel_mask=SetImageChannelMask(image,channel);
14050     q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
14051     if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14052         (SvTYPE(av) != SVt_PVAV))
14053       PUSHs(&sv_undef);
14054     else
14055       {
14056         double
14057           scale;
14058 
14059         register ssize_t
14060           i;
14061 
14062         i=0;
14063         scale=1.0;
14064         if (normalize != MagickFalse)
14065           scale=QuantumRange;
14066         if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14067             (i <= av_len(av)))
14068           {
14069             SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14070               av_fetch(av,i,0)))),q);
14071             i++;
14072           }
14073         if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14074             (i <= av_len(av)))
14075           {
14076             SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14077               av_fetch(av,i,0)))),q);
14078             i++;
14079           }
14080         if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14081             (i <= av_len(av)))
14082           {
14083             SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14084               av_fetch(av,i,0)))),q);
14085             i++;
14086           }
14087         if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14088             (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14089           {
14090             SetPixelBlack(image,ClampToQuantum(scale*
14091               SvNV(*(av_fetch(av,i,0)))),q);
14092             i++;
14093           }
14094         if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14095             (i <= av_len(av)))
14096           {
14097             SetPixelAlpha(image,ClampToQuantum(scale*
14098               SvNV(*(av_fetch(av,i,0)))),q);
14099             i++;
14100           }
14101         (void) SyncAuthenticPixels(image,exception);
14102       }
14103     (void) SetImageChannelMask(image,channel_mask);
14104 
14105   PerlException:
14106     InheritPerlException(exception,perl_exception);
14107     exception=DestroyExceptionInfo(exception);
14108     SvREFCNT_dec(perl_exception);
14109   }
14110 
14111 #
14112 ###############################################################################
14113 #                                                                             #
14114 #                                                                             #
14115 #                                                                             #
14116 #   S m u s h                                                                 #
14117 #                                                                             #
14118 #                                                                             #
14119 #                                                                             #
14120 ###############################################################################
14121 #
14122 #
14123 void
Smush(ref,...)14124 Smush(ref,...)
14125   Image::Magick ref=NO_INIT
14126   ALIAS:
14127     SmushImage  = 1
14128     smush       = 2
14129     smushimage  = 3
14130   PPCODE:
14131   {
14132     AV
14133       *av;
14134 
14135     char
14136       *attribute;
14137 
14138     ExceptionInfo
14139       *exception;
14140 
14141     HV
14142       *hv;
14143 
14144     Image
14145       *image;
14146 
14147     register ssize_t
14148       i;
14149 
14150     ssize_t
14151       offset,
14152       stack;
14153 
14154     struct PackageInfo
14155       *info;
14156 
14157     SV
14158       *av_reference,
14159       *perl_exception,
14160       *reference,
14161       *rv,
14162       *sv;
14163 
14164     PERL_UNUSED_VAR(ref);
14165     PERL_UNUSED_VAR(ix);
14166     exception=AcquireExceptionInfo();
14167     perl_exception=newSVpv("",0);
14168     sv=NULL;
14169     attribute=NULL;
14170     av=NULL;
14171     if (sv_isobject(ST(0)) == 0)
14172       {
14173         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14174           PackageName);
14175         goto PerlException;
14176       }
14177     reference=SvRV(ST(0));
14178     hv=SvSTASH(reference);
14179     av=newAV();
14180     av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14181     SvREFCNT_dec(av);
14182     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14183     if (image == (Image *) NULL)
14184       {
14185         ThrowPerlException(exception,OptionError,"NoImagesDefined",
14186           PackageName);
14187         goto PerlException;
14188       }
14189     info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14190     /*
14191       Get options.
14192     */
14193     offset=0;
14194     stack=MagickTrue;
14195     for (i=2; i < items; i+=2)
14196     {
14197       attribute=(char *) SvPV(ST(i-1),na);
14198       switch (*attribute)
14199       {
14200         case 'O':
14201         case 'o':
14202         {
14203           if (LocaleCompare(attribute,"offset") == 0)
14204             {
14205               offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14206               break;
14207             }
14208           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14209             attribute);
14210           break;
14211         }
14212         case 'S':
14213         case 's':
14214         {
14215           if (LocaleCompare(attribute,"stack") == 0)
14216             {
14217               stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14218                 SvPV(ST(i),na));
14219               if (stack < 0)
14220                 {
14221                   ThrowPerlException(exception,OptionError,"UnrecognizedType",
14222                     SvPV(ST(i),na));
14223                   return;
14224                 }
14225               break;
14226             }
14227           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14228             attribute);
14229           break;
14230         }
14231         default:
14232         {
14233           ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14234             attribute);
14235           break;
14236         }
14237       }
14238     }
14239     image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14240       exception);
14241     if (image == (Image *) NULL)
14242       goto PerlException;
14243     for ( ; image; image=image->next)
14244     {
14245       AddImageToRegistry(sv,image);
14246       rv=newRV(sv);
14247       av_push(av,sv_bless(rv,hv));
14248       SvREFCNT_dec(sv);
14249     }
14250     exception=DestroyExceptionInfo(exception);
14251     ST(0)=av_reference;
14252     SvREFCNT_dec(perl_exception);
14253     XSRETURN(1);
14254 
14255   PerlException:
14256     InheritPerlException(exception,perl_exception);
14257     exception=DestroyExceptionInfo(exception);
14258     sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14259     SvPOK_on(perl_exception);
14260     ST(0)=sv_2mortal(perl_exception);
14261     XSRETURN(1);
14262   }
14263 
14264 #
14265 ###############################################################################
14266 #                                                                             #
14267 #                                                                             #
14268 #                                                                             #
14269 #   S t a t i s t i c s                                                       #
14270 #                                                                             #
14271 #                                                                             #
14272 #                                                                             #
14273 ###############################################################################
14274 #
14275 #
14276 void
Statistics(ref,...)14277 Statistics(ref,...)
14278   Image::Magick ref=NO_INIT
14279   ALIAS:
14280     StatisticsImage = 1
14281     statistics      = 2
14282     statisticsimage = 3
14283   PPCODE:
14284   {
14285 #define ChannelStatistics(channel) \
14286 { \
14287   (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
14288     (double) channel_statistics[channel].depth); \
14289   PUSHs(sv_2mortal(newSVpv(message,0))); \
14290   (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
14291     channel_statistics[channel].minima/scale); \
14292   PUSHs(sv_2mortal(newSVpv(message,0))); \
14293   (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
14294     channel_statistics[channel].maxima/scale); \
14295   PUSHs(sv_2mortal(newSVpv(message,0))); \
14296   (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
14297     channel_statistics[channel].mean/scale); \
14298   PUSHs(sv_2mortal(newSVpv(message,0))); \
14299   (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
14300     channel_statistics[channel].standard_deviation/scale); \
14301   PUSHs(sv_2mortal(newSVpv(message,0))); \
14302   (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
14303     channel_statistics[channel].kurtosis); \
14304   PUSHs(sv_2mortal(newSVpv(message,0))); \
14305   (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
14306     channel_statistics[channel].skewness); \
14307   PUSHs(sv_2mortal(newSVpv(message,0))); \
14308   (void) FormatLocaleString(message,MagickPathExtent,"%.15g", \
14309     channel_statistics[channel].entropy); \
14310   PUSHs(sv_2mortal(newSVpv(message,0))); \
14311 }
14312 
14313     AV
14314       *av;
14315 
14316     char
14317       message[MagickPathExtent];
14318 
14319     ChannelStatistics
14320       *channel_statistics;
14321 
14322     double
14323       scale;
14324 
14325     ExceptionInfo
14326       *exception;
14327 
14328     Image
14329       *image;
14330 
14331     ssize_t
14332       count;
14333 
14334     struct PackageInfo
14335       *info;
14336 
14337     SV
14338       *perl_exception,
14339       *reference;
14340 
14341     PERL_UNUSED_VAR(ref);
14342     PERL_UNUSED_VAR(ix);
14343     exception=AcquireExceptionInfo();
14344     perl_exception=newSVpv("",0);
14345     av=NULL;
14346     if (sv_isobject(ST(0)) == 0)
14347       {
14348         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14349           PackageName);
14350         goto PerlException;
14351       }
14352     reference=SvRV(ST(0));
14353     av=newAV();
14354     SvREFCNT_dec(av);
14355     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14356     if (image == (Image *) NULL)
14357       {
14358         ThrowPerlException(exception,OptionError,"NoImagesDefined",
14359           PackageName);
14360         goto PerlException;
14361       }
14362     count=0;
14363     for ( ; image; image=image->next)
14364     {
14365       channel_statistics=GetImageStatistics(image,exception);
14366       if (channel_statistics == (ChannelStatistics *) NULL)
14367         continue;
14368       count++;
14369       EXTEND(sp,35*count);
14370       scale=(double) QuantumRange;
14371       ChannelStatistics(RedChannel);
14372       ChannelStatistics(GreenChannel);
14373       ChannelStatistics(BlueChannel);
14374       if (image->colorspace == CMYKColorspace)
14375         ChannelStatistics(BlackChannel);
14376       if (image->alpha_trait != UndefinedPixelTrait)
14377         ChannelStatistics(AlphaChannel);
14378       channel_statistics=(ChannelStatistics *)
14379         RelinquishMagickMemory(channel_statistics);
14380     }
14381 
14382   PerlException:
14383     InheritPerlException(exception,perl_exception);
14384     exception=DestroyExceptionInfo(exception);
14385     SvREFCNT_dec(perl_exception);
14386   }
14387 
14388 #
14389 ###############################################################################
14390 #                                                                             #
14391 #                                                                             #
14392 #                                                                             #
14393 #   S y n c A u t h e n t i c P i x e l s                                     #
14394 #                                                                             #
14395 #                                                                             #
14396 #                                                                             #
14397 ###############################################################################
14398 #
14399 #
14400 void
SyncAuthenticPixels(ref,...)14401 SyncAuthenticPixels(ref,...)
14402   Image::Magick ref = NO_INIT
14403   ALIAS:
14404     Syncauthenticpixels = 1
14405     SyncImagePixels = 2
14406     syncimagepixels = 3
14407   CODE:
14408   {
14409     ExceptionInfo
14410       *exception;
14411 
14412     Image
14413       *image;
14414 
14415     MagickBooleanType
14416       status;
14417 
14418     struct PackageInfo
14419       *info;
14420 
14421     SV
14422       *perl_exception,
14423       *reference;
14424 
14425     PERL_UNUSED_VAR(ref);
14426     PERL_UNUSED_VAR(ix);
14427     exception=AcquireExceptionInfo();
14428     perl_exception=newSVpv("",0);
14429     if (sv_isobject(ST(0)) == 0)
14430       {
14431         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14432           PackageName);
14433         goto PerlException;
14434       }
14435 
14436     reference=SvRV(ST(0));
14437     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14438     if (image == (Image *) NULL)
14439       {
14440         ThrowPerlException(exception,OptionError,"NoImagesDefined",
14441           PackageName);
14442         goto PerlException;
14443       }
14444 
14445     status=SyncAuthenticPixels(image,exception);
14446     if (status != MagickFalse)
14447       return;
14448 
14449   PerlException:
14450     InheritPerlException(exception,perl_exception);
14451     exception=DestroyExceptionInfo(exception);
14452     SvREFCNT_dec(perl_exception);  /* throw away all errors */
14453   }
14454 
14455 #
14456 ###############################################################################
14457 #                                                                             #
14458 #                                                                             #
14459 #                                                                             #
14460 #   W r i t e                                                                 #
14461 #                                                                             #
14462 #                                                                             #
14463 #                                                                             #
14464 ###############################################################################
14465 #
14466 #
14467 void
Write(ref,...)14468 Write(ref,...)
14469   Image::Magick ref=NO_INIT
14470   ALIAS:
14471     WriteImage    = 1
14472     write         = 2
14473     writeimage    = 3
14474   PPCODE:
14475   {
14476     char
14477       filename[MagickPathExtent];
14478 
14479     ExceptionInfo
14480       *exception;
14481 
14482     Image
14483       *image,
14484       *next;
14485 
14486     register ssize_t
14487       i;
14488 
14489     ssize_t
14490       number_images,
14491       scene;
14492 
14493     struct PackageInfo
14494       *info,
14495       *package_info;
14496 
14497     SV
14498       *perl_exception,
14499       *reference;
14500 
14501     PERL_UNUSED_VAR(ref);
14502     PERL_UNUSED_VAR(ix);
14503     exception=AcquireExceptionInfo();
14504     perl_exception=newSVpv("",0);
14505     number_images=0;
14506     package_info=(struct PackageInfo *) NULL;
14507     if (sv_isobject(ST(0)) == 0)
14508       {
14509         ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14510           PackageName);
14511         goto PerlException;
14512       }
14513     reference=SvRV(ST(0));
14514     image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14515     if (image == (Image *) NULL)
14516       {
14517         ThrowPerlException(exception,OptionError,"NoImagesDefined",
14518           PackageName);
14519         goto PerlException;
14520       }
14521     package_info=ClonePackageInfo(info,exception);
14522     if (items == 2)
14523       SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14524     else
14525       if (items > 2)
14526         for (i=2; i < items; i+=2)
14527           SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14528             exception);
14529     (void) CopyMagickString(filename,package_info->image_info->filename,
14530       MagickPathExtent);
14531     scene=0;
14532     for (next=image; next; next=next->next)
14533     {
14534       (void) CopyMagickString(next->filename,filename,MagickPathExtent);
14535       next->scene=scene++;
14536     }
14537     *package_info->image_info->magick='\0';
14538     SetImageInfo(package_info->image_info,(unsigned int)
14539       GetImageListLength(image),exception);
14540     for (next=image; next; next=next->next)
14541     {
14542       (void) WriteImage(package_info->image_info,next,exception);
14543       number_images++;
14544       if (package_info->image_info->adjoin)
14545         break;
14546     }
14547 
14548   PerlException:
14549     if (package_info != (struct PackageInfo *) NULL)
14550       DestroyPackageInfo(package_info);
14551     InheritPerlException(exception,perl_exception);
14552     exception=DestroyExceptionInfo(exception);
14553     sv_setiv(perl_exception,(IV) number_images);
14554     SvPOK_on(perl_exception);
14555     ST(0)=sv_2mortal(perl_exception);
14556     XSRETURN(1);
14557   }
14558