blob: 873c6b171840690afd65af67d721c3c2599cd3fe [file] [log] [blame]
cristy4a3ce0a2013-08-03 20:06:59 +00001/*
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 %
cristyde984cd2013-12-01 14:49:27 +000022% Cristy %
cristy4a3ce0a2013-08-03 20:06:59 +000023% February 1997 %
24% %
25% %
Cristy252dd2c2018-12-02 09:42:06 -050026% Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization %
cristy4a3ce0a2013-08-03 20:06:59 +000027% 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% %
Cristy0a176e12018-10-13 10:28:43 -040032% https://imagemagick.org/script/license.php %
cristy4a3ce0a2013-08-03 20:06:59 +000033% %
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)
52extern "C" {
53#endif
54
55#define PERL_NO_GET_CONTEXT
dirk190cc1c2015-06-16 11:48:37 +000056#include <MagickCore/MagickCore.h>
cristy4a3ce0a2013-08-03 20:06:59 +000057#include "EXTERN.h"
58#include "perl.h"
59#include "XSUB.h"
60#include <math.h>
cristy4a3ce0a2013-08-03 20:06:59 +000061#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)])
cristy3249b7b2014-02-09 21:43:14 +000077#define MagickPI 3.14159265358979323846264338327950288419716939937510
cristy4a3ce0a2013-08-03 20:06:59 +000078#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 \
cristy151b66d2015-04-15 10:50:31 +0000116 message[MagickPathExtent]; \
cristy4a3ce0a2013-08-03 20:06:59 +0000117 \
118 if ((exception)->severity != UndefinedException) \
119 { \
cristy151b66d2015-04-15 10:50:31 +0000120 (void) FormatLocaleString(message,MagickPathExtent,"Exception %d: %s%s%s%s",\
cristy4a3ce0a2013-08-03 20:06:59 +0000121 (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*/
143typedef enum
144{
Cristya9a04772018-01-16 11:44:34 -0500145 NullReference = 0,
cristy4a3ce0a2013-08-03 20:06:59 +0000146 ArrayReference = (~0),
147 RealReference = (~0)-1,
148 FileReference = (~0)-2,
149 ImageReference = (~0)-3,
150 IntegerReference = (~0)-4,
151 StringReference = (~0)-5
152} MagickReference;
153
154typedef struct _Arguments
155{
156 const char
157 *method;
158
159 ssize_t
160 type;
161} Arguments;
162
163struct ArgumentList
164{
165 ssize_t
166 integer_reference;
167
168 double
169 real_reference;
170
171 const char
172 *string_reference;
173
174 Image
175 *image_reference;
176
177 SV
178 *array_reference;
179
180 FILE
181 *file_reference;
182
183 size_t
184 length;
185};
186
187struct PackageInfo
188{
189 ImageInfo
190 *image_info;
191};
192
193typedef void
194 *Image__Magick; /* data type for the Image::Magick package */
195
196/*
197 Static declarations.
198*/
199static struct
200 Methods
201 {
202 const char
203 *name;
204
205 Arguments
206 arguments[MaxArguments];
207 } Methods[] =
208 {
209 { "Comment", { {"comment", StringReference} } },
210 { "Label", { {"label", StringReference} } },
211 { "AddNoise", { {"noise", MagickNoiseOptions}, {"attenuate", RealReference},
212 {"channel", MagickChannelOptions} } },
213 { "Colorize", { {"fill", StringReference}, {"blend", StringReference} } },
214 { "Border", { {"geometry", StringReference}, {"width", IntegerReference},
215 {"height", IntegerReference}, {"fill", StringReference},
216 {"bordercolor", StringReference}, {"color", StringReference},
217 {"compose", MagickComposeOptions} } },
218 { "Blur", { {"geometry", StringReference}, {"radius", RealReference},
219 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
220 { "Chop", { {"geometry", StringReference}, {"width", IntegerReference},
221 {"height", IntegerReference}, {"x", IntegerReference},
cristy260bd762014-08-15 12:46:34 +0000222 {"y", IntegerReference}, {"gravity", MagickGravityOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000223 { "Crop", { {"geometry", StringReference}, {"width", IntegerReference},
224 {"height", IntegerReference}, {"x", IntegerReference},
225 {"y", IntegerReference}, {"fuzz", StringReference},
226 {"gravity", MagickGravityOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500227 { "Despeckle", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000228 { "Edge", { {"radius", RealReference} } },
229 { "Emboss", { {"geometry", StringReference}, {"radius", RealReference},
230 {"sigma", RealReference} } },
Cristy8cb2e452018-01-14 14:46:31 -0500231 { "Enhance", { { (const char *) NULL, NullReference } } },
232 { "Flip", { { (const char *) NULL, NullReference } } },
233 { "Flop", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000234 { "Frame", { {"geometry", StringReference}, {"width", IntegerReference},
235 {"height", IntegerReference}, {"inner", IntegerReference},
236 {"outer", IntegerReference}, {"fill", StringReference},
237 {"color", StringReference}, {"compose", MagickComposeOptions} } },
238 { "Implode", { {"amount", RealReference},
239 {"interpolate", MagickInterpolateOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500240 { "Magnify", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000241 { "MedianFilter", { {"geometry", StringReference},
242 {"width", IntegerReference}, {"height", IntegerReference},
243 {"channel", MagickChannelOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500244 { "Minify", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000245 { "OilPaint", { {"radius", RealReference}, {"sigma", RealReference} } },
246 { "ReduceNoise", { {"geometry", StringReference},
247 {"width", IntegerReference},{"height", IntegerReference},
248 {"channel", MagickChannelOptions} } },
249 { "Roll", { {"geometry", StringReference}, {"x", IntegerReference},
250 {"y", IntegerReference} } },
cristy83a28a02013-08-03 20:25:48 +0000251 { "Rotate", { {"degrees", RealReference},
cristy4a3ce0a2013-08-03 20:06:59 +0000252 {"background", StringReference} } },
253 { "Sample", { {"geometry", StringReference}, {"width", IntegerReference},
254 {"height", IntegerReference} } },
255 { "Scale", { {"geometry", StringReference}, {"width", IntegerReference},
256 {"height", IntegerReference} } },
257 { "Shade", { {"geometry", StringReference}, {"azimuth", RealReference},
258 {"elevation", RealReference}, {"gray", MagickBooleanOptions} } },
259 { "Sharpen", { {"geometry", StringReference}, {"radius", RealReference},
260 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
261 { "Shear", { {"geometry", StringReference}, {"x", RealReference},
262 {"y", RealReference}, { "fill", StringReference},
263 {"color", StringReference} } },
Cristye3319c12015-08-24 07:11:48 -0400264 { "Spread", { {"radius", RealReference},
Cristy3ca633e2016-02-13 12:49:01 -0500265 {"interpolate", MagickInterpolateOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000266 { "Swirl", { {"degrees", RealReference},
267 {"interpolate", MagickInterpolateOptions} } },
268 { "Resize", { {"geometry", StringReference}, {"width", IntegerReference},
269 {"height", IntegerReference}, {"filter", MagickFilterOptions},
270 {"support", StringReference } } },
271 { "Zoom", { {"geometry", StringReference}, {"width", IntegerReference},
272 {"height", IntegerReference}, {"filter", MagickFilterOptions},
273 {"support", RealReference } } },
274 { "Annotate", { {"text", StringReference}, {"font", StringReference},
275 {"pointsize", RealReference}, {"density", StringReference},
276 {"undercolor", StringReference}, {"stroke", StringReference},
277 {"fill", StringReference}, {"geometry", StringReference},
278 {"sans", StringReference}, {"x", RealReference},
279 {"y", RealReference}, {"gravity", MagickGravityOptions},
280 {"translate", StringReference}, {"scale", StringReference},
281 {"rotate", RealReference}, {"skewX", RealReference},
282 {"skewY", RealReference}, {"strokewidth", RealReference},
283 {"antialias", MagickBooleanOptions}, {"family", StringReference},
284 {"style", MagickStyleOptions}, {"stretch", MagickStretchOptions},
285 {"weight", IntegerReference}, {"align", MagickAlignOptions},
286 {"encoding", StringReference}, {"affine", ArrayReference},
287 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
288 {"tile", ImageReference}, {"kerning", RealReference},
289 {"interline-spacing", RealReference},
290 {"interword-spacing", RealReference},
291 {"direction", MagickDirectionOptions} } },
292 { "ColorFloodfill", { {"geometry", StringReference},
293 {"x", IntegerReference}, {"y", IntegerReference},
294 {"fill", StringReference}, {"bordercolor", StringReference},
295 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
296 { "Composite", { {"image", ImageReference},
297 {"compose", MagickComposeOptions}, {"geometry", StringReference},
298 {"x", IntegerReference}, {"y", IntegerReference},
299 {"gravity", MagickGravityOptions}, {"opacity", StringReference},
300 {"tile", MagickBooleanOptions}, {"rotate", RealReference},
301 {"color", StringReference}, {"mask", ImageReference},
302 {"channel", MagickChannelOptions},
303 {"interpolate", MagickInterpolateOptions}, {"args", StringReference},
Cristy74e39292018-07-08 13:13:20 -0400304 {"blend", StringReference}, {"clip-to-self", MagickBooleanOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000305 { "Contrast", { {"sharpen", MagickBooleanOptions} } },
306 { "CycleColormap", { {"display", IntegerReference} } },
307 { "Draw", { {"primitive", MagickPrimitiveOptions},
308 {"points", StringReference}, {"method", MagickMethodOptions},
309 {"stroke", StringReference}, {"fill", StringReference},
310 {"strokewidth", RealReference}, {"font", StringReference},
311 {"bordercolor", StringReference}, {"x", RealReference},
312 {"y", RealReference}, {"translate", StringReference},
313 {"scale", StringReference}, {"rotate", RealReference},
314 {"skewX", RealReference}, {"skewY", RealReference},
315 {"tile", ImageReference}, {"pointsize", RealReference},
316 {"antialias", MagickBooleanOptions}, {"density", StringReference},
317 {"linewidth", RealReference}, {"affine", ArrayReference},
318 {"stroke-dashoffset", RealReference},
319 {"stroke-dasharray", ArrayReference},
320 {"interpolate", MagickInterpolateOptions},
321 {"origin", StringReference}, {"text", StringReference},
322 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
323 {"vector-graphics", StringReference}, {"kerning", RealReference},
324 {"interline-spacing", RealReference},
325 {"interword-spacing", RealReference},
326 {"direction", MagickDirectionOptions} } },
327 { "Equalize", { {"channel", MagickChannelOptions} } },
328 { "Gamma", { {"gamma", StringReference}, {"channel", MagickChannelOptions},
329 {"red", RealReference}, {"green", RealReference},
330 {"blue", RealReference} } },
331 { "Map", { {"image", ImageReference},
332 {"dither-method", MagickDitherOptions} } },
333 { "MatteFloodfill", { {"geometry", StringReference},
334 {"x", IntegerReference}, {"y", IntegerReference},
335 {"opacity", StringReference}, {"bordercolor", StringReference},
336 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
337 { "Modulate", { {"factor", StringReference}, {"hue", RealReference},
338 {"saturation", RealReference}, {"whiteness", RealReference},
339 {"brightness", RealReference}, {"lightness", RealReference},
340 {"blackness", RealReference} } },
341 { "Negate", { {"gray", MagickBooleanOptions},
342 {"channel", MagickChannelOptions} } },
343 { "Normalize", { {"channel", MagickChannelOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500344 { "NumberColors", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000345 { "Opaque", { {"color", StringReference}, {"fill", StringReference},
346 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
347 {"invert", MagickBooleanOptions} } },
348 { "Quantize", { {"colors", IntegerReference},
349 {"treedepth", IntegerReference}, {"colorspace", MagickColorspaceOptions},
350 {"dither", MagickDitherOptions}, {"measure", MagickBooleanOptions},
351 {"global", MagickBooleanOptions}, {"transparent-color", StringReference},
352 {"dither-method", MagickDitherOptions} } },
353 { "Raise", { {"geometry", StringReference}, {"width", IntegerReference},
354 {"height", IntegerReference}, {"raise", MagickBooleanOptions} } },
355 { "Segment", { {"geometry", StringReference},
356 {"cluster-threshold", RealReference},
357 {"smoothing-threshold", RealReference},
358 {"colorspace", MagickColorspaceOptions},
359 {"verbose", MagickBooleanOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500360 { "Signature", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000361 { "Solarize", { {"geometry", StringReference},
362 {"threshold", StringReference} } },
Cristy8cb2e452018-01-14 14:46:31 -0500363 { "Sync", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000364 { "Texture", { {"texture", ImageReference} } },
365 { "Evaluate", { {"value", RealReference},
366 {"operator", MagickEvaluateOptions},
367 {"channel", MagickChannelOptions} } },
368 { "Transparent", { {"color", StringReference}, {"opacity", StringReference},
369 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
370 { "Threshold", { {"threshold", StringReference},
371 {"channel", MagickChannelOptions} } },
372 { "Charcoal", { {"geometry", StringReference}, {"radius", RealReference},
373 {"sigma", RealReference} } },
374 { "Trim", { {"fuzz", StringReference} } },
375 { "Wave", { {"geometry", StringReference}, {"amplitude", RealReference},
376 {"wavelength", RealReference},
377 {"interpolate", MagickInterpolateOptions} } },
378 { "Separate", { {"channel", MagickChannelOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500379 { "Condense", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000380 { "Stereo", { {"image", ImageReference}, {"x", IntegerReference},
381 {"y", IntegerReference} } },
382 { "Stegano", { {"image", ImageReference}, {"offset", IntegerReference} } },
Cristy8cb2e452018-01-14 14:46:31 -0500383 { "Deconstruct", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000384 { "GaussianBlur", { {"geometry", StringReference},
385 {"radius", RealReference}, {"sigma", RealReference},
386 {"channel", MagickChannelOptions} } },
387 { "Convolve", { {"coefficients", ArrayReference},
388 {"channel", MagickChannelOptions}, {"bias", StringReference},
389 {"kernel", StringReference} } },
390 { "Profile", { {"name", StringReference}, {"profile", StringReference},
391 { "rendering-intent", MagickIntentOptions},
392 { "black-point-compensation", MagickBooleanOptions} } },
393 { "UnsharpMask", { {"geometry", StringReference},
394 {"radius", RealReference}, {"sigma", RealReference},
395 {"gain", RealReference}, {"threshold", RealReference},
396 {"channel", MagickChannelOptions} } },
397 { "MotionBlur", { {"geometry", StringReference},
398 {"radius", RealReference}, {"sigma", RealReference},
399 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
400 { "OrderedDither", { {"threshold", StringReference},
401 {"channel", MagickChannelOptions} } },
402 { "Shave", { {"geometry", StringReference}, {"width", IntegerReference},
403 {"height", IntegerReference} } },
404 { "Level", { {"levels", StringReference}, {"black-point", RealReference},
405 {"white-point", RealReference}, {"gamma", RealReference},
406 {"channel", MagickChannelOptions}, {"level", StringReference} } },
407 { "Clip", { {"id", StringReference}, {"inside", MagickBooleanOptions} } },
408 { "AffineTransform", { {"affine", ArrayReference},
409 {"translate", StringReference}, {"scale", StringReference},
410 {"rotate", RealReference}, {"skewX", RealReference},
411 {"skewY", RealReference}, {"interpolate", MagickInterpolateOptions},
412 {"background", StringReference} } },
413 { "Difference", { {"image", ImageReference}, {"fuzz", StringReference} } },
414 { "AdaptiveThreshold", { {"geometry", StringReference},
Cristy9f252542018-11-21 19:13:46 -0500415 {"width", IntegerReference}, {"height", IntegerReference},
416 {"bias", RealReference} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000417 { "Resample", { {"density", StringReference}, {"x", RealReference},
418 {"y", RealReference}, {"filter", MagickFilterOptions},
419 {"support", RealReference } } },
420 { "Describe", { {"file", FileReference} } },
421 { "BlackThreshold", { {"threshold", StringReference},
422 {"channel", MagickChannelOptions} } },
423 { "WhiteThreshold", { {"threshold", StringReference},
424 {"channel", MagickChannelOptions} } },
cristy60c73c02014-03-25 12:09:58 +0000425 { "RotationalBlur", { {"geometry", StringReference},
426 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000427 { "Thumbnail", { {"geometry", StringReference}, {"width", IntegerReference},
428 {"height", IntegerReference} } },
Cristy8cb2e452018-01-14 14:46:31 -0500429 { "Strip", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000430 { "Tint", { {"fill", StringReference}, {"blend", StringReference} } },
431 { "Channel", { {"channel", MagickChannelOptions} } },
432 { "Splice", { {"geometry", StringReference}, {"width", IntegerReference},
433 {"height", IntegerReference}, {"x", IntegerReference},
434 {"y", IntegerReference}, {"fuzz", StringReference},
435 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
436 { "Posterize", { {"levels", IntegerReference},
437 {"dither", MagickBooleanOptions} } },
438 { "Shadow", { {"geometry", StringReference}, {"alpha", RealReference},
439 {"sigma", RealReference}, {"x", IntegerReference},
440 {"y", IntegerReference} } },
441 { "Identify", { {"file", FileReference}, {"features", StringReference},
442 {"unique", MagickBooleanOptions} } },
443 { "SepiaTone", { {"threshold", RealReference} } },
444 { "SigmoidalContrast", { {"geometry", StringReference},
445 {"contrast", RealReference}, {"mid-point", RealReference},
446 {"channel", MagickChannelOptions}, {"sharpen", MagickBooleanOptions} } },
447 { "Extent", { {"geometry", StringReference}, {"width", IntegerReference},
448 {"height", IntegerReference}, {"x", IntegerReference},
449 {"y", IntegerReference}, {"fuzz", StringReference},
450 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
451 { "Vignette", { {"geometry", StringReference}, {"radius", RealReference},
452 {"sigma", RealReference}, {"x", IntegerReference},
453 {"y", IntegerReference}, {"background", StringReference} } },
454 { "ContrastStretch", { {"levels", StringReference},
455 {"black-point", RealReference},{"white-point", RealReference},
456 {"channel", MagickChannelOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500457 { "Sans0", { { (const char *) NULL, NullReference } } },
458 { "Sans1", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000459 { "AdaptiveSharpen", { {"geometry", StringReference},
460 {"radius", RealReference}, {"sigma", RealReference},
461 {"bias", RealReference}, {"channel", MagickChannelOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500462 { "Transpose", { { (const char *) NULL, NullReference } } },
463 { "Transverse", { { (const char *) NULL, NullReference } } },
464 { "AutoOrient", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000465 { "AdaptiveBlur", { {"geometry", StringReference},
466 {"radius", RealReference}, {"sigma", RealReference},
467 {"channel", MagickChannelOptions} } },
468 { "Sketch", { {"geometry", StringReference},
469 {"radius", RealReference}, {"sigma", RealReference},
470 {"angle", RealReference} } },
Cristy8cb2e452018-01-14 14:46:31 -0500471 { "UniqueColors", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000472 { "AdaptiveResize", { {"geometry", StringReference},
473 {"width", IntegerReference}, {"height", IntegerReference},
474 {"filter", MagickFilterOptions}, {"support", StringReference },
475 {"blur", RealReference } } },
476 { "ClipMask", { {"mask", ImageReference} } },
477 { "LinearStretch", { {"levels", StringReference},
478 {"black-point", RealReference},{"white-point", RealReference} } },
479 { "ColorMatrix", { {"matrix", ArrayReference} } },
480 { "Mask", { {"mask", ImageReference} } },
481 { "Polaroid", { {"caption", StringReference}, {"angle", RealReference},
482 {"font", StringReference}, {"stroke", StringReference},
483 {"fill", StringReference}, {"strokewidth", RealReference},
484 {"pointsize", RealReference}, {"gravity", MagickGravityOptions},
485 {"background", StringReference},
486 {"interpolate", MagickInterpolateOptions} } },
487 { "FloodfillPaint", { {"geometry", StringReference},
488 {"x", IntegerReference}, {"y", IntegerReference},
489 {"fill", StringReference}, {"bordercolor", StringReference},
490 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
491 {"invert", MagickBooleanOptions} } },
492 { "Distort", { {"points", ArrayReference}, {"method", MagickDistortOptions},
493 {"virtual-pixel", MagickVirtualPixelOptions},
494 {"best-fit", MagickBooleanOptions} } },
495 { "Clut", { {"image", ImageReference},
496 {"interpolate", MagickInterpolateOptions},
497 {"channel", MagickChannelOptions} } },
498 { "LiquidRescale", { {"geometry", StringReference},
499 {"width", IntegerReference}, {"height", IntegerReference},
500 {"delta-x", RealReference}, {"rigidity", RealReference } } },
501 { "Encipher", { {"passphrase", StringReference} } },
502 { "Decipher", { {"passphrase", StringReference} } },
503 { "Deskew", { {"geometry", StringReference},
504 {"threshold", StringReference} } },
505 { "Remap", { {"image", ImageReference},
506 {"dither-method", MagickDitherOptions} } },
507 { "SparseColor", { {"points", ArrayReference},
508 {"method", MagickSparseColorOptions},
509 {"virtual-pixel", MagickVirtualPixelOptions},
510 {"channel", MagickChannelOptions} } },
511 { "Function", { {"parameters", ArrayReference},
512 {"function", MagickFunctionOptions},
513 {"virtual-pixel", MagickVirtualPixelOptions} } },
514 { "SelectiveBlur", { {"geometry", StringReference},
515 {"radius", RealReference}, {"sigma", RealReference},
516 {"threshold", RealReference}, {"channel", MagickChannelOptions} } },
517 { "HaldClut", { {"image", ImageReference},
518 {"channel", MagickChannelOptions} } },
519 { "BlueShift", { {"factor", StringReference} } },
520 { "ForwardFourierTransform", { {"magnitude", MagickBooleanOptions} } },
521 { "InverseFourierTransform", { {"magnitude", MagickBooleanOptions} } },
522 { "ColorDecisionList", {
523 {"color-correction-collection", StringReference} } },
524 { "AutoGamma", { {"channel", MagickChannelOptions} } },
525 { "AutoLevel", { {"channel", MagickChannelOptions} } },
526 { "LevelColors", { {"invert", MagickBooleanOptions},
527 {"black-point", StringReference}, {"white-point", StringReference},
528 {"channel", MagickChannelOptions}, {"invert", MagickBooleanOptions} } },
529 { "Clamp", { {"channel", MagickChannelOptions} } },
530 { "BrightnessContrast", { {"levels", StringReference},
531 {"brightness", RealReference},{"contrast", RealReference},
532 {"channel", MagickChannelOptions} } },
533 { "Morphology", { {"kernel", StringReference},
534 {"channel", MagickChannelOptions}, {"method", MagickMorphologyOptions},
535 {"iterations", IntegerReference} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000536 { "Mode", { {"geometry", StringReference},
537 {"width", IntegerReference},{"height", IntegerReference},
538 {"channel", MagickChannelOptions} } },
539 { "Statistic", { {"geometry", StringReference},
540 {"width", IntegerReference},{"height", IntegerReference},
541 {"channel", MagickChannelOptions}, {"type", MagickStatisticOptions} } },
542 { "Perceptible", { {"epsilon", RealReference},
543 {"channel", MagickChannelOptions} } },
544 { "Poly", { {"terms", ArrayReference},
545 {"channel", MagickChannelOptions} } },
546 { "Grayscale", { {"method", MagickNoiseOptions} } },
cristy4ceadb82014-03-29 15:30:43 +0000547 { "CannyEdge", { {"geometry", StringReference},
548 {"radius", RealReference}, {"sigma", RealReference},
cristycfe7bf02014-04-04 15:31:52 +0000549 {"lower-percent", RealReference}, {"upper-percent", RealReference} } },
cristy2fc10e52014-04-26 14:13:53 +0000550 { "HoughLine", { {"geometry", StringReference},
cristy4e215022014-04-19 18:02:35 +0000551 {"width", IntegerReference}, {"height", IntegerReference},
552 {"threshold", IntegerReference} } },
cristy2fc10e52014-04-26 14:13:53 +0000553 { "MeanShift", { {"geometry", StringReference},
554 {"width", IntegerReference}, {"height", IntegerReference},
cristy1309fc32014-04-26 18:48:37 +0000555 {"distance", RealReference} } },
cristy3b207f82014-09-27 14:21:20 +0000556 { "Kuwahara", { {"geometry", StringReference}, {"radius", RealReference},
557 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
Cristy2ca0e9a2016-01-01 08:36:14 -0500558 { "ConnectedComponents", { {"connectivity", IntegerReference} } },
cristyf3a724a2015-06-25 13:02:53 +0000559 { "CopyPixels", { {"image", ImageReference}, {"geometry", StringReference},
560 {"width", IntegerReference}, {"height", IntegerReference},
561 {"x", IntegerReference}, {"y", IntegerReference},
Cristy532b3382018-08-05 17:56:56 -0400562 {"gravity", MagickGravityOptions}, {"offset", StringReference},
cristyf3a724a2015-06-25 13:02:53 +0000563 {"dx", IntegerReference}, {"dy", IntegerReference} } },
Cristy5488c982016-02-13 14:07:50 -0500564 { "Color", { {"color", StringReference} } },
Cristyc1759412016-02-27 12:17:58 -0500565 { "WaveletDenoise", { {"geometry", StringReference},
566 {"threshold", RealReference}, {"softness", RealReference},
Cristy2d830ed2016-02-21 10:54:16 -0500567 {"channel", MagickChannelOptions} } },
Cristy99a57162016-12-05 11:47:57 -0500568 { "Colorspace", { {"colorspace", MagickColorspaceOptions} } },
Cristy53353872017-07-02 12:24:24 -0400569 { "AutoThreshold", { {"method", MagickAutoThresholdOptions} } },
Cristy532b3382018-08-05 17:56:56 -0400570 { "RangeThreshold", { {"geometry", StringReference},
Cristy72f24752018-08-14 20:17:26 -0400571 {"low-black", RealReference}, {"low-white", RealReference},
572 {"high-white", RealReference}, {"high-black", RealReference},
Cristy532b3382018-08-05 17:56:56 -0400573 {"channel", MagickChannelOptions} } },
Cristy30263282018-12-11 16:40:25 -0500574 { "CLAHE", { {"geometry", StringReference}, {"width", IntegerReference},
575 {"height", IntegerReference}, {"number-bins", IntegerReference},
Cristy768e9002019-01-08 07:35:16 -0500576 {"clip-limit", RealReference} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000577 };
578
579static SplayTreeInfo
580 *magick_registry = (SplayTreeInfo *) NULL;
581
582/*
583 Forward declarations.
584*/
585static Image
586 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
587
588static ssize_t
589 strEQcase(const char *,const char *);
590
591/*
592%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
593% %
594% %
595% %
596% C l o n e P a c k a g e I n f o %
597% %
598% %
599% %
600%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
601%
602% ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
603% a new one.
604%
605% The format of the ClonePackageInfo routine is:
606%
607% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
608% exception)
609%
610% A description of each parameter follows:
611%
612% o info: a structure of type info.
613%
614% o exception: Return any errors or warnings in this structure.
615%
616*/
617static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
618 ExceptionInfo *exception)
619{
620 struct PackageInfo
621 *clone_info;
622
623 clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
624 if (clone_info == (struct PackageInfo *) NULL)
625 {
626 ThrowPerlException(exception,ResourceLimitError,
627 "UnableToClonePackageInfo",PackageName);
628 return((struct PackageInfo *) NULL);
629 }
630 if (info == (struct PackageInfo *) NULL)
631 {
632 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
633 return(clone_info);
634 }
635 *clone_info=(*info);
636 clone_info->image_info=CloneImageInfo(info->image_info);
637 return(clone_info);
638}
639
640/*
641%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
642% %
643% %
644% %
645% c o n s t a n t %
646% %
647% %
648% %
649%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
650%
651% constant() returns a double value for the specified name.
652%
653% The format of the constant routine is:
654%
655% double constant(char *name,ssize_t sans)
656%
657% A description of each parameter follows:
658%
659% o value: Method constant returns a double value for the specified name.
660%
661% o name: The name of the constant.
662%
663% o sans: This integer value is not used.
664%
665*/
666static double constant(char *name,ssize_t sans)
667{
668 (void) sans;
669 errno=0;
670 switch (*name)
671 {
672 case 'B':
673 {
674 if (strEQ(name,"BlobError"))
675 return(BlobError);
676 if (strEQ(name,"BlobWarning"))
677 return(BlobWarning);
678 break;
679 }
680 case 'C':
681 {
682 if (strEQ(name,"CacheError"))
683 return(CacheError);
684 if (strEQ(name,"CacheWarning"))
685 return(CacheWarning);
686 if (strEQ(name,"CoderError"))
687 return(CoderError);
688 if (strEQ(name,"CoderWarning"))
689 return(CoderWarning);
690 if (strEQ(name,"ConfigureError"))
691 return(ConfigureError);
692 if (strEQ(name,"ConfigureWarning"))
693 return(ConfigureWarning);
694 if (strEQ(name,"CorruptImageError"))
695 return(CorruptImageError);
696 if (strEQ(name,"CorruptImageWarning"))
697 return(CorruptImageWarning);
698 break;
699 }
700 case 'D':
701 {
702 if (strEQ(name,"DelegateError"))
703 return(DelegateError);
704 if (strEQ(name,"DelegateWarning"))
705 return(DelegateWarning);
706 if (strEQ(name,"DrawError"))
707 return(DrawError);
708 if (strEQ(name,"DrawWarning"))
709 return(DrawWarning);
710 break;
711 }
712 case 'E':
713 {
714 if (strEQ(name,"ErrorException"))
715 return(ErrorException);
716 if (strEQ(name,"ExceptionError"))
717 return(CoderError);
718 if (strEQ(name,"ExceptionWarning"))
719 return(CoderWarning);
720 break;
721 }
722 case 'F':
723 {
724 if (strEQ(name,"FatalErrorException"))
725 return(FatalErrorException);
726 if (strEQ(name,"FileOpenError"))
727 return(FileOpenError);
728 if (strEQ(name,"FileOpenWarning"))
729 return(FileOpenWarning);
730 break;
731 }
732 case 'I':
733 {
734 if (strEQ(name,"ImageError"))
735 return(ImageError);
736 if (strEQ(name,"ImageWarning"))
737 return(ImageWarning);
738 break;
739 }
740 case 'M':
741 {
742 if (strEQ(name,"MaxRGB"))
743 return(QuantumRange);
744 if (strEQ(name,"MissingDelegateError"))
745 return(MissingDelegateError);
746 if (strEQ(name,"MissingDelegateWarning"))
747 return(MissingDelegateWarning);
748 if (strEQ(name,"ModuleError"))
749 return(ModuleError);
750 if (strEQ(name,"ModuleWarning"))
751 return(ModuleWarning);
752 break;
753 }
754 case 'O':
755 {
756 if (strEQ(name,"Opaque"))
757 return(OpaqueAlpha);
758 if (strEQ(name,"OptionError"))
759 return(OptionError);
760 if (strEQ(name,"OptionWarning"))
761 return(OptionWarning);
762 break;
763 }
764 case 'Q':
765 {
766 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
767 return(MAGICKCORE_QUANTUM_DEPTH);
768 if (strEQ(name,"QuantumDepth"))
769 return(MAGICKCORE_QUANTUM_DEPTH);
770 if (strEQ(name,"QuantumRange"))
771 return(QuantumRange);
772 break;
773 }
774 case 'R':
775 {
776 if (strEQ(name,"ResourceLimitError"))
777 return(ResourceLimitError);
778 if (strEQ(name,"ResourceLimitWarning"))
779 return(ResourceLimitWarning);
780 if (strEQ(name,"RegistryError"))
781 return(RegistryError);
782 if (strEQ(name,"RegistryWarning"))
783 return(RegistryWarning);
784 break;
785 }
786 case 'S':
787 {
788 if (strEQ(name,"StreamError"))
789 return(StreamError);
790 if (strEQ(name,"StreamWarning"))
791 return(StreamWarning);
792 if (strEQ(name,"Success"))
793 return(0);
794 break;
795 }
796 case 'T':
797 {
798 if (strEQ(name,"Transparent"))
799 return(TransparentAlpha);
800 if (strEQ(name,"TypeError"))
801 return(TypeError);
802 if (strEQ(name,"TypeWarning"))
803 return(TypeWarning);
804 break;
805 }
806 case 'W':
807 {
808 if (strEQ(name,"WarningException"))
809 return(WarningException);
810 break;
811 }
812 case 'X':
813 {
814 if (strEQ(name,"XServerError"))
815 return(XServerError);
816 if (strEQ(name,"XServerWarning"))
817 return(XServerWarning);
818 break;
819 }
820 }
821 errno=EINVAL;
822 return(0);
823}
824
825/*
826%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
827% %
828% %
829% %
830% D e s t r o y P a c k a g e I n f o %
831% %
832% %
833% %
834%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
835%
836% Method DestroyPackageInfo frees a previously created info structure.
837%
838% The format of the DestroyPackageInfo routine is:
839%
840% DestroyPackageInfo(struct PackageInfo *info)
841%
842% A description of each parameter follows:
843%
844% o info: a structure of type info.
845%
846*/
847static void DestroyPackageInfo(struct PackageInfo *info)
848{
849 info->image_info=DestroyImageInfo(info->image_info);
850 info=(struct PackageInfo *) RelinquishMagickMemory(info);
851}
852
853/*
854%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
855% %
856% %
857% %
858% G e t L i s t %
859% %
860% %
861% %
862%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
863%
864% Method GetList is recursively called by SetupList to traverse the
865% Image__Magick reference. If building an reference_vector (see SetupList),
866% *current is the current position in *reference_vector and *last is the final
867% entry in *reference_vector.
868%
869% The format of the GetList routine is:
870%
871% GetList(info)
872%
873% A description of each parameter follows:
874%
875% o info: a structure of type info.
876%
877*/
878static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
879 ssize_t *current,ssize_t *last,ExceptionInfo *exception)
880{
881 Image
882 *image;
883
884 if (reference == (SV *) NULL)
885 return(NULL);
886 switch (SvTYPE(reference))
887 {
888 case SVt_PVAV:
889 {
890 AV
891 *av;
892
893 Image
894 *head,
895 *previous;
896
897 register ssize_t
898 i;
899
900 ssize_t
901 n;
902
903 /*
904 Array of images.
905 */
906 previous=(Image *) NULL;
907 head=(Image *) NULL;
908 av=(AV *) reference;
909 n=av_len(av);
910 for (i=0; i <= n; i++)
911 {
912 SV
913 **rv;
914
915 rv=av_fetch(av,i,0);
916 if (rv && *rv && sv_isobject(*rv))
917 {
918 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
919 exception);
920 if (image == (Image *) NULL)
921 continue;
922 if (image == previous)
923 {
924 image=CloneImage(image,0,0,MagickTrue,exception);
925 if (image == (Image *) NULL)
926 return(NULL);
927 }
928 image->previous=previous;
929 *(previous ? &previous->next : &head)=image;
930 for (previous=image; previous->next; previous=previous->next) ;
931 }
932 }
933 return(head);
934 }
935 case SVt_PVMG:
936 {
937 /*
938 Blessed scalar, one image.
939 */
940 image=INT2PTR(Image *,SvIV(reference));
941 if (image == (Image *) NULL)
942 return(NULL);
943 image->previous=(Image *) NULL;
944 image->next=(Image *) NULL;
945 if (reference_vector)
946 {
947 if (*current == *last)
948 {
949 *last+=256;
950 if (*reference_vector == (SV **) NULL)
951 *reference_vector=(SV **) AcquireQuantumMemory(*last,
952 sizeof(*reference_vector));
953 else
954 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
955 *last,sizeof(*reference_vector));
956 }
957 if (*reference_vector == (SV **) NULL)
958 {
959 ThrowPerlException(exception,ResourceLimitError,
960 "MemoryAllocationFailed",PackageName);
961 return((Image *) NULL);
962 }
963 (*reference_vector)[*current]=reference;
964 (*reference_vector)[++(*current)]=NULL;
965 }
966 return(image);
967 }
968 default:
969 break;
970 }
971 (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
972 (double) SvTYPE(reference));
973 return((Image *) NULL);
974}
975
976/*
977%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
978% %
979% %
980% %
981% G e t P a c k a g e I n f o %
982% %
983% %
984% %
985%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
986%
987% Method GetPackageInfo looks up or creates an info structure for the given
988% Image__Magick reference. If it does create a new one, the information in
989% package_info is used to initialize it.
990%
991% The format of the GetPackageInfo routine is:
992%
993% struct PackageInfo *GetPackageInfo(void *reference,
994% struct PackageInfo *package_info,ExceptionInfo *exception)
995%
996% A description of each parameter follows:
997%
998% o info: a structure of type info.
999%
1000% o exception: Return any errors or warnings in this structure.
1001%
1002*/
1003static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
1004 struct PackageInfo *package_info,ExceptionInfo *exception)
1005{
1006 char
cristy151b66d2015-04-15 10:50:31 +00001007 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00001008
1009 struct PackageInfo
1010 *clone_info;
1011
1012 SV
1013 *sv;
1014
cristy151b66d2015-04-15 10:50:31 +00001015 (void) FormatLocaleString(message,MagickPathExtent,"%s::package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00001016 PackageName,XS_VERSION,reference);
1017 sv=perl_get_sv(message,(TRUE | 0x02));
1018 if (sv == (SV *) NULL)
1019 {
1020 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
1021 message);
1022 return(package_info);
1023 }
1024 if (SvREFCNT(sv) == 0)
1025 (void) SvREFCNT_inc(sv);
1026 if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
1027 return(clone_info);
1028 clone_info=ClonePackageInfo(package_info,exception);
1029 sv_setiv(sv,PTR2IV(clone_info));
1030 return(clone_info);
1031}
1032
1033/*
1034%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1035% %
1036% %
1037% %
1038% S e t A t t r i b u t e %
1039% %
1040% %
1041% %
1042%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1043%
1044% SetAttribute() sets the attribute to the value in sval. This can change
1045% either or both of image or info.
1046%
1047% The format of the SetAttribute routine is:
1048%
1049% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1050% SV *sval,ExceptionInfo *exception)
1051%
1052% A description of each parameter follows:
1053%
1054% o list: a list of strings.
1055%
1056% o string: a character string.
1057%
1058*/
1059
1060static double SiPrefixToDoubleInterval(const char *string,const double interval)
1061{
1062 char
1063 *q;
1064
1065 double
1066 value;
1067
1068 value=InterpretSiPrefixValue(string,&q);
1069 if (*q == '%')
1070 value*=interval/100.0;
1071 return(value);
1072}
1073
1074static inline double StringToDouble(const char *string,char **sentinal)
1075{
1076 return(InterpretLocaleValue(string,sentinal));
1077}
1078
1079static double StringToDoubleInterval(const char *string,const double interval)
1080{
1081 char
1082 *q;
1083
1084 double
1085 value;
1086
1087 value=InterpretLocaleValue(string,&q);
1088 if (*q == '%')
1089 value*=interval/100.0;
1090 return(value);
1091}
1092
1093static inline ssize_t StringToLong(const char *value)
1094{
1095 return(strtol(value,(char **) NULL,10));
1096}
1097
1098static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1099 const char *attribute,SV *sval,ExceptionInfo *exception)
1100{
1101 GeometryInfo
1102 geometry_info;
1103
1104 long
1105 x,
1106 y;
1107
1108 PixelInfo
1109 pixel;
1110
1111 MagickStatusType
1112 flags;
1113
1114 PixelInfo
1115 *color,
1116 target_color;
1117
1118 ssize_t
1119 sp;
1120
1121 switch (*attribute)
1122 {
1123 case 'A':
1124 case 'a':
1125 {
1126 if (LocaleCompare(attribute,"adjoin") == 0)
1127 {
1128 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1129 SvPV(sval,na)) : SvIV(sval);
1130 if (sp < 0)
1131 {
1132 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1133 SvPV(sval,na));
1134 break;
1135 }
1136 if (info)
1137 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1138 break;
1139 }
1140 if (LocaleCompare(attribute,"alpha") == 0)
1141 {
1142 sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1143 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1144 if (sp < 0)
1145 {
1146 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1147 SvPV(sval,na));
1148 break;
1149 }
1150 for ( ; image; image=image->next)
1151 (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1152 exception);
1153 break;
1154 }
1155 if (LocaleCompare(attribute,"antialias") == 0)
1156 {
1157 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1158 SvPV(sval,na)) : SvIV(sval);
1159 if (sp < 0)
1160 {
1161 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1162 SvPV(sval,na));
1163 break;
1164 }
1165 if (info)
1166 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1167 break;
1168 }
1169 if (LocaleCompare(attribute,"area-limit") == 0)
1170 {
1171 MagickSizeType
1172 limit;
1173
1174 limit=MagickResourceInfinity;
1175 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1176 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1177 100.0);
1178 (void) SetMagickResourceLimit(AreaResource,limit);
1179 break;
1180 }
1181 if (LocaleCompare(attribute,"attenuate") == 0)
1182 {
1183 if (info)
1184 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1185 break;
1186 }
1187 if (LocaleCompare(attribute,"authenticate") == 0)
1188 {
1189 if (info)
1190 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1191 break;
1192 }
1193 if (info)
1194 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1195 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001196 {
1197 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstra337c9bc2017-04-03 16:04:21 +02001198 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001199 }
cristy4a3ce0a2013-08-03 20:06:59 +00001200 break;
1201 }
1202 case 'B':
1203 case 'b':
1204 {
1205 if (LocaleCompare(attribute,"background") == 0)
1206 {
1207 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1208 exception);
1209 if (info)
1210 info->image_info->background_color=target_color;
1211 for ( ; image; image=image->next)
1212 image->background_color=target_color;
1213 break;
1214 }
1215 if (LocaleCompare(attribute,"blue-primary") == 0)
1216 {
1217 for ( ; image; image=image->next)
1218 {
1219 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1220 image->chromaticity.blue_primary.x=geometry_info.rho;
1221 image->chromaticity.blue_primary.y=geometry_info.sigma;
1222 if ((flags & SigmaValue) == 0)
1223 image->chromaticity.blue_primary.y=
1224 image->chromaticity.blue_primary.x;
1225 }
1226 break;
1227 }
1228 if (LocaleCompare(attribute,"bordercolor") == 0)
1229 {
1230 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1231 exception);
1232 if (info)
1233 info->image_info->border_color=target_color;
1234 for ( ; image; image=image->next)
1235 image->border_color=target_color;
1236 break;
1237 }
1238 if (info)
1239 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1240 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001241 {
1242 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001243 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001244 }
cristy4a3ce0a2013-08-03 20:06:59 +00001245 break;
1246 }
1247 case 'C':
1248 case 'c':
1249 {
1250 if (LocaleCompare(attribute,"cache-threshold") == 0)
1251 {
1252 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1253 SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1254 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1255 (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1256 break;
1257 }
1258 if (LocaleCompare(attribute,"clip-mask") == 0)
1259 {
1260 Image
1261 *clip_mask;
1262
1263 clip_mask=(Image *) NULL;
1264 if (SvPOK(sval))
1265 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1266 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001267 SetImageMask(image,ReadPixelMask,clip_mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001268 break;
1269 }
1270 if (LocaleNCompare(attribute,"colormap",8) == 0)
1271 {
1272 for ( ; image; image=image->next)
1273 {
1274 int
1275 items;
1276
1277 long
1278 i;
1279
1280 if (image->storage_class == DirectClass)
1281 continue;
1282 i=0;
1283 items=sscanf(attribute,"%*[^[][%ld",&i);
1284 (void) items;
1285 if (i > (ssize_t) image->colors)
1286 i%=image->colors;
1287 if ((strchr(SvPV(sval,na),',') == 0) ||
1288 (strchr(SvPV(sval,na),')') != 0))
1289 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1290 image->colormap+i,exception);
1291 else
1292 {
1293 color=image->colormap+i;
1294 pixel.red=color->red;
1295 pixel.green=color->green;
1296 pixel.blue=color->blue;
1297 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1298 pixel.red=geometry_info.rho;
1299 pixel.green=geometry_info.sigma;
1300 pixel.blue=geometry_info.xi;
1301 color->red=ClampToQuantum(pixel.red);
1302 color->green=ClampToQuantum(pixel.green);
1303 color->blue=ClampToQuantum(pixel.blue);
1304 }
1305 }
1306 break;
1307 }
1308 if (LocaleCompare(attribute,"colorspace") == 0)
1309 {
1310 sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1311 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1312 if (sp < 0)
1313 {
1314 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1315 SvPV(sval,na));
1316 break;
1317 }
1318 for ( ; image; image=image->next)
Cristy59262d92016-12-05 15:21:50 -05001319 (void) SetImageColorspace(image,(ColorspaceType) sp,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001320 break;
1321 }
1322 if (LocaleCompare(attribute,"comment") == 0)
1323 {
1324 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001325 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00001326 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04001327 SvPV(sval,na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001328 break;
1329 }
1330 if (LocaleCompare(attribute,"compression") == 0)
1331 {
1332 sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1333 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1334 if (sp < 0)
1335 {
1336 ThrowPerlException(exception,OptionError,
1337 "UnrecognizedImageCompression",SvPV(sval,na));
1338 break;
1339 }
1340 if (info)
1341 info->image_info->compression=(CompressionType) sp;
1342 for ( ; image; image=image->next)
1343 image->compression=(CompressionType) sp;
1344 break;
1345 }
1346 if (info)
1347 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1348 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001349 {
1350 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001351 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001352 }
cristy4a3ce0a2013-08-03 20:06:59 +00001353 break;
1354 }
1355 case 'D':
1356 case 'd':
1357 {
1358 if (LocaleCompare(attribute,"debug") == 0)
1359 {
1360 SetLogEventMask(SvPV(sval,na));
1361 break;
1362 }
1363 if (LocaleCompare(attribute,"delay") == 0)
1364 {
1365 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1366 for ( ; image; image=image->next)
1367 {
1368 image->delay=(size_t) floor(geometry_info.rho+0.5);
1369 if ((flags & SigmaValue) != 0)
1370 image->ticks_per_second=(ssize_t)
1371 floor(geometry_info.sigma+0.5);
1372 }
1373 break;
1374 }
1375 if (LocaleCompare(attribute,"disk-limit") == 0)
1376 {
1377 MagickSizeType
1378 limit;
1379
1380 limit=MagickResourceInfinity;
1381 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1382 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1383 100.0);
1384 (void) SetMagickResourceLimit(DiskResource,limit);
1385 break;
1386 }
1387 if (LocaleCompare(attribute,"density") == 0)
1388 {
1389 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1390 {
1391 ThrowPerlException(exception,OptionError,"MissingGeometry",
1392 SvPV(sval,na));
1393 break;
1394 }
1395 if (info)
1396 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1397 for ( ; image; image=image->next)
1398 {
1399 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1400 image->resolution.x=geometry_info.rho;
1401 image->resolution.y=geometry_info.sigma;
1402 if ((flags & SigmaValue) == 0)
1403 image->resolution.y=image->resolution.x;
1404 }
1405 break;
1406 }
1407 if (LocaleCompare(attribute,"depth") == 0)
1408 {
1409 if (info)
1410 info->image_info->depth=SvIV(sval);
1411 for ( ; image; image=image->next)
1412 (void) SetImageDepth(image,SvIV(sval),exception);
1413 break;
1414 }
1415 if (LocaleCompare(attribute,"dispose") == 0)
1416 {
1417 sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1418 SvPV(sval,na)) : SvIV(sval);
1419 if (sp < 0)
1420 {
1421 ThrowPerlException(exception,OptionError,
1422 "UnrecognizedDisposeMethod",SvPV(sval,na));
1423 break;
1424 }
1425 for ( ; image; image=image->next)
1426 image->dispose=(DisposeType) sp;
1427 break;
1428 }
1429 if (LocaleCompare(attribute,"dither") == 0)
1430 {
1431 if (info)
1432 {
1433 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1434 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1435 if (sp < 0)
1436 {
1437 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1438 SvPV(sval,na));
1439 break;
1440 }
1441 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1442 }
1443 break;
1444 }
1445 if (LocaleCompare(attribute,"display") == 0)
1446 {
1447 display:
1448 if (info)
1449 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1450 break;
1451 }
1452 if (info)
1453 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1454 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001455 {
1456 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001457 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001458 }
cristy4a3ce0a2013-08-03 20:06:59 +00001459 break;
1460 }
1461 case 'E':
1462 case 'e':
1463 {
1464 if (LocaleCompare(attribute,"endian") == 0)
1465 {
1466 sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1467 SvPV(sval,na)) : SvIV(sval);
1468 if (sp < 0)
1469 {
1470 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1471 SvPV(sval,na));
1472 break;
1473 }
1474 if (info)
1475 info->image_info->endian=(EndianType) sp;
1476 for ( ; image; image=image->next)
1477 image->endian=(EndianType) sp;
1478 break;
1479 }
1480 if (LocaleCompare(attribute,"extract") == 0)
1481 {
1482 /*
1483 Set image extract geometry.
1484 */
1485 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1486 break;
1487 }
1488 if (info)
1489 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1490 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001491 {
1492 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001493 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001494 }
cristy4a3ce0a2013-08-03 20:06:59 +00001495 break;
1496 }
1497 case 'F':
1498 case 'f':
1499 {
1500 if (LocaleCompare(attribute,"filename") == 0)
1501 {
1502 if (info)
1503 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001504 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001505 for ( ; image; image=image->next)
1506 (void) CopyMagickString(image->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001507 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001508 break;
1509 }
1510 if (LocaleCompare(attribute,"file") == 0)
1511 {
1512 FILE
1513 *file;
1514
1515 PerlIO
1516 *io_info;
1517
1518 if (info == (struct PackageInfo *) NULL)
1519 break;
1520 io_info=IoIFP(sv_2io(sval));
1521 if (io_info == (PerlIO *) NULL)
1522 {
1523 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1524 PackageName);
1525 break;
1526 }
1527 file=PerlIO_findFILE(io_info);
1528 if (file == (FILE *) NULL)
1529 {
1530 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1531 PackageName);
1532 break;
1533 }
1534 SetImageInfoFile(info->image_info,file);
1535 break;
1536 }
1537 if (LocaleCompare(attribute,"fill") == 0)
1538 {
1539 if (info)
1540 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1541 break;
1542 }
1543 if (LocaleCompare(attribute,"font") == 0)
1544 {
1545 if (info)
1546 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1547 break;
1548 }
1549 if (LocaleCompare(attribute,"foreground") == 0)
1550 break;
1551 if (LocaleCompare(attribute,"fuzz") == 0)
1552 {
1553 if (info)
1554 info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1555 QuantumRange+1.0);
1556 for ( ; image; image=image->next)
1557 image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1558 QuantumRange+1.0);
1559 break;
1560 }
1561 if (info)
1562 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1563 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001564 {
1565 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001566 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001567 }
cristy4a3ce0a2013-08-03 20:06:59 +00001568 break;
1569 }
1570 case 'G':
1571 case 'g':
1572 {
1573 if (LocaleCompare(attribute,"gamma") == 0)
1574 {
1575 for ( ; image; image=image->next)
1576 image->gamma=SvNV(sval);
1577 break;
1578 }
1579 if (LocaleCompare(attribute,"gravity") == 0)
1580 {
1581 sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1582 SvPV(sval,na)) : SvIV(sval);
1583 if (sp < 0)
1584 {
1585 ThrowPerlException(exception,OptionError,
1586 "UnrecognizedGravityType",SvPV(sval,na));
1587 break;
1588 }
1589 if (info)
1590 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1591 for ( ; image; image=image->next)
1592 image->gravity=(GravityType) sp;
1593 break;
1594 }
1595 if (LocaleCompare(attribute,"green-primary") == 0)
1596 {
1597 for ( ; image; image=image->next)
1598 {
1599 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1600 image->chromaticity.green_primary.x=geometry_info.rho;
1601 image->chromaticity.green_primary.y=geometry_info.sigma;
1602 if ((flags & SigmaValue) == 0)
1603 image->chromaticity.green_primary.y=
1604 image->chromaticity.green_primary.x;
1605 }
1606 break;
1607 }
1608 if (info)
1609 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1610 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001611 {
1612 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001613 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001614 }
cristy4a3ce0a2013-08-03 20:06:59 +00001615 break;
1616 }
1617 case 'I':
1618 case 'i':
1619 {
1620 if (LocaleNCompare(attribute,"index",5) == 0)
1621 {
1622 int
1623 items;
1624
1625 long
1626 index;
1627
1628 register Quantum
1629 *q;
1630
1631 CacheView
1632 *image_view;
1633
1634 for ( ; image; image=image->next)
1635 {
1636 if (image->storage_class != PseudoClass)
1637 continue;
1638 x=0;
1639 y=0;
1640 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1641 (void) items;
1642 image_view=AcquireAuthenticCacheView(image,exception);
1643 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1644 if (q != (Quantum *) NULL)
1645 {
1646 items=sscanf(SvPV(sval,na),"%ld",&index);
1647 if ((index >= 0) && (index < (ssize_t) image->colors))
1648 SetPixelIndex(image,index,q);
1649 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1650 }
1651 image_view=DestroyCacheView(image_view);
1652 }
1653 break;
1654 }
1655 if (LocaleCompare(attribute,"iterations") == 0)
1656 {
1657 iterations:
1658 for ( ; image; image=image->next)
1659 image->iterations=SvIV(sval);
1660 break;
1661 }
1662 if (LocaleCompare(attribute,"interlace") == 0)
1663 {
1664 sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1665 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1666 if (sp < 0)
1667 {
1668 ThrowPerlException(exception,OptionError,
1669 "UnrecognizedInterlaceType",SvPV(sval,na));
1670 break;
1671 }
1672 if (info)
1673 info->image_info->interlace=(InterlaceType) sp;
1674 for ( ; image; image=image->next)
1675 image->interlace=(InterlaceType) sp;
1676 break;
1677 }
1678 if (info)
1679 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1680 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001681 {
1682 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001683 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001684 }
cristy4a3ce0a2013-08-03 20:06:59 +00001685 break;
1686 }
1687 case 'L':
1688 case 'l':
1689 {
1690 if (LocaleCompare(attribute,"label") == 0)
1691 {
1692 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001693 (void) SetImageProperty(image,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00001694 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04001695 SvPV(sval,na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001696 break;
1697 }
1698 if (LocaleCompare(attribute,"loop") == 0)
1699 goto iterations;
1700 if (info)
1701 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1702 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001703 {
1704 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001705 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001706 }
cristy4a3ce0a2013-08-03 20:06:59 +00001707 break;
1708 }
1709 case 'M':
1710 case 'm':
1711 {
1712 if (LocaleCompare(attribute,"magick") == 0)
1713 {
1714 if (info)
Cristyb5b1f5d2017-03-31 16:42:35 -04001715 (void) FormatLocaleString(info->image_info->filename,
1716 MagickPathExtent,"%s:",SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001717 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001718 (void) CopyMagickString(image->magick,SvPV(sval,na),
1719 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001720 break;
1721 }
1722 if (LocaleCompare(attribute,"map-limit") == 0)
1723 {
1724 MagickSizeType
1725 limit;
1726
1727 limit=MagickResourceInfinity;
1728 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1729 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1730 100.0);
1731 (void) SetMagickResourceLimit(MapResource,limit);
1732 break;
1733 }
1734 if (LocaleCompare(attribute,"mask") == 0)
1735 {
1736 Image
1737 *mask;
1738
1739 mask=(Image *) NULL;
1740 if (SvPOK(sval))
1741 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1742 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001743 SetImageMask(image,ReadPixelMask,mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001744 break;
1745 }
1746 if (LocaleCompare(attribute,"mattecolor") == 0)
1747 {
1748 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1749 exception);
1750 if (info)
Cristy8645e042016-02-03 16:35:29 -05001751 info->image_info->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001752 for ( ; image; image=image->next)
Cristy8645e042016-02-03 16:35:29 -05001753 image->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001754 break;
1755 }
1756 if (LocaleCompare(attribute,"matte") == 0)
1757 {
1758 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1759 SvPV(sval,na)) : SvIV(sval);
1760 if (sp < 0)
1761 {
1762 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1763 SvPV(sval,na));
1764 break;
1765 }
1766 for ( ; image; image=image->next)
1767 image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1768 break;
1769 }
1770 if (LocaleCompare(attribute,"memory-limit") == 0)
1771 {
1772 MagickSizeType
1773 limit;
1774
1775 limit=MagickResourceInfinity;
1776 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1777 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1778 100.0);
1779 (void) SetMagickResourceLimit(MemoryResource,limit);
1780 break;
1781 }
1782 if (LocaleCompare(attribute,"monochrome") == 0)
1783 {
1784 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1785 SvPV(sval,na)) : SvIV(sval);
1786 if (sp < 0)
1787 {
1788 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1789 SvPV(sval,na));
1790 break;
1791 }
1792 if (info)
1793 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1794 for ( ; image; image=image->next)
1795 (void) SetImageType(image,BilevelType,exception);
1796 break;
1797 }
1798 if (info)
1799 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1800 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001801 {
1802 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001803 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001804 }
cristy4a3ce0a2013-08-03 20:06:59 +00001805 break;
1806 }
1807 case 'O':
1808 case 'o':
1809 {
1810 if (LocaleCompare(attribute,"option") == 0)
1811 {
1812 if (info)
1813 DefineImageOption(info->image_info,SvPV(sval,na));
1814 break;
1815 }
1816 if (LocaleCompare(attribute,"orientation") == 0)
1817 {
1818 sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1819 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1820 if (sp < 0)
1821 {
1822 ThrowPerlException(exception,OptionError,
1823 "UnrecognizedOrientationType",SvPV(sval,na));
1824 break;
1825 }
1826 if (info)
1827 info->image_info->orientation=(OrientationType) sp;
1828 for ( ; image; image=image->next)
1829 image->orientation=(OrientationType) sp;
1830 break;
1831 }
1832 if (info)
1833 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1834 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001835 {
1836 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001837 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001838 }
cristy4a3ce0a2013-08-03 20:06:59 +00001839 break;
1840 }
1841 case 'P':
1842 case 'p':
1843 {
1844 if (LocaleCompare(attribute,"page") == 0)
1845 {
1846 char
1847 *geometry;
1848
1849 geometry=GetPageGeometry(SvPV(sval,na));
1850 if (info)
1851 (void) CloneString(&info->image_info->page,geometry);
1852 for ( ; image; image=image->next)
1853 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1854 geometry=(char *) RelinquishMagickMemory(geometry);
1855 break;
1856 }
1857 if (LocaleNCompare(attribute,"pixel",5) == 0)
1858 {
1859 int
1860 items;
1861
1862 PixelInfo
1863 pixel;
1864
1865 register Quantum
1866 *q;
1867
1868 CacheView
1869 *image_view;
1870
1871 for ( ; image; image=image->next)
1872 {
1873 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1874 break;
1875 x=0;
1876 y=0;
1877 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1878 (void) items;
1879 image_view=AcquireVirtualCacheView(image,exception);
1880 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1881 if (q != (Quantum *) NULL)
1882 {
1883 if ((strchr(SvPV(sval,na),',') == 0) ||
1884 (strchr(SvPV(sval,na),')') != 0))
1885 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1886 &pixel,exception);
1887 else
1888 {
1889 GetPixelInfo(image,&pixel);
1890 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1891 pixel.red=geometry_info.rho;
1892 if ((flags & SigmaValue) != 0)
1893 pixel.green=geometry_info.sigma;
1894 if ((flags & XiValue) != 0)
1895 pixel.blue=geometry_info.xi;
1896 if ((flags & PsiValue) != 0)
1897 pixel.alpha=geometry_info.psi;
1898 if ((flags & ChiValue) != 0)
1899 pixel.black=geometry_info.chi;
1900 }
1901 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1902 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1903 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1904 if (image->colorspace == CMYKColorspace)
1905 SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1906 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1907 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1908 }
1909 image_view=DestroyCacheView(image_view);
1910 }
1911 break;
1912 }
1913 if (LocaleCompare(attribute,"pointsize") == 0)
1914 {
1915 if (info)
1916 {
1917 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1918 info->image_info->pointsize=geometry_info.rho;
1919 }
1920 break;
1921 }
cristy4a3ce0a2013-08-03 20:06:59 +00001922 if (info)
1923 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1924 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001925 {
1926 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001927 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001928 }
cristy4a3ce0a2013-08-03 20:06:59 +00001929 break;
1930 }
1931 case 'Q':
1932 case 'q':
1933 {
1934 if (LocaleCompare(attribute,"quality") == 0)
1935 {
1936 if (info)
1937 info->image_info->quality=SvIV(sval);
1938 for ( ; image; image=image->next)
1939 image->quality=SvIV(sval);
1940 break;
1941 }
1942 if (info)
1943 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1944 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001945 {
1946 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001947 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001948 }
cristy4a3ce0a2013-08-03 20:06:59 +00001949 break;
1950 }
1951 case 'R':
1952 case 'r':
1953 {
cristyc0fe4752015-07-27 18:02:39 +00001954 if (LocaleCompare(attribute,"read-mask") == 0)
1955 {
1956 Image
1957 *mask;
1958
1959 mask=(Image *) NULL;
1960 if (SvPOK(sval))
1961 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1962 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001963 SetImageMask(image,ReadPixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00001964 break;
1965 }
cristy4a3ce0a2013-08-03 20:06:59 +00001966 if (LocaleCompare(attribute,"red-primary") == 0)
1967 {
1968 for ( ; image; image=image->next)
1969 {
1970 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1971 image->chromaticity.red_primary.x=geometry_info.rho;
1972 image->chromaticity.red_primary.y=geometry_info.sigma;
1973 if ((flags & SigmaValue) == 0)
1974 image->chromaticity.red_primary.y=
1975 image->chromaticity.red_primary.x;
1976 }
1977 break;
1978 }
1979 if (LocaleCompare(attribute,"render") == 0)
1980 {
1981 sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1982 SvPV(sval,na)) : SvIV(sval);
1983 if (sp < 0)
1984 {
1985 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1986 SvPV(sval,na));
1987 break;
1988 }
1989 for ( ; image; image=image->next)
1990 image->rendering_intent=(RenderingIntent) sp;
1991 break;
1992 }
1993 if (LocaleCompare(attribute,"repage") == 0)
1994 {
1995 RectangleInfo
1996 geometry;
1997
1998 for ( ; image; image=image->next)
1999 {
2000 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
2001 if ((flags & WidthValue) != 0)
2002 {
2003 if ((flags & HeightValue) == 0)
2004 geometry.height=geometry.width;
2005 image->page.width=geometry.width;
2006 image->page.height=geometry.height;
2007 }
2008 if ((flags & AspectValue) != 0)
2009 {
2010 if ((flags & XValue) != 0)
2011 image->page.x+=geometry.x;
2012 if ((flags & YValue) != 0)
2013 image->page.y+=geometry.y;
2014 }
2015 else
2016 {
2017 if ((flags & XValue) != 0)
2018 {
2019 image->page.x=geometry.x;
2020 if (((flags & WidthValue) != 0) && (geometry.x > 0))
2021 image->page.width=image->columns+geometry.x;
2022 }
2023 if ((flags & YValue) != 0)
2024 {
2025 image->page.y=geometry.y;
2026 if (((flags & HeightValue) != 0) && (geometry.y > 0))
2027 image->page.height=image->rows+geometry.y;
2028 }
2029 }
2030 }
2031 break;
2032 }
2033 if (info)
2034 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2035 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002036 {
2037 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002038 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002039 }
cristy4a3ce0a2013-08-03 20:06:59 +00002040 break;
2041 }
2042 case 'S':
2043 case 's':
2044 {
2045 if (LocaleCompare(attribute,"sampling-factor") == 0)
2046 {
2047 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2048 {
2049 ThrowPerlException(exception,OptionError,"MissingGeometry",
2050 SvPV(sval,na));
2051 break;
2052 }
2053 if (info)
2054 (void) CloneString(&info->image_info->sampling_factor,
2055 SvPV(sval,na));
2056 break;
2057 }
2058 if (LocaleCompare(attribute,"scene") == 0)
2059 {
2060 for ( ; image; image=image->next)
2061 image->scene=SvIV(sval);
2062 break;
2063 }
2064 if (LocaleCompare(attribute,"server") == 0)
2065 goto display;
2066 if (LocaleCompare(attribute,"size") == 0)
2067 {
2068 if (info)
2069 {
2070 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2071 {
2072 ThrowPerlException(exception,OptionError,"MissingGeometry",
2073 SvPV(sval,na));
2074 break;
2075 }
2076 (void) CloneString(&info->image_info->size,SvPV(sval,na));
2077 }
2078 break;
2079 }
2080 if (LocaleCompare(attribute,"stroke") == 0)
2081 {
2082 if (info)
2083 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2084 break;
2085 }
2086 if (info)
2087 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2088 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002089 {
2090 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002091 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002092 }
cristy4a3ce0a2013-08-03 20:06:59 +00002093 break;
2094 }
2095 case 'T':
2096 case 't':
2097 {
2098 if (LocaleCompare(attribute,"texture") == 0)
2099 {
2100 if (info)
2101 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2102 break;
2103 }
2104 if (LocaleCompare(attribute,"thread-limit") == 0)
2105 {
2106 MagickSizeType
2107 limit;
2108
2109 limit=MagickResourceInfinity;
2110 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2111 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2112 100.0);
2113 (void) SetMagickResourceLimit(ThreadResource,limit);
2114 break;
2115 }
2116 if (LocaleCompare(attribute,"tile-offset") == 0)
2117 {
2118 char
2119 *geometry;
2120
2121 geometry=GetPageGeometry(SvPV(sval,na));
2122 if (info)
2123 (void) CloneString(&info->image_info->page,geometry);
2124 for ( ; image; image=image->next)
2125 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2126 exception);
2127 geometry=(char *) RelinquishMagickMemory(geometry);
2128 break;
2129 }
2130 if (LocaleCompare(attribute,"time-limit") == 0)
2131 {
2132 MagickSizeType
2133 limit;
2134
2135 limit=MagickResourceInfinity;
2136 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2137 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2138 100.0);
2139 (void) SetMagickResourceLimit(TimeResource,limit);
2140 break;
2141 }
2142 if (LocaleCompare(attribute,"transparent-color") == 0)
2143 {
2144 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2145 exception);
2146 if (info)
2147 info->image_info->transparent_color=target_color;
2148 for ( ; image; image=image->next)
2149 image->transparent_color=target_color;
2150 break;
2151 }
2152 if (LocaleCompare(attribute,"type") == 0)
2153 {
2154 sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2155 SvPV(sval,na)) : SvIV(sval);
2156 if (sp < 0)
2157 {
2158 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2159 SvPV(sval,na));
2160 break;
2161 }
2162 if (info)
2163 info->image_info->type=(ImageType) sp;
2164 for ( ; image; image=image->next)
2165 SetImageType(image,(ImageType) sp,exception);
2166 break;
2167 }
2168 if (info)
2169 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2170 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002171 {
2172 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002173 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002174 }
cristy4a3ce0a2013-08-03 20:06:59 +00002175 break;
2176 }
2177 case 'U':
2178 case 'u':
2179 {
2180 if (LocaleCompare(attribute,"units") == 0)
2181 {
2182 sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2183 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2184 if (sp < 0)
2185 {
2186 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2187 SvPV(sval,na));
2188 break;
2189 }
2190 if (info)
2191 info->image_info->units=(ResolutionType) sp;
2192 for ( ; image; image=image->next)
2193 {
2194 ResolutionType
2195 units;
2196
2197 units=(ResolutionType) sp;
2198 if (image->units != units)
2199 switch (image->units)
2200 {
2201 case UndefinedResolution:
2202 case PixelsPerInchResolution:
2203 {
2204 if (units == PixelsPerCentimeterResolution)
2205 {
2206 image->resolution.x*=2.54;
2207 image->resolution.y*=2.54;
2208 }
2209 break;
2210 }
2211 case PixelsPerCentimeterResolution:
2212 {
2213 if (units == PixelsPerInchResolution)
2214 {
2215 image->resolution.x/=2.54;
2216 image->resolution.y/=2.54;
2217 }
2218 break;
2219 }
2220 }
2221 image->units=units;
2222 }
2223 break;
2224 }
2225 if (info)
2226 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2227 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002228 {
2229 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002230 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002231 }
cristy4a3ce0a2013-08-03 20:06:59 +00002232 break;
2233 }
2234 case 'V':
2235 case 'v':
2236 {
2237 if (LocaleCompare(attribute,"verbose") == 0)
2238 {
2239 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2240 SvPV(sval,na)) : SvIV(sval);
2241 if (sp < 0)
2242 {
2243 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2244 SvPV(sval,na));
2245 break;
2246 }
2247 if (info)
2248 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2249 break;
2250 }
cristy4a3ce0a2013-08-03 20:06:59 +00002251 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2252 {
2253 sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2254 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2255 if (sp < 0)
2256 {
2257 ThrowPerlException(exception,OptionError,
2258 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2259 break;
2260 }
2261 for ( ; image; image=image->next)
2262 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2263 break;
2264 }
2265 if (info)
2266 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2267 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002268 {
2269 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002270 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002271 }
cristy4a3ce0a2013-08-03 20:06:59 +00002272 break;
2273 }
2274 case 'W':
2275 case 'w':
2276 {
2277 if (LocaleCompare(attribute,"white-point") == 0)
2278 {
2279 for ( ; image; image=image->next)
2280 {
2281 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2282 image->chromaticity.white_point.x=geometry_info.rho;
2283 image->chromaticity.white_point.y=geometry_info.sigma;
2284 if ((flags & SigmaValue) == 0)
2285 image->chromaticity.white_point.y=
2286 image->chromaticity.white_point.x;
2287 }
2288 break;
2289 }
cristyc0fe4752015-07-27 18:02:39 +00002290 if (LocaleCompare(attribute,"write-mask") == 0)
2291 {
2292 Image
2293 *mask;
2294
2295 mask=(Image *) NULL;
2296 if (SvPOK(sval))
2297 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
2298 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00002299 SetImageMask(image,WritePixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00002300 break;
2301 }
cristy4a3ce0a2013-08-03 20:06:59 +00002302 if (info)
2303 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2304 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002305 {
2306 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002307 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002308 }
cristy4a3ce0a2013-08-03 20:06:59 +00002309 break;
2310 }
2311 default:
2312 {
2313 if (info)
2314 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2315 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002316 {
2317 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002318 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002319 }
cristy4a3ce0a2013-08-03 20:06:59 +00002320 break;
2321 }
2322 }
2323}
2324
2325/*
2326%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2327% %
2328% %
2329% %
2330% S e t u p L i s t %
2331% %
2332% %
2333% %
2334%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2335%
2336% Method SetupList returns the list of all the images linked by their
2337% image->next and image->previous link lists for use with ImageMagick. If
2338% info is non-NULL, an info structure is returned in *info. If
2339% reference_vector is non-NULL,an array of SV* are returned in
2340% *reference_vector. Reference_vector is used when the images are going to be
2341% replaced with new Image*'s.
2342%
2343% The format of the SetupList routine is:
2344%
2345% Image *SetupList(SV *reference,struct PackageInfo **info,
2346% SV ***reference_vector,ExceptionInfo *exception)
2347%
2348% A description of each parameter follows:
2349%
2350% o list: a list of strings.
2351%
2352% o string: a character string.
2353%
2354% o exception: Return any errors or warnings in this structure.
2355%
2356*/
2357static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2358 SV ***reference_vector,ExceptionInfo *exception)
2359{
2360 Image
2361 *image;
2362
2363 ssize_t
2364 current,
2365 last;
2366
2367 if (reference_vector)
2368 *reference_vector=NULL;
2369 if (info)
2370 *info=NULL;
2371 current=0;
2372 last=0;
2373 image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2374 if (info && (SvTYPE(reference) == SVt_PVAV))
2375 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2376 exception);
2377 return(image);
2378}
2379
2380/*
2381%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2382% %
2383% %
2384% %
2385% s t r E Q c a s e %
2386% %
2387% %
2388% %
2389%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2390%
2391% strEQcase() compares two strings and returns 0 if they are the
2392% same or if the second string runs out first. The comparison is case
2393% insensitive.
2394%
2395% The format of the strEQcase routine is:
2396%
2397% ssize_t strEQcase(const char *p,const char *q)
2398%
2399% A description of each parameter follows:
2400%
2401% o p: a character string.
2402%
2403% o q: a character string.
2404%
2405%
2406*/
2407static ssize_t strEQcase(const char *p,const char *q)
2408{
2409 char
2410 c;
2411
2412 register ssize_t
2413 i;
2414
2415 for (i=0 ; (c=(*q)) != 0; i++)
2416 {
2417 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2418 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2419 return(0);
2420 p++;
2421 q++;
2422 }
2423 return(((*q == 0) && (*p == 0)) ? i : 0);
2424}
2425
2426/*
2427%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2428% %
2429% %
2430% %
2431% I m a g e : : M a g i c k %
2432% %
2433% %
2434% %
2435%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2436%
2437%
2438*/
2439MODULE = Image::Magick PACKAGE = Image::Magick
2440
2441PROTOTYPES: ENABLE
2442
2443BOOT:
2444 MagickCoreGenesis("PerlMagick",MagickFalse);
2445 SetWarningHandler(NULL);
2446 SetErrorHandler(NULL);
2447 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2448 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2449
2450void
2451UNLOAD()
2452 PPCODE:
2453 {
2454 if (magick_registry != (SplayTreeInfo *) NULL)
2455 magick_registry=DestroySplayTree(magick_registry);
2456 MagickCoreTerminus();
2457 }
2458
2459double
2460constant(name,argument)
2461 char *name
2462 ssize_t argument
2463
2464#
2465###############################################################################
2466# #
2467# #
2468# #
2469# A n i m a t e #
2470# #
2471# #
2472# #
2473###############################################################################
2474#
2475#
2476void
2477Animate(ref,...)
2478 Image::Magick ref=NO_INIT
2479 ALIAS:
2480 AnimateImage = 1
2481 animate = 2
2482 animateimage = 3
2483 PPCODE:
2484 {
2485 ExceptionInfo
2486 *exception;
2487
2488 Image
2489 *image;
2490
2491 register ssize_t
2492 i;
2493
2494 struct PackageInfo
2495 *info,
2496 *package_info;
2497
2498 SV
2499 *perl_exception,
2500 *reference;
2501
2502 PERL_UNUSED_VAR(ref);
2503 PERL_UNUSED_VAR(ix);
2504 exception=AcquireExceptionInfo();
2505 perl_exception=newSVpv("",0);
2506 package_info=(struct PackageInfo *) NULL;
2507 if (sv_isobject(ST(0)) == 0)
2508 {
2509 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2510 PackageName);
2511 goto PerlException;
2512 }
2513 reference=SvRV(ST(0));
2514 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2515 if (image == (Image *) NULL)
2516 {
2517 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2518 PackageName);
2519 goto PerlException;
2520 }
2521 package_info=ClonePackageInfo(info,exception);
2522 if (items == 2)
2523 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2524 else
2525 if (items > 2)
2526 for (i=2; i < items; i+=2)
2527 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2528 exception);
2529 (void) AnimateImages(package_info->image_info,image,exception);
2530 (void) CatchImageException(image);
2531
2532 PerlException:
2533 if (package_info != (struct PackageInfo *) NULL)
2534 DestroyPackageInfo(package_info);
2535 InheritPerlException(exception,perl_exception);
2536 exception=DestroyExceptionInfo(exception);
2537 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2538 SvPOK_on(perl_exception);
2539 ST(0)=sv_2mortal(perl_exception);
2540 XSRETURN(1);
2541 }
2542
2543#
2544###############################################################################
2545# #
2546# #
2547# #
2548# A p p e n d #
2549# #
2550# #
2551# #
2552###############################################################################
2553#
2554#
2555void
2556Append(ref,...)
2557 Image::Magick ref=NO_INIT
2558 ALIAS:
2559 AppendImage = 1
2560 append = 2
2561 appendimage = 3
2562 PPCODE:
2563 {
2564 AV
2565 *av;
2566
2567 char
2568 *attribute;
2569
2570 ExceptionInfo
2571 *exception;
2572
2573 HV
2574 *hv;
2575
2576 Image
2577 *image;
2578
2579 register ssize_t
2580 i;
2581
2582 ssize_t
2583 stack;
2584
2585 struct PackageInfo
2586 *info;
2587
2588 SV
2589 *av_reference,
2590 *perl_exception,
2591 *reference,
2592 *rv,
2593 *sv;
2594
2595 PERL_UNUSED_VAR(ref);
2596 PERL_UNUSED_VAR(ix);
2597 exception=AcquireExceptionInfo();
2598 perl_exception=newSVpv("",0);
2599 sv=NULL;
2600 attribute=NULL;
2601 av=NULL;
2602 if (sv_isobject(ST(0)) == 0)
2603 {
2604 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2605 PackageName);
2606 goto PerlException;
2607 }
2608 reference=SvRV(ST(0));
2609 hv=SvSTASH(reference);
2610 av=newAV();
2611 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2612 SvREFCNT_dec(av);
2613 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2614 if (image == (Image *) NULL)
2615 {
2616 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2617 PackageName);
2618 goto PerlException;
2619 }
2620 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2621 /*
2622 Get options.
2623 */
2624 stack=MagickTrue;
2625 for (i=2; i < items; i+=2)
2626 {
2627 attribute=(char *) SvPV(ST(i-1),na);
2628 switch (*attribute)
2629 {
2630 case 'S':
2631 case 's':
2632 {
2633 if (LocaleCompare(attribute,"stack") == 0)
2634 {
2635 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2636 SvPV(ST(i),na));
2637 if (stack < 0)
2638 {
2639 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2640 SvPV(ST(i),na));
2641 return;
2642 }
2643 break;
2644 }
2645 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2646 attribute);
2647 break;
2648 }
2649 default:
2650 {
2651 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2652 attribute);
2653 break;
2654 }
2655 }
2656 }
2657 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2658 if (image == (Image *) NULL)
2659 goto PerlException;
2660 for ( ; image; image=image->next)
2661 {
2662 AddImageToRegistry(sv,image);
2663 rv=newRV(sv);
2664 av_push(av,sv_bless(rv,hv));
2665 SvREFCNT_dec(sv);
2666 }
2667 exception=DestroyExceptionInfo(exception);
2668 ST(0)=av_reference;
2669 SvREFCNT_dec(perl_exception);
2670 XSRETURN(1);
2671
2672 PerlException:
2673 InheritPerlException(exception,perl_exception);
2674 exception=DestroyExceptionInfo(exception);
2675 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2676 SvPOK_on(perl_exception);
2677 ST(0)=sv_2mortal(perl_exception);
2678 XSRETURN(1);
2679 }
2680
2681#
2682###############################################################################
2683# #
2684# #
2685# #
2686# A v e r a g e #
2687# #
2688# #
2689# #
2690###############################################################################
2691#
2692#
2693void
2694Average(ref)
2695 Image::Magick ref=NO_INIT
2696 ALIAS:
2697 AverageImage = 1
2698 average = 2
2699 averageimage = 3
2700 PPCODE:
2701 {
2702 AV
2703 *av;
2704
2705 char
2706 *p;
2707
2708 ExceptionInfo
2709 *exception;
2710
2711 HV
2712 *hv;
2713
2714 Image
2715 *image;
2716
2717 struct PackageInfo
2718 *info;
2719
2720 SV
2721 *perl_exception,
2722 *reference,
2723 *rv,
2724 *sv;
2725
2726 PERL_UNUSED_VAR(ref);
2727 PERL_UNUSED_VAR(ix);
2728 exception=AcquireExceptionInfo();
2729 perl_exception=newSVpv("",0);
2730 sv=NULL;
2731 if (sv_isobject(ST(0)) == 0)
2732 {
2733 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2734 PackageName);
2735 goto PerlException;
2736 }
2737 reference=SvRV(ST(0));
2738 hv=SvSTASH(reference);
2739 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2740 if (image == (Image *) NULL)
2741 {
2742 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2743 PackageName);
2744 goto PerlException;
2745 }
2746 image=EvaluateImages(image,MeanEvaluateOperator,exception);
2747 if (image == (Image *) NULL)
2748 goto PerlException;
2749 /*
2750 Create blessed Perl array for the returned image.
2751 */
2752 av=newAV();
2753 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2754 SvREFCNT_dec(av);
2755 AddImageToRegistry(sv,image);
2756 rv=newRV(sv);
2757 av_push(av,sv_bless(rv,hv));
2758 SvREFCNT_dec(sv);
2759 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00002760 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
2761 "average-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00002762 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2763 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00002764 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002765 SetImageInfo(info->image_info,0,exception);
2766 exception=DestroyExceptionInfo(exception);
2767 SvREFCNT_dec(perl_exception);
2768 XSRETURN(1);
2769
2770 PerlException:
2771 InheritPerlException(exception,perl_exception);
2772 exception=DestroyExceptionInfo(exception);
2773 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2774 SvPOK_on(perl_exception);
2775 ST(0)=sv_2mortal(perl_exception);
2776 XSRETURN(1);
2777 }
2778
2779#
2780###############################################################################
2781# #
2782# #
2783# #
2784# B l o b T o I m a g e #
2785# #
2786# #
2787# #
2788###############################################################################
2789#
2790#
2791void
2792BlobToImage(ref,...)
2793 Image::Magick ref=NO_INIT
2794 ALIAS:
2795 BlobToImage = 1
2796 blobtoimage = 2
2797 blobto = 3
2798 PPCODE:
2799 {
2800 AV
2801 *av;
2802
2803 char
2804 **keep,
2805 **list;
2806
2807 ExceptionInfo
2808 *exception;
2809
2810 HV
2811 *hv;
2812
2813 Image
2814 *image;
2815
2816 register char
2817 **p;
2818
2819 register ssize_t
2820 i;
2821
2822 ssize_t
2823 ac,
2824 n,
2825 number_images;
2826
2827 STRLEN
2828 *length;
2829
2830 struct PackageInfo
2831 *info;
2832
2833 SV
2834 *perl_exception,
2835 *reference,
2836 *rv,
2837 *sv;
2838
2839 PERL_UNUSED_VAR(ref);
2840 PERL_UNUSED_VAR(ix);
2841 exception=AcquireExceptionInfo();
2842 perl_exception=newSVpv("",0);
2843 sv=NULL;
2844 number_images=0;
2845 ac=(items < 2) ? 1 : items-1;
2846 length=(STRLEN *) NULL;
2847 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2848 if (list == (char **) NULL)
2849 {
2850 ThrowPerlException(exception,ResourceLimitError,
2851 "MemoryAllocationFailed",PackageName);
2852 goto PerlException;
2853 }
2854 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2855 if (length == (STRLEN *) NULL)
2856 {
2857 ThrowPerlException(exception,ResourceLimitError,
2858 "MemoryAllocationFailed",PackageName);
2859 goto PerlException;
2860 }
2861 if (sv_isobject(ST(0)) == 0)
2862 {
2863 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2864 PackageName);
2865 goto PerlException;
2866 }
2867 reference=SvRV(ST(0));
2868 hv=SvSTASH(reference);
2869 if (SvTYPE(reference) != SVt_PVAV)
2870 {
2871 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2872 PackageName);
2873 goto PerlException;
2874 }
2875 av=(AV *) reference;
2876 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2877 exception);
2878 n=1;
2879 if (items <= 1)
2880 {
2881 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2882 goto PerlException;
2883 }
2884 for (n=0, i=0; i < ac; i++)
2885 {
2886 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2887 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2888 {
2889 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2890 continue;
2891 }
2892 n++;
2893 }
2894 list[n]=(char *) NULL;
2895 keep=list;
2896 for (i=number_images=0; i < n; i++)
2897 {
2898 image=BlobToImage(info->image_info,list[i],length[i],exception);
2899 if (image == (Image *) NULL)
2900 break;
2901 for ( ; image; image=image->next)
2902 {
2903 AddImageToRegistry(sv,image);
2904 rv=newRV(sv);
2905 av_push(av,sv_bless(rv,hv));
2906 SvREFCNT_dec(sv);
2907 number_images++;
2908 }
2909 }
2910 /*
2911 Free resources.
2912 */
2913 for (i=0; i < n; i++)
2914 if (list[i] != (char *) NULL)
2915 for (p=keep; list[i] != *p++; )
2916 if (*p == (char *) NULL)
2917 {
2918 list[i]=(char *) RelinquishMagickMemory(list[i]);
2919 break;
2920 }
2921
2922 PerlException:
2923 if (list)
2924 list=(char **) RelinquishMagickMemory(list);
2925 if (length)
2926 length=(STRLEN *) RelinquishMagickMemory(length);
2927 InheritPerlException(exception,perl_exception);
2928 exception=DestroyExceptionInfo(exception);
2929 sv_setiv(perl_exception,(IV) number_images);
2930 SvPOK_on(perl_exception);
2931 ST(0)=sv_2mortal(perl_exception);
2932 XSRETURN(1);
2933 }
2934
2935#
2936###############################################################################
2937# #
2938# #
2939# #
2940# C h a n n e l F x #
2941# #
2942# #
2943# #
2944###############################################################################
2945#
2946#
2947void
2948ChannelFx(ref,...)
2949 Image::Magick ref=NO_INIT
2950 ALIAS:
2951 ChannelFxImage = 1
2952 channelfx = 2
2953 channelfximage = 3
2954 PPCODE:
2955 {
2956 AV
2957 *av;
2958
2959 char
2960 *attribute,
cristy151b66d2015-04-15 10:50:31 +00002961 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00002962
2963 ChannelType
2964 channel,
2965 channel_mask;
2966
2967 ExceptionInfo
2968 *exception;
2969
2970 HV
2971 *hv;
2972
2973 Image
2974 *image;
2975
2976 register ssize_t
2977 i;
2978
2979 struct PackageInfo
2980 *info;
2981
2982 SV
2983 *av_reference,
2984 *perl_exception,
2985 *reference,
2986 *rv,
2987 *sv;
2988
2989 PERL_UNUSED_VAR(ref);
2990 PERL_UNUSED_VAR(ix);
2991 exception=AcquireExceptionInfo();
2992 perl_exception=newSVpv("",0);
2993 sv=NULL;
2994 attribute=NULL;
2995 av=NULL;
2996 if (sv_isobject(ST(0)) == 0)
2997 {
2998 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2999 PackageName);
3000 goto PerlException;
3001 }
3002 reference=SvRV(ST(0));
3003 hv=SvSTASH(reference);
3004 av=newAV();
3005 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3006 SvREFCNT_dec(av);
3007 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3008 if (image == (Image *) NULL)
3009 {
3010 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3011 PackageName);
3012 goto PerlException;
3013 }
3014 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3015 /*
3016 Get options.
3017 */
3018 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00003019 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003020 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00003021 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003022 else
3023 for (i=2; i < items; i+=2)
3024 {
3025 attribute=(char *) SvPV(ST(i-1),na);
3026 switch (*attribute)
3027 {
3028 case 'C':
3029 case 'c':
3030 {
3031 if (LocaleCompare(attribute,"channel") == 0)
3032 {
3033 ssize_t
3034 option;
3035
3036 option=ParseChannelOption(SvPV(ST(i),na));
3037 if (option < 0)
3038 {
3039 ThrowPerlException(exception,OptionError,
3040 "UnrecognizedType",SvPV(ST(i),na));
3041 return;
3042 }
3043 channel=(ChannelType) option;
3044 break;
3045 }
3046 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3047 attribute);
3048 break;
3049 }
3050 case 'E':
3051 case 'e':
3052 {
3053 if (LocaleCompare(attribute,"expression") == 0)
3054 {
3055 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00003056 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003057 break;
3058 }
3059 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3060 attribute);
3061 break;
3062 }
3063 default:
3064 {
3065 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3066 attribute);
3067 break;
3068 }
3069 }
3070 }
3071 channel_mask=SetImageChannelMask(image,channel);
3072 image=ChannelFxImage(image,expression,exception);
3073 if (image != (Image *) NULL)
3074 (void) SetImageChannelMask(image,channel_mask);
3075 if (image == (Image *) NULL)
3076 goto PerlException;
3077 for ( ; image; image=image->next)
3078 {
3079 AddImageToRegistry(sv,image);
3080 rv=newRV(sv);
3081 av_push(av,sv_bless(rv,hv));
3082 SvREFCNT_dec(sv);
3083 }
3084 exception=DestroyExceptionInfo(exception);
3085 ST(0)=av_reference;
3086 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3087 XSRETURN(1);
3088
3089 PerlException:
3090 InheritPerlException(exception,perl_exception);
3091 exception=DestroyExceptionInfo(exception);
3092 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3093 SvPOK_on(perl_exception);
3094 ST(0)=sv_2mortal(perl_exception);
3095 XSRETURN(1);
3096 }
3097
3098#
3099###############################################################################
3100# #
3101# #
3102# #
3103# C l o n e #
3104# #
3105# #
3106# #
3107###############################################################################
3108#
3109#
3110void
3111Clone(ref)
3112 Image::Magick ref=NO_INIT
3113 ALIAS:
3114 CopyImage = 1
3115 copy = 2
3116 copyimage = 3
3117 CloneImage = 4
3118 clone = 5
3119 cloneimage = 6
3120 Clone = 7
3121 PPCODE:
3122 {
3123 AV
3124 *av;
3125
3126 ExceptionInfo
3127 *exception;
3128
3129 HV
3130 *hv;
3131
3132 Image
3133 *clone,
3134 *image;
3135
3136 struct PackageInfo
3137 *info;
3138
3139 SV
3140 *perl_exception,
3141 *reference,
3142 *rv,
3143 *sv;
3144
3145 PERL_UNUSED_VAR(ref);
3146 PERL_UNUSED_VAR(ix);
3147 exception=AcquireExceptionInfo();
3148 perl_exception=newSVpv("",0);
3149 sv=NULL;
3150 if (sv_isobject(ST(0)) == 0)
3151 {
3152 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3153 PackageName);
3154 goto PerlException;
3155 }
3156 reference=SvRV(ST(0));
3157 hv=SvSTASH(reference);
3158 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3159 if (image == (Image *) NULL)
3160 {
3161 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3162 PackageName);
3163 goto PerlException;
3164 }
3165 /*
3166 Create blessed Perl array for the returned image.
3167 */
3168 av=newAV();
3169 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3170 SvREFCNT_dec(av);
3171 for ( ; image; image=image->next)
3172 {
3173 clone=CloneImage(image,0,0,MagickTrue,exception);
3174 if (clone == (Image *) NULL)
3175 break;
3176 AddImageToRegistry(sv,clone);
3177 rv=newRV(sv);
3178 av_push(av,sv_bless(rv,hv));
3179 SvREFCNT_dec(sv);
3180 }
3181 exception=DestroyExceptionInfo(exception);
3182 SvREFCNT_dec(perl_exception);
3183 XSRETURN(1);
3184
3185 PerlException:
3186 InheritPerlException(exception,perl_exception);
3187 exception=DestroyExceptionInfo(exception);
3188 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3189 SvPOK_on(perl_exception);
3190 ST(0)=sv_2mortal(perl_exception);
3191 XSRETURN(1);
3192 }
3193
3194#
3195###############################################################################
3196# #
3197# #
3198# #
3199# C L O N E #
3200# #
3201# #
3202# #
3203###############################################################################
3204#
3205#
3206void
3207CLONE(ref,...)
3208 SV *ref;
3209 CODE:
3210 {
3211 PERL_UNUSED_VAR(ref);
3212 if (magick_registry != (SplayTreeInfo *) NULL)
3213 {
3214 register Image
3215 *p;
3216
3217 ResetSplayTreeIterator(magick_registry);
3218 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3219 while (p != (Image *) NULL)
3220 {
3221 ReferenceImage(p);
3222 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3223 }
3224 }
3225 }
3226
3227#
3228###############################################################################
3229# #
3230# #
3231# #
3232# C o a l e s c e #
3233# #
3234# #
3235# #
3236###############################################################################
3237#
3238#
3239void
3240Coalesce(ref)
3241 Image::Magick ref=NO_INIT
3242 ALIAS:
3243 CoalesceImage = 1
3244 coalesce = 2
3245 coalesceimage = 3
3246 PPCODE:
3247 {
3248 AV
3249 *av;
3250
3251 ExceptionInfo
3252 *exception;
3253
3254 HV
3255 *hv;
3256
3257 Image
3258 *image;
3259
3260 struct PackageInfo
3261 *info;
3262
3263 SV
3264 *av_reference,
3265 *perl_exception,
3266 *reference,
3267 *rv,
3268 *sv;
3269
3270 PERL_UNUSED_VAR(ref);
3271 PERL_UNUSED_VAR(ix);
3272 exception=AcquireExceptionInfo();
3273 perl_exception=newSVpv("",0);
3274 sv=NULL;
3275 if (sv_isobject(ST(0)) == 0)
3276 {
3277 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3278 PackageName);
3279 goto PerlException;
3280 }
3281 reference=SvRV(ST(0));
3282 hv=SvSTASH(reference);
3283 av=newAV();
3284 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3285 SvREFCNT_dec(av);
3286 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3287 if (image == (Image *) NULL)
3288 {
3289 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3290 PackageName);
3291 goto PerlException;
3292 }
3293 image=CoalesceImages(image,exception);
3294 if (image == (Image *) NULL)
3295 goto PerlException;
3296 for ( ; image; image=image->next)
3297 {
3298 AddImageToRegistry(sv,image);
3299 rv=newRV(sv);
3300 av_push(av,sv_bless(rv,hv));
3301 SvREFCNT_dec(sv);
3302 }
3303 exception=DestroyExceptionInfo(exception);
3304 ST(0)=av_reference;
3305 SvREFCNT_dec(perl_exception);
3306 XSRETURN(1);
3307
3308 PerlException:
3309 InheritPerlException(exception,perl_exception);
3310 exception=DestroyExceptionInfo(exception);
3311 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3312 SvPOK_on(perl_exception);
3313 ST(0)=sv_2mortal(perl_exception);
3314 XSRETURN(1);
3315 }
3316
3317#
3318###############################################################################
3319# #
3320# #
3321# #
3322# C o m p a r e #
3323# #
3324# #
3325# #
3326###############################################################################
3327#
3328#
3329void
3330Compare(ref,...)
3331 Image::Magick ref=NO_INIT
3332 ALIAS:
3333 CompareImages = 1
3334 compare = 2
3335 compareimage = 3
3336 PPCODE:
3337 {
3338 AV
3339 *av;
3340
3341 char
3342 *attribute;
3343
3344 double
3345 distortion;
3346
3347 ExceptionInfo
3348 *exception;
3349
3350 HV
3351 *hv;
3352
3353 Image
3354 *difference_image,
3355 *image,
3356 *reconstruct_image;
3357
3358 MetricType
3359 metric;
3360
3361 register ssize_t
3362 i;
3363
3364 ssize_t
3365 option;
3366
3367 struct PackageInfo
3368 *info;
3369
3370 SV
3371 *av_reference,
3372 *perl_exception,
3373 *reference,
3374 *rv,
3375 *sv;
3376
3377 PERL_UNUSED_VAR(ref);
3378 PERL_UNUSED_VAR(ix);
3379 exception=AcquireExceptionInfo();
3380 perl_exception=newSVpv("",0);
3381 sv=NULL;
3382 av=NULL;
3383 attribute=NULL;
3384 if (sv_isobject(ST(0)) == 0)
3385 {
3386 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3387 PackageName);
3388 goto PerlException;
3389 }
3390 reference=SvRV(ST(0));
3391 hv=SvSTASH(reference);
3392 av=newAV();
3393 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3394 SvREFCNT_dec(av);
3395 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3396 if (image == (Image *) NULL)
3397 {
3398 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3399 PackageName);
3400 goto PerlException;
3401 }
3402 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3403 /*
3404 Get attribute.
3405 */
3406 reconstruct_image=image;
3407 metric=RootMeanSquaredErrorMetric;
3408 for (i=2; i < items; i+=2)
3409 {
3410 attribute=(char *) SvPV(ST(i-1),na);
3411 switch (*attribute)
3412 {
3413 case 'C':
3414 case 'c':
3415 {
3416 if (LocaleCompare(attribute,"channel") == 0)
3417 {
3418 ssize_t
3419 option;
3420
3421 option=ParseChannelOption(SvPV(ST(i),na));
3422 if (option < 0)
3423 {
3424 ThrowPerlException(exception,OptionError,
3425 "UnrecognizedType",SvPV(ST(i),na));
3426 return;
3427 }
cristybcd59342015-06-07 14:07:19 +00003428 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00003429 break;
3430 }
3431 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3432 attribute);
3433 break;
3434 }
3435 case 'F':
3436 case 'f':
3437 {
3438 if (LocaleCompare(attribute,"fuzz") == 0)
3439 {
3440 image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3441 break;
3442 }
3443 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3444 attribute);
3445 break;
3446 }
3447 case 'I':
3448 case 'i':
3449 {
3450 if (LocaleCompare(attribute,"image") == 0)
3451 {
3452 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3453 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3454 break;
3455 }
3456 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3457 attribute);
3458 break;
3459 }
3460 case 'M':
3461 case 'm':
3462 {
3463 if (LocaleCompare(attribute,"metric") == 0)
3464 {
3465 option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3466 SvPV(ST(i),na));
3467 if (option < 0)
3468 {
3469 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3470 SvPV(ST(i),na));
3471 break;
3472 }
3473 metric=(MetricType) option;
3474 break;
3475 }
3476 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3477 attribute);
3478 break;
3479 }
3480 default:
3481 {
3482 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3483 attribute);
3484 break;
3485 }
3486 }
3487 }
3488 difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3489 exception);
3490 if (difference_image != (Image *) NULL)
3491 {
3492 difference_image->error.mean_error_per_pixel=distortion;
3493 AddImageToRegistry(sv,difference_image);
3494 rv=newRV(sv);
3495 av_push(av,sv_bless(rv,hv));
3496 SvREFCNT_dec(sv);
3497 }
3498 exception=DestroyExceptionInfo(exception);
3499 ST(0)=av_reference;
3500 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3501 XSRETURN(1);
3502
3503 PerlException:
3504 InheritPerlException(exception,perl_exception);
3505 exception=DestroyExceptionInfo(exception);
3506 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3507 SvPOK_on(perl_exception);
3508 ST(0)=sv_2mortal(perl_exception);
3509 XSRETURN(1);
3510 }
3511
3512#
3513###############################################################################
3514# #
3515# #
3516# #
cristy15655332013-10-06 00:27:33 +00003517# C o m p l e x I m a g e s #
3518# #
3519# #
3520# #
3521###############################################################################
3522#
3523#
3524void
3525ComplexImages(ref)
3526 Image::Magick ref=NO_INIT
3527 ALIAS:
3528 ComplexImages = 1
3529 compleximages = 2
3530 PPCODE:
3531 {
3532 AV
3533 *av;
3534
3535 char
3536 *attribute,
3537 *p;
3538
cristyfa21e9e2013-10-07 10:37:38 +00003539 ComplexOperator
3540 op;
3541
cristy15655332013-10-06 00:27:33 +00003542 ExceptionInfo
3543 *exception;
3544
3545 HV
3546 *hv;
3547
3548 Image
3549 *image;
3550
cristy15655332013-10-06 00:27:33 +00003551 register ssize_t
3552 i;
3553
3554 struct PackageInfo
3555 *info;
3556
3557 SV
3558 *perl_exception,
3559 *reference,
3560 *rv,
3561 *sv;
3562
3563 PERL_UNUSED_VAR(ref);
3564 PERL_UNUSED_VAR(ix);
3565 exception=AcquireExceptionInfo();
3566 perl_exception=newSVpv("",0);
3567 sv=NULL;
3568 if (sv_isobject(ST(0)) == 0)
3569 {
3570 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3571 PackageName);
3572 goto PerlException;
3573 }
3574 reference=SvRV(ST(0));
3575 hv=SvSTASH(reference);
3576 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3577 if (image == (Image *) NULL)
3578 {
3579 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3580 PackageName);
3581 goto PerlException;
3582 }
cristyfd168722013-10-07 15:59:31 +00003583 op=UndefinedComplexOperator;
cristy15655332013-10-06 00:27:33 +00003584 if (items == 2)
3585 {
3586 ssize_t
3587 in;
3588
3589 in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *)
3590 SvPV(ST(1),na));
3591 if (in < 0)
3592 {
3593 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3594 SvPV(ST(1),na));
3595 return;
3596 }
cristyfa21e9e2013-10-07 10:37:38 +00003597 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003598 }
3599 else
3600 for (i=2; i < items; i+=2)
3601 {
3602 attribute=(char *) SvPV(ST(i-1),na);
3603 switch (*attribute)
3604 {
3605 case 'O':
3606 case 'o':
3607 {
3608 if (LocaleCompare(attribute,"operator") == 0)
3609 {
3610 ssize_t
3611 in;
3612
3613 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3614 MagickComplexOptions,MagickFalse,SvPV(ST(i),na));
3615 if (in < 0)
3616 {
3617 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3618 SvPV(ST(i),na));
3619 return;
3620 }
cristyfa21e9e2013-10-07 10:37:38 +00003621 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003622 break;
3623 }
3624 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3625 attribute);
3626 break;
3627 }
3628 default:
3629 {
3630 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3631 attribute);
3632 break;
3633 }
3634 }
3635 }
3636 image=ComplexImages(image,op,exception);
3637 if (image == (Image *) NULL)
3638 goto PerlException;
3639 /*
3640 Create blessed Perl array for the returned image.
3641 */
3642 av=newAV();
3643 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3644 SvREFCNT_dec(av);
3645 AddImageToRegistry(sv,image);
3646 rv=newRV(sv);
3647 av_push(av,sv_bless(rv,hv));
3648 SvREFCNT_dec(sv);
3649 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00003650 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
3651 "complex-%.*s",(int) (MagickPathExtent-9),
cristy15655332013-10-06 00:27:33 +00003652 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3653 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00003654 MagickPathExtent);
cristy15655332013-10-06 00:27:33 +00003655 SetImageInfo(info->image_info,0,exception);
3656 exception=DestroyExceptionInfo(exception);
3657 SvREFCNT_dec(perl_exception);
3658 XSRETURN(1);
3659
3660 PerlException:
3661 InheritPerlException(exception,perl_exception);
3662 exception=DestroyExceptionInfo(exception);
3663 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3664 SvPOK_on(perl_exception);
3665 ST(0)=sv_2mortal(perl_exception);
3666 XSRETURN(1);
3667 }
3668
3669#
3670###############################################################################
3671# #
3672# #
3673# #
cristy4a3ce0a2013-08-03 20:06:59 +00003674# C o m p a r e L a y e r s #
3675# #
3676# #
3677# #
3678###############################################################################
3679#
3680#
3681void
3682CompareLayers(ref)
3683 Image::Magick ref=NO_INIT
3684 ALIAS:
3685 CompareImagesLayers = 1
3686 comparelayers = 2
3687 compareimagelayers = 3
3688 PPCODE:
3689 {
3690 AV
3691 *av;
3692
3693 char
3694 *attribute;
3695
3696 ExceptionInfo
3697 *exception;
3698
3699 HV
3700 *hv;
3701
3702 Image
3703 *image;
3704
3705 LayerMethod
3706 method;
3707
3708 register ssize_t
3709 i;
3710
3711 ssize_t
3712 option;
3713
3714 struct PackageInfo
3715 *info;
3716
3717 SV
3718 *av_reference,
3719 *perl_exception,
3720 *reference,
3721 *rv,
3722 *sv;
3723
3724 PERL_UNUSED_VAR(ref);
3725 PERL_UNUSED_VAR(ix);
3726 exception=AcquireExceptionInfo();
3727 perl_exception=newSVpv("",0);
3728 sv=NULL;
3729 if (sv_isobject(ST(0)) == 0)
3730 {
3731 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3732 PackageName);
3733 goto PerlException;
3734 }
3735 reference=SvRV(ST(0));
3736 hv=SvSTASH(reference);
3737 av=newAV();
3738 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3739 SvREFCNT_dec(av);
3740 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3741 if (image == (Image *) NULL)
3742 {
3743 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3744 PackageName);
3745 goto PerlException;
3746 }
3747 method=CompareAnyLayer;
3748 for (i=2; i < items; i+=2)
3749 {
3750 attribute=(char *) SvPV(ST(i-1),na);
3751 switch (*attribute)
3752 {
3753 case 'M':
3754 case 'm':
3755 {
3756 if (LocaleCompare(attribute,"method") == 0)
3757 {
3758 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3759 SvPV(ST(i),na));
3760 if (option < 0)
3761 {
3762 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3763 SvPV(ST(i),na));
3764 break;
3765 }
3766 method=(LayerMethod) option;
3767 break;
3768 }
3769 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3770 attribute);
3771 break;
3772 }
3773 default:
3774 {
3775 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3776 attribute);
3777 break;
3778 }
3779 }
3780 }
3781 image=CompareImagesLayers(image,method,exception);
3782 if (image == (Image *) NULL)
3783 goto PerlException;
3784 for ( ; image; image=image->next)
3785 {
3786 AddImageToRegistry(sv,image);
3787 rv=newRV(sv);
3788 av_push(av,sv_bless(rv,hv));
3789 SvREFCNT_dec(sv);
3790 }
3791 exception=DestroyExceptionInfo(exception);
3792 ST(0)=av_reference;
3793 SvREFCNT_dec(perl_exception);
3794 XSRETURN(1);
3795
3796 PerlException:
3797 InheritPerlException(exception,perl_exception);
3798 exception=DestroyExceptionInfo(exception);
3799 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3800 SvPOK_on(perl_exception);
3801 ST(0)=sv_2mortal(perl_exception);
3802 XSRETURN(1);
3803 }
3804
3805#
3806###############################################################################
3807# #
3808# #
3809# #
3810# D e s t r o y #
3811# #
3812# #
3813# #
3814###############################################################################
3815#
3816#
3817void
3818DESTROY(ref)
3819 Image::Magick ref=NO_INIT
3820 PPCODE:
3821 {
3822 SV
3823 *reference;
3824
3825 PERL_UNUSED_VAR(ref);
3826 if (sv_isobject(ST(0)) == 0)
3827 croak("ReferenceIsNotMyType");
3828 reference=SvRV(ST(0));
3829 switch (SvTYPE(reference))
3830 {
3831 case SVt_PVAV:
3832 {
3833 char
cristy151b66d2015-04-15 10:50:31 +00003834 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00003835
3836 const SV
3837 *key;
3838
3839 HV
3840 *hv;
3841
3842 GV
3843 **gvp;
3844
3845 struct PackageInfo
3846 *info;
3847
3848 SV
3849 *sv;
3850
3851 /*
3852 Array (AV *) reference
3853 */
cristy151b66d2015-04-15 10:50:31 +00003854 (void) FormatLocaleString(message,MagickPathExtent,"package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00003855 XS_VERSION,reference);
3856 hv=gv_stashpv(PackageName, FALSE);
3857 if (!hv)
3858 break;
3859 gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3860 if (!gvp)
3861 break;
3862 sv=GvSV(*gvp);
3863 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3864 {
3865 info=INT2PTR(struct PackageInfo *,SvIV(sv));
3866 DestroyPackageInfo(info);
3867 }
3868 key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3869 (void) key;
3870 break;
3871 }
3872 case SVt_PVMG:
3873 {
3874 Image
3875 *image;
3876
3877 /*
3878 Blessed scalar = (Image *) SvIV(reference)
3879 */
3880 image=INT2PTR(Image *,SvIV(reference));
3881 if (image != (Image *) NULL)
3882 DeleteImageFromRegistry(reference,image);
3883 break;
3884 }
3885 default:
3886 break;
3887 }
3888 }
3889
3890#
3891###############################################################################
3892# #
3893# #
3894# #
3895# D i s p l a y #
3896# #
3897# #
3898# #
3899###############################################################################
3900#
3901#
3902void
3903Display(ref,...)
3904 Image::Magick ref=NO_INIT
3905 ALIAS:
3906 DisplayImage = 1
3907 display = 2
3908 displayimage = 3
3909 PPCODE:
3910 {
3911 ExceptionInfo
3912 *exception;
3913
3914 Image
3915 *image;
3916
3917 register ssize_t
3918 i;
3919
3920 struct PackageInfo
3921 *info,
3922 *package_info;
3923
3924 SV
3925 *perl_exception,
3926 *reference;
3927
3928 PERL_UNUSED_VAR(ref);
3929 PERL_UNUSED_VAR(ix);
3930 exception=AcquireExceptionInfo();
3931 perl_exception=newSVpv("",0);
3932 package_info=(struct PackageInfo *) NULL;
3933 if (sv_isobject(ST(0)) == 0)
3934 {
3935 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3936 PackageName);
3937 goto PerlException;
3938 }
3939 reference=SvRV(ST(0));
3940 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3941 if (image == (Image *) NULL)
3942 {
3943 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3944 PackageName);
3945 goto PerlException;
3946 }
3947 package_info=ClonePackageInfo(info,exception);
3948 if (items == 2)
3949 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3950 else
3951 if (items > 2)
3952 for (i=2; i < items; i+=2)
3953 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3954 exception);
3955 (void) DisplayImages(package_info->image_info,image,exception);
3956 (void) CatchImageException(image);
3957
3958 PerlException:
3959 if (package_info != (struct PackageInfo *) NULL)
3960 DestroyPackageInfo(package_info);
3961 InheritPerlException(exception,perl_exception);
3962 exception=DestroyExceptionInfo(exception);
3963 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3964 SvPOK_on(perl_exception);
3965 ST(0)=sv_2mortal(perl_exception);
3966 XSRETURN(1);
3967 }
3968
3969#
3970###############################################################################
3971# #
3972# #
3973# #
3974# E v a l u a t e I m a g e s #
3975# #
3976# #
3977# #
3978###############################################################################
3979#
3980#
3981void
3982EvaluateImages(ref)
3983 Image::Magick ref=NO_INIT
3984 ALIAS:
3985 EvaluateImages = 1
3986 evaluateimages = 2
3987 PPCODE:
3988 {
3989 AV
3990 *av;
3991
3992 char
3993 *attribute,
3994 *p;
3995
3996 ExceptionInfo
3997 *exception;
3998
3999 HV
4000 *hv;
4001
4002 Image
4003 *image;
4004
4005 MagickEvaluateOperator
4006 op;
4007
4008 register ssize_t
4009 i;
4010
4011 struct PackageInfo
4012 *info;
4013
4014 SV
4015 *perl_exception,
4016 *reference,
4017 *rv,
4018 *sv;
4019
4020 PERL_UNUSED_VAR(ref);
4021 PERL_UNUSED_VAR(ix);
4022 exception=AcquireExceptionInfo();
4023 perl_exception=newSVpv("",0);
4024 sv=NULL;
4025 if (sv_isobject(ST(0)) == 0)
4026 {
4027 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4028 PackageName);
4029 goto PerlException;
4030 }
4031 reference=SvRV(ST(0));
4032 hv=SvSTASH(reference);
4033 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4034 if (image == (Image *) NULL)
4035 {
4036 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4037 PackageName);
4038 goto PerlException;
4039 }
4040 op=MeanEvaluateOperator;
4041 if (items == 2)
4042 {
4043 ssize_t
4044 in;
4045
4046 in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
4047 SvPV(ST(1),na));
4048 if (in < 0)
4049 {
4050 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4051 SvPV(ST(1),na));
4052 return;
4053 }
4054 op=(MagickEvaluateOperator) in;
4055 }
4056 else
4057 for (i=2; i < items; i+=2)
4058 {
4059 attribute=(char *) SvPV(ST(i-1),na);
4060 switch (*attribute)
4061 {
4062 case 'O':
4063 case 'o':
4064 {
4065 if (LocaleCompare(attribute,"operator") == 0)
4066 {
4067 ssize_t
4068 in;
4069
4070 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
4071 MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
4072 if (in < 0)
4073 {
4074 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4075 SvPV(ST(i),na));
4076 return;
4077 }
4078 op=(MagickEvaluateOperator) in;
4079 break;
4080 }
4081 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4082 attribute);
4083 break;
4084 }
4085 default:
4086 {
4087 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4088 attribute);
4089 break;
4090 }
4091 }
4092 }
4093 image=EvaluateImages(image,op,exception);
4094 if (image == (Image *) NULL)
4095 goto PerlException;
4096 /*
4097 Create blessed Perl array for the returned image.
4098 */
4099 av=newAV();
4100 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4101 SvREFCNT_dec(av);
4102 AddImageToRegistry(sv,image);
4103 rv=newRV(sv);
4104 av_push(av,sv_bless(rv,hv));
4105 SvREFCNT_dec(sv);
4106 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004107 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4108 "evaluate-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004109 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4110 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004111 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004112 SetImageInfo(info->image_info,0,exception);
4113 exception=DestroyExceptionInfo(exception);
4114 SvREFCNT_dec(perl_exception);
4115 XSRETURN(1);
4116
4117 PerlException:
4118 InheritPerlException(exception,perl_exception);
4119 exception=DestroyExceptionInfo(exception);
4120 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4121 SvPOK_on(perl_exception);
4122 ST(0)=sv_2mortal(perl_exception);
4123 XSRETURN(1);
4124 }
4125
4126#
4127###############################################################################
4128# #
4129# #
4130# #
4131# F e a t u r e s #
4132# #
4133# #
4134# #
4135###############################################################################
4136#
4137#
4138void
4139Features(ref,...)
4140 Image::Magick ref=NO_INIT
4141 ALIAS:
4142 FeaturesImage = 1
4143 features = 2
4144 featuresimage = 3
4145 PPCODE:
4146 {
4147#define ChannelFeatures(channel,direction) \
4148{ \
Cristyb1710fe2017-02-11 13:51:48 -05004149 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004150 channel_features[channel].angular_second_moment[direction]); \
4151 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004152 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004153 channel_features[channel].contrast[direction]); \
4154 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004155 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004156 channel_features[channel].contrast[direction]); \
4157 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004158 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004159 channel_features[channel].variance_sum_of_squares[direction]); \
4160 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004161 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004162 channel_features[channel].inverse_difference_moment[direction]); \
4163 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004164 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004165 channel_features[channel].sum_average[direction]); \
4166 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004167 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004168 channel_features[channel].sum_variance[direction]); \
4169 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004170 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004171 channel_features[channel].sum_entropy[direction]); \
4172 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004173 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004174 channel_features[channel].entropy[direction]); \
4175 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004176 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004177 channel_features[channel].difference_variance[direction]); \
4178 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004179 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004180 channel_features[channel].difference_entropy[direction]); \
4181 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004182 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004183 channel_features[channel].measure_of_correlation_1[direction]); \
4184 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004185 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004186 channel_features[channel].measure_of_correlation_2[direction]); \
4187 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004188 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004189 channel_features[channel].maximum_correlation_coefficient[direction]); \
4190 PUSHs(sv_2mortal(newSVpv(message,0))); \
4191}
4192
4193 AV
4194 *av;
4195
4196 char
4197 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004198 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004199
4200 ChannelFeatures
4201 *channel_features;
4202
4203 double
4204 distance;
4205
4206 ExceptionInfo
4207 *exception;
4208
4209 Image
4210 *image;
4211
4212 register ssize_t
4213 i;
4214
4215 ssize_t
4216 count;
4217
4218 struct PackageInfo
4219 *info;
4220
4221 SV
4222 *perl_exception,
4223 *reference;
4224
4225 PERL_UNUSED_VAR(ref);
4226 PERL_UNUSED_VAR(ix);
4227 exception=AcquireExceptionInfo();
4228 perl_exception=newSVpv("",0);
4229 av=NULL;
4230 if (sv_isobject(ST(0)) == 0)
4231 {
4232 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4233 PackageName);
4234 goto PerlException;
4235 }
4236 reference=SvRV(ST(0));
4237 av=newAV();
4238 SvREFCNT_dec(av);
4239 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4240 if (image == (Image *) NULL)
4241 {
4242 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4243 PackageName);
4244 goto PerlException;
4245 }
cristy7dbd9262014-07-02 17:53:42 +00004246 distance=1.0;
cristy4a3ce0a2013-08-03 20:06:59 +00004247 for (i=2; i < items; i+=2)
4248 {
4249 attribute=(char *) SvPV(ST(i-1),na);
4250 switch (*attribute)
4251 {
4252 case 'D':
4253 case 'd':
4254 {
4255 if (LocaleCompare(attribute,"distance") == 0)
4256 {
4257 distance=StringToLong((char *) SvPV(ST(1),na));
4258 break;
4259 }
4260 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4261 attribute);
4262 break;
4263 }
4264 default:
4265 {
4266 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4267 attribute);
4268 break;
4269 }
4270 }
4271 }
4272 count=0;
4273 for ( ; image; image=image->next)
4274 {
Cristy5a854dc2017-02-11 15:43:46 -05004275 register ssize_t
4276 j;
4277
cristy4a3ce0a2013-08-03 20:06:59 +00004278 channel_features=GetImageFeatures(image,distance,exception);
4279 if (channel_features == (ChannelFeatures *) NULL)
4280 continue;
4281 count++;
Cristy5a854dc2017-02-11 15:43:46 -05004282 for (j=0; j < 4; j++)
cristy4a3ce0a2013-08-03 20:06:59 +00004283 {
Cristy5a854dc2017-02-11 15:43:46 -05004284 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
4285 {
4286 PixelChannel channel=GetPixelChannelChannel(image,i);
4287 PixelTrait traits=GetPixelChannelTraits(image,channel);
4288 if (traits == UndefinedPixelTrait)
4289 continue;
4290 EXTEND(sp,14*(i+1)*count);
4291 ChannelFeatures(channel,j);
4292 }
cristy4a3ce0a2013-08-03 20:06:59 +00004293 }
4294 channel_features=(ChannelFeatures *)
4295 RelinquishMagickMemory(channel_features);
4296 }
4297
4298 PerlException:
4299 InheritPerlException(exception,perl_exception);
4300 exception=DestroyExceptionInfo(exception);
4301 SvREFCNT_dec(perl_exception);
4302 }
4303
4304#
4305###############################################################################
4306# #
4307# #
4308# #
4309# F l a t t e n #
4310# #
4311# #
4312# #
4313###############################################################################
4314#
4315#
4316void
4317Flatten(ref)
4318 Image::Magick ref=NO_INIT
4319 ALIAS:
4320 FlattenImage = 1
4321 flatten = 2
4322 flattenimage = 3
4323 PPCODE:
4324 {
4325 AV
4326 *av;
4327
4328 char
4329 *attribute,
4330 *p;
4331
4332 ExceptionInfo
4333 *exception;
4334
4335 HV
4336 *hv;
4337
4338 Image
4339 *image;
4340
4341 PixelInfo
4342 background_color;
4343
4344 register ssize_t
4345 i;
4346
4347 struct PackageInfo
4348 *info;
4349
4350 SV
4351 *perl_exception,
4352 *reference,
4353 *rv,
4354 *sv;
4355
4356 PERL_UNUSED_VAR(ref);
4357 PERL_UNUSED_VAR(ix);
4358 exception=AcquireExceptionInfo();
4359 perl_exception=newSVpv("",0);
4360 sv=NULL;
4361 if (sv_isobject(ST(0)) == 0)
4362 {
4363 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4364 PackageName);
4365 goto PerlException;
4366 }
4367 reference=SvRV(ST(0));
4368 hv=SvSTASH(reference);
4369 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4370 if (image == (Image *) NULL)
4371 {
4372 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4373 PackageName);
4374 goto PerlException;
4375 }
4376 background_color=image->background_color;
4377 if (items == 2)
4378 (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4379 &background_color,exception);
4380 else
4381 for (i=2; i < items; i+=2)
4382 {
4383 attribute=(char *) SvPV(ST(i-1),na);
4384 switch (*attribute)
4385 {
4386 case 'B':
4387 case 'b':
4388 {
4389 if (LocaleCompare(attribute,"background") == 0)
4390 {
4391 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4392 AllCompliance,&background_color,exception);
4393 break;
4394 }
4395 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4396 attribute);
4397 break;
4398 }
4399 default:
4400 {
4401 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4402 attribute);
4403 break;
4404 }
4405 }
4406 }
4407 image->background_color=background_color;
4408 image=MergeImageLayers(image,FlattenLayer,exception);
4409 if (image == (Image *) NULL)
4410 goto PerlException;
4411 /*
4412 Create blessed Perl array for the returned image.
4413 */
4414 av=newAV();
4415 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4416 SvREFCNT_dec(av);
4417 AddImageToRegistry(sv,image);
4418 rv=newRV(sv);
4419 av_push(av,sv_bless(rv,hv));
4420 SvREFCNT_dec(sv);
4421 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004422 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4423 "flatten-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004424 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4425 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004426 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004427 SetImageInfo(info->image_info,0,exception);
4428 exception=DestroyExceptionInfo(exception);
4429 SvREFCNT_dec(perl_exception);
4430 XSRETURN(1);
4431
4432 PerlException:
4433 InheritPerlException(exception,perl_exception);
4434 exception=DestroyExceptionInfo(exception);
4435 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4436 SvPOK_on(perl_exception); /* return messages in string context */
4437 ST(0)=sv_2mortal(perl_exception);
4438 XSRETURN(1);
4439 }
4440
4441#
4442###############################################################################
4443# #
4444# #
4445# #
4446# F x #
4447# #
4448# #
4449# #
4450###############################################################################
4451#
4452#
4453void
4454Fx(ref,...)
4455 Image::Magick ref=NO_INIT
4456 ALIAS:
4457 FxImage = 1
4458 fx = 2
4459 fximage = 3
4460 PPCODE:
4461 {
4462 AV
4463 *av;
4464
4465 char
4466 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004467 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004468
4469 ChannelType
4470 channel,
4471 channel_mask;
4472
4473 ExceptionInfo
4474 *exception;
4475
4476 HV
4477 *hv;
4478
4479 Image
4480 *image;
4481
4482 register ssize_t
4483 i;
4484
4485 struct PackageInfo
4486 *info;
4487
4488 SV
4489 *av_reference,
4490 *perl_exception,
4491 *reference,
4492 *rv,
4493 *sv;
4494
4495 PERL_UNUSED_VAR(ref);
4496 PERL_UNUSED_VAR(ix);
4497 exception=AcquireExceptionInfo();
4498 perl_exception=newSVpv("",0);
4499 sv=NULL;
4500 attribute=NULL;
4501 av=NULL;
4502 if (sv_isobject(ST(0)) == 0)
4503 {
4504 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4505 PackageName);
4506 goto PerlException;
4507 }
4508 reference=SvRV(ST(0));
4509 hv=SvSTASH(reference);
4510 av=newAV();
4511 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4512 SvREFCNT_dec(av);
4513 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4514 if (image == (Image *) NULL)
4515 {
4516 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4517 PackageName);
4518 goto PerlException;
4519 }
4520 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4521 /*
4522 Get options.
4523 */
4524 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00004525 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004526 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00004527 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004528 else
4529 for (i=2; i < items; i+=2)
4530 {
4531 attribute=(char *) SvPV(ST(i-1),na);
4532 switch (*attribute)
4533 {
4534 case 'C':
4535 case 'c':
4536 {
4537 if (LocaleCompare(attribute,"channel") == 0)
4538 {
4539 ssize_t
4540 option;
4541
4542 option=ParseChannelOption(SvPV(ST(i),na));
4543 if (option < 0)
4544 {
4545 ThrowPerlException(exception,OptionError,
4546 "UnrecognizedType",SvPV(ST(i),na));
4547 return;
4548 }
4549 channel=(ChannelType) option;
4550 break;
4551 }
4552 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4553 attribute);
4554 break;
4555 }
4556 case 'E':
4557 case 'e':
4558 {
4559 if (LocaleCompare(attribute,"expression") == 0)
4560 {
4561 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00004562 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004563 break;
4564 }
4565 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4566 attribute);
4567 break;
4568 }
4569 default:
4570 {
4571 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4572 attribute);
4573 break;
4574 }
4575 }
4576 }
4577 channel_mask=SetImageChannelMask(image,channel);
4578 image=FxImage(image,expression,exception);
4579 if (image != (Image *) NULL)
4580 (void) SetImageChannelMask(image,channel_mask);
4581 if (image == (Image *) NULL)
4582 goto PerlException;
4583 for ( ; image; image=image->next)
4584 {
4585 AddImageToRegistry(sv,image);
4586 rv=newRV(sv);
4587 av_push(av,sv_bless(rv,hv));
4588 SvREFCNT_dec(sv);
4589 }
4590 exception=DestroyExceptionInfo(exception);
4591 ST(0)=av_reference;
4592 SvREFCNT_dec(perl_exception); /* can't return warning messages */
4593 XSRETURN(1);
4594
4595 PerlException:
4596 InheritPerlException(exception,perl_exception);
4597 exception=DestroyExceptionInfo(exception);
4598 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4599 SvPOK_on(perl_exception);
4600 ST(0)=sv_2mortal(perl_exception);
4601 XSRETURN(1);
4602 }
4603
4604#
4605###############################################################################
4606# #
4607# #
4608# #
4609# G e t #
4610# #
4611# #
4612# #
4613###############################################################################
4614#
4615#
4616void
4617Get(ref,...)
4618 Image::Magick ref=NO_INIT
4619 ALIAS:
4620 GetAttributes = 1
4621 GetAttribute = 2
4622 get = 3
4623 getattributes = 4
4624 getattribute = 5
4625 PPCODE:
4626 {
4627 char
4628 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004629 color[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004630
4631 const char
4632 *value;
4633
4634 ExceptionInfo
4635 *exception;
4636
4637 Image
4638 *image;
4639
4640 long
4641 j;
4642
4643 register ssize_t
4644 i;
4645
4646 struct PackageInfo
4647 *info;
4648
4649 SV
4650 *perl_exception,
4651 *reference,
4652 *s;
4653
4654 PERL_UNUSED_VAR(ref);
4655 PERL_UNUSED_VAR(ix);
4656 exception=AcquireExceptionInfo();
4657 perl_exception=newSVpv("",0);
4658 if (sv_isobject(ST(0)) == 0)
4659 {
4660 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4661 PackageName);
4662 XSRETURN_EMPTY;
4663 }
4664 reference=SvRV(ST(0));
4665 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4666 if (image == (Image *) NULL && !info)
4667 XSRETURN_EMPTY;
4668 EXTEND(sp,items);
4669 for (i=1; i < items; i++)
4670 {
4671 attribute=(char *) SvPV(ST(i),na);
4672 s=NULL;
4673 switch (*attribute)
4674 {
4675 case 'A':
4676 case 'a':
4677 {
4678 if (LocaleCompare(attribute,"adjoin") == 0)
4679 {
4680 if (info)
4681 s=newSViv((ssize_t) info->image_info->adjoin);
4682 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4683 continue;
4684 }
4685 if (LocaleCompare(attribute,"antialias") == 0)
4686 {
4687 if (info)
4688 s=newSViv((ssize_t) info->image_info->antialias);
4689 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4690 continue;
4691 }
4692 if (LocaleCompare(attribute,"area") == 0)
4693 {
4694 s=newSViv(GetMagickResource(AreaResource));
4695 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4696 continue;
4697 }
4698 if (LocaleCompare(attribute,"attenuate") == 0)
4699 {
4700 const char
4701 *value;
4702
4703 value=GetImageProperty(image,attribute,exception);
4704 if (value != (const char *) NULL)
4705 s=newSVpv(value,0);
4706 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4707 continue;
4708 }
4709 if (LocaleCompare(attribute,"authenticate") == 0)
4710 {
4711 if (info)
4712 {
4713 const char
4714 *option;
4715
4716 option=GetImageOption(info->image_info,attribute);
4717 if (option != (const char *) NULL)
4718 s=newSVpv(option,0);
4719 }
4720 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4721 continue;
4722 }
4723 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4724 attribute);
4725 break;
4726 }
4727 case 'B':
4728 case 'b':
4729 {
4730 if (LocaleCompare(attribute,"background") == 0)
4731 {
4732 if (image == (Image *) NULL)
4733 break;
cristy151b66d2015-04-15 10:50:31 +00004734 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004735 "%.20g,%.20g,%.20g,%.20g",(double) image->background_color.red,
4736 (double) image->background_color.green,
4737 (double) image->background_color.blue,
4738 (double) image->background_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004739 s=newSVpv(color,0);
4740 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4741 continue;
4742 }
4743 if (LocaleCompare(attribute,"base-columns") == 0)
4744 {
4745 if (image != (Image *) NULL)
4746 s=newSViv((ssize_t) image->magick_columns);
4747 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4748 continue;
4749 }
4750 if (LocaleCompare(attribute,"base-filename") == 0)
4751 {
4752 if (image != (Image *) NULL)
4753 s=newSVpv(image->magick_filename,0);
4754 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4755 continue;
4756 }
4757 if (LocaleCompare(attribute,"base-height") == 0)
4758 {
4759 if (image != (Image *) NULL)
4760 s=newSViv((ssize_t) image->magick_rows);
4761 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4762 continue;
4763 }
4764 if (LocaleCompare(attribute,"base-rows") == 0)
4765 {
4766 if (image != (Image *) NULL)
4767 s=newSViv((ssize_t) image->magick_rows);
4768 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4769 continue;
4770 }
4771 if (LocaleCompare(attribute,"base-width") == 0)
4772 {
4773 if (image != (Image *) NULL)
4774 s=newSViv((ssize_t) image->magick_columns);
4775 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4776 continue;
4777 }
4778 if (LocaleCompare(attribute,"blue-primary") == 0)
4779 {
4780 if (image == (Image *) NULL)
4781 break;
Cristyb1710fe2017-02-11 13:51:48 -05004782 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00004783 image->chromaticity.blue_primary.x,
4784 image->chromaticity.blue_primary.y);
4785 s=newSVpv(color,0);
4786 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4787 continue;
4788 }
4789 if (LocaleCompare(attribute,"bordercolor") == 0)
4790 {
4791 if (image == (Image *) NULL)
4792 break;
cristy151b66d2015-04-15 10:50:31 +00004793 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004794 "%.20g,%.20g,%.20g,%.20g",(double) image->border_color.red,
4795 (double) image->border_color.green,
4796 (double) image->border_color.blue,
4797 (double) image->border_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004798 s=newSVpv(color,0);
4799 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4800 continue;
4801 }
4802 if (LocaleCompare(attribute,"bounding-box") == 0)
4803 {
4804 char
cristy151b66d2015-04-15 10:50:31 +00004805 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004806
4807 RectangleInfo
4808 page;
4809
4810 if (image == (Image *) NULL)
4811 break;
4812 page=GetImageBoundingBox(image,exception);
cristy151b66d2015-04-15 10:50:31 +00004813 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00004814 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4815 page.height,(double) page.x,(double) page.y);
4816 s=newSVpv(geometry,0);
4817 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4818 continue;
4819 }
4820 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4821 attribute);
4822 break;
4823 }
4824 case 'C':
4825 case 'c':
4826 {
4827 if (LocaleCompare(attribute,"class") == 0)
4828 {
4829 if (image == (Image *) NULL)
4830 break;
4831 s=newSViv(image->storage_class);
4832 (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4833 image->storage_class));
4834 SvIOK_on(s);
4835 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4836 continue;
4837 }
4838 if (LocaleCompare(attribute,"clip-mask") == 0)
4839 {
4840 if (image != (Image *) NULL)
4841 {
4842 Image
4843 *mask_image;
4844
4845 SV
4846 *sv;
4847
4848 sv=NULL;
4849 if (image->read_mask == MagickFalse)
4850 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004851 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004852 if (mask_image != (Image *) NULL)
4853 {
4854 AddImageToRegistry(sv,mask_image);
4855 s=sv_bless(newRV(sv),SvSTASH(reference));
4856 }
4857 }
4858 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4859 continue;
4860 }
4861 if (LocaleCompare(attribute,"clip-path") == 0)
4862 {
4863 if (image != (Image *) NULL)
4864 {
4865 Image
4866 *mask_image;
4867
4868 SV
4869 *sv;
4870
4871 sv=NULL;
4872 if (image->read_mask != MagickFalse)
4873 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004874 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004875 if (mask_image != (Image *) NULL)
4876 {
4877 AddImageToRegistry(sv,mask_image);
4878 s=sv_bless(newRV(sv),SvSTASH(reference));
4879 }
4880 }
4881 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4882 continue;
4883 }
4884 if (LocaleCompare(attribute,"compression") == 0)
4885 {
4886 j=info ? info->image_info->compression : image ?
4887 image->compression : UndefinedCompression;
4888 if (info)
4889 if (info->image_info->compression == UndefinedCompression)
4890 j=image->compression;
4891 s=newSViv(j);
4892 (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4893 j));
4894 SvIOK_on(s);
4895 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4896 continue;
4897 }
4898 if (LocaleCompare(attribute,"colorspace") == 0)
4899 {
4900 j=image ? image->colorspace : RGBColorspace;
4901 s=newSViv(j);
4902 (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4903 j));
4904 SvIOK_on(s);
4905 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4906 continue;
4907 }
4908 if (LocaleCompare(attribute,"colors") == 0)
4909 {
4910 if (image != (Image *) NULL)
4911 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4912 exception));
4913 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4914 continue;
4915 }
4916 if (LocaleNCompare(attribute,"colormap",8) == 0)
4917 {
4918 int
4919 items;
4920
4921 if (image == (Image *) NULL || !image->colormap)
4922 break;
4923 j=0;
4924 items=sscanf(attribute,"%*[^[][%ld",&j);
4925 (void) items;
4926 if (j > (ssize_t) image->colors)
4927 j%=image->colors;
cristy151b66d2015-04-15 10:50:31 +00004928 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004929 "%.20g,%.20g,%.20g,%.20g",(double) image->colormap[j].red,
4930 (double) image->colormap[j].green,
4931 (double) image->colormap[j].blue,
4932 (double) image->colormap[j].alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004933 s=newSVpv(color,0);
4934 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4935 continue;
4936 }
4937 if (LocaleCompare(attribute,"columns") == 0)
4938 {
4939 if (image != (Image *) NULL)
4940 s=newSViv((ssize_t) image->columns);
4941 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4942 continue;
4943 }
4944 if (LocaleCompare(attribute,"comment") == 0)
4945 {
4946 const char
4947 *value;
4948
Cristy935a4052017-03-31 17:45:37 -04004949 value=GetImageProperty(image,attribute,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004950 if (value != (const char *) NULL)
4951 s=newSVpv(value,0);
4952 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4953 continue;
4954 }
4955 if (LocaleCompare(attribute,"copyright") == 0)
4956 {
4957 s=newSVpv(GetMagickCopyright(),0);
4958 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4959 continue;
4960 }
4961 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4962 attribute);
4963 break;
4964 }
4965 case 'D':
4966 case 'd':
4967 {
4968 if (LocaleCompare(attribute,"density") == 0)
4969 {
4970 char
cristy151b66d2015-04-15 10:50:31 +00004971 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004972
4973 if (image == (Image *) NULL)
4974 break;
Cristyb1710fe2017-02-11 13:51:48 -05004975 (void) FormatLocaleString(geometry,MagickPathExtent,"%.20gx%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00004976 image->resolution.x,image->resolution.y);
4977 s=newSVpv(geometry,0);
4978 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4979 continue;
4980 }
4981 if (LocaleCompare(attribute,"delay") == 0)
4982 {
4983 if (image != (Image *) NULL)
4984 s=newSViv((ssize_t) image->delay);
4985 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4986 continue;
4987 }
4988 if (LocaleCompare(attribute,"depth") == 0)
4989 {
4990 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
4991 if (image != (Image *) NULL)
4992 s=newSViv((ssize_t) GetImageDepth(image,exception));
4993 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4994 continue;
4995 }
4996 if (LocaleCompare(attribute,"directory") == 0)
4997 {
4998 if (image && image->directory)
4999 s=newSVpv(image->directory,0);
5000 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5001 continue;
5002 }
5003 if (LocaleCompare(attribute,"dispose") == 0)
5004 {
5005 if (image == (Image *) NULL)
5006 break;
5007
5008 s=newSViv(image->dispose);
5009 (void) sv_setpv(s,
5010 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
5011 SvIOK_on(s);
5012 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5013 continue;
5014 }
5015 if (LocaleCompare(attribute,"disk") == 0)
5016 {
5017 s=newSViv(GetMagickResource(DiskResource));
5018 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5019 continue;
5020 }
5021 if (LocaleCompare(attribute,"dither") == 0)
5022 {
5023 if (info)
5024 s=newSViv((ssize_t) info->image_info->dither);
5025 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5026 continue;
5027 }
5028 if (LocaleCompare(attribute,"display") == 0) /* same as server */
5029 {
5030 if (info && info->image_info->server_name)
5031 s=newSVpv(info->image_info->server_name,0);
5032 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5033 continue;
5034 }
5035 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5036 attribute);
5037 break;
5038 }
5039 case 'E':
5040 case 'e':
5041 {
5042 if (LocaleCompare(attribute,"elapsed-time") == 0)
5043 {
5044 if (image != (Image *) NULL)
5045 s=newSVnv(GetElapsedTime(&image->timer));
5046 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5047 continue;
5048 }
5049 if (LocaleCompare(attribute,"endian") == 0)
5050 {
5051 j=info ? info->image_info->endian : image ? image->endian :
5052 UndefinedEndian;
5053 s=newSViv(j);
5054 (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
5055 SvIOK_on(s);
5056 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5057 continue;
5058 }
5059 if (LocaleCompare(attribute,"error") == 0)
5060 {
5061 if (image != (Image *) NULL)
5062 s=newSVnv(image->error.mean_error_per_pixel);
5063 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5064 continue;
5065 }
5066 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5067 attribute);
5068 break;
5069 }
5070 case 'F':
5071 case 'f':
5072 {
5073 if (LocaleCompare(attribute,"filesize") == 0)
5074 {
5075 if (image != (Image *) NULL)
5076 s=newSViv((ssize_t) GetBlobSize(image));
5077 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5078 continue;
5079 }
5080 if (LocaleCompare(attribute,"filename") == 0)
5081 {
Cristy2273d6a2017-07-14 19:19:55 -04005082 if (info && *info->image_info->filename)
cristy4a3ce0a2013-08-03 20:06:59 +00005083 s=newSVpv(info->image_info->filename,0);
5084 if (image != (Image *) NULL)
5085 s=newSVpv(image->filename,0);
5086 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5087 continue;
5088 }
5089 if (LocaleCompare(attribute,"filter") == 0)
5090 {
5091 s=image ? newSViv(image->filter) : newSViv(0);
5092 (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
5093 image->filter));
5094 SvIOK_on(s);
5095 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5096 continue;
5097 }
5098 if (LocaleCompare(attribute,"font") == 0)
5099 {
5100 if (info && info->image_info->font)
5101 s=newSVpv(info->image_info->font,0);
5102 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5103 continue;
5104 }
5105 if (LocaleCompare(attribute,"foreground") == 0)
5106 continue;
5107 if (LocaleCompare(attribute,"format") == 0)
5108 {
5109 const MagickInfo
5110 *magick_info;
5111
5112 magick_info=(const MagickInfo *) NULL;
5113 if (info && (*info->image_info->magick != '\0'))
5114 magick_info=GetMagickInfo(info->image_info->magick,exception);
5115 if (image != (Image *) NULL)
5116 magick_info=GetMagickInfo(image->magick,exception);
5117 if ((magick_info != (const MagickInfo *) NULL) &&
5118 (*magick_info->description != '\0'))
5119 s=newSVpv((char *) magick_info->description,0);
5120 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5121 continue;
5122 }
5123 if (LocaleCompare(attribute,"fuzz") == 0)
5124 {
5125 if (info)
5126 s=newSVnv(info->image_info->fuzz);
5127 if (image != (Image *) NULL)
5128 s=newSVnv(image->fuzz);
5129 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5130 continue;
5131 }
5132 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5133 attribute);
5134 break;
5135 }
5136 case 'G':
5137 case 'g':
5138 {
5139 if (LocaleCompare(attribute,"gamma") == 0)
5140 {
5141 if (image != (Image *) NULL)
5142 s=newSVnv(image->gamma);
5143 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5144 continue;
5145 }
5146 if (LocaleCompare(attribute,"geometry") == 0)
5147 {
5148 if (image && image->geometry)
5149 s=newSVpv(image->geometry,0);
5150 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5151 continue;
5152 }
5153 if (LocaleCompare(attribute,"gravity") == 0)
5154 {
5155 s=image ? newSViv(image->gravity) : newSViv(0);
5156 (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
5157 image->gravity));
5158 SvIOK_on(s);
5159 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5160 continue;
5161 }
5162 if (LocaleCompare(attribute,"green-primary") == 0)
5163 {
5164 if (image == (Image *) NULL)
5165 break;
Cristyb1710fe2017-02-11 13:51:48 -05005166 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005167 image->chromaticity.green_primary.x,
5168 image->chromaticity.green_primary.y);
5169 s=newSVpv(color,0);
5170 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5171 continue;
5172 }
5173 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5174 attribute);
5175 break;
5176 }
5177 case 'H':
5178 case 'h':
5179 {
5180 if (LocaleCompare(attribute,"height") == 0)
5181 {
5182 if (image != (Image *) NULL)
5183 s=newSViv((ssize_t) image->rows);
5184 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5185 continue;
5186 }
5187 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5188 attribute);
5189 break;
5190 }
5191 case 'I':
5192 case 'i':
5193 {
5194 if (LocaleCompare(attribute,"icc") == 0)
5195 {
5196 if (image != (Image *) NULL)
5197 {
5198 const StringInfo
5199 *profile;
5200
5201 profile=GetImageProfile(image,"icc");
5202 if (profile != (StringInfo *) NULL)
5203 s=newSVpv((const char *) GetStringInfoDatum(profile),
5204 GetStringInfoLength(profile));
5205 }
5206 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5207 continue;
5208 }
5209 if (LocaleCompare(attribute,"icm") == 0)
5210 {
5211 if (image != (Image *) NULL)
5212 {
5213 const StringInfo
5214 *profile;
5215
5216 profile=GetImageProfile(image,"icm");
5217 if (profile != (const StringInfo *) NULL)
5218 s=newSVpv((const char *) GetStringInfoDatum(profile),
5219 GetStringInfoLength(profile));
5220 }
5221 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5222 continue;
5223 }
5224 if (LocaleCompare(attribute,"id") == 0)
5225 {
5226 if (image != (Image *) NULL)
5227 {
5228 char
cristy151b66d2015-04-15 10:50:31 +00005229 key[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005230
5231 MagickBooleanType
5232 status;
5233
5234 static ssize_t
5235 id = 0;
5236
cristy151b66d2015-04-15 10:50:31 +00005237 (void) FormatLocaleString(key,MagickPathExtent,"%.20g\n",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00005238 id);
5239 status=SetImageRegistry(ImageRegistryType,key,image,
5240 exception);
5241 (void) status;
5242 s=newSViv(id++);
5243 }
5244 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5245 continue;
5246 }
5247 if (LocaleNCompare(attribute,"index",5) == 0)
5248 {
5249 char
cristy151b66d2015-04-15 10:50:31 +00005250 name[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005251
5252 int
5253 items;
5254
5255 long
5256 x,
5257 y;
5258
5259 register const Quantum
5260 *p;
5261
5262 CacheView
5263 *image_view;
5264
5265 if (image == (Image *) NULL)
5266 break;
5267 if (image->storage_class != PseudoClass)
5268 break;
5269 x=0;
5270 y=0;
5271 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5272 (void) items;
5273 image_view=AcquireVirtualCacheView(image,exception);
5274 p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5275 if (p != (const Quantum *) NULL)
5276 {
cristy151b66d2015-04-15 10:50:31 +00005277 (void) FormatLocaleString(name,MagickPathExtent,QuantumFormat,
cristy4a3ce0a2013-08-03 20:06:59 +00005278 GetPixelIndex(image,p));
5279 s=newSVpv(name,0);
5280 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5281 }
5282 image_view=DestroyCacheView(image_view);
5283 continue;
5284 }
5285 if (LocaleCompare(attribute,"iptc") == 0)
5286 {
5287 if (image != (Image *) NULL)
5288 {
5289 const StringInfo
5290 *profile;
5291
5292 profile=GetImageProfile(image,"iptc");
5293 if (profile != (const StringInfo *) NULL)
5294 s=newSVpv((const char *) GetStringInfoDatum(profile),
5295 GetStringInfoLength(profile));
5296 }
5297 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5298 continue;
5299 }
5300 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
5301 {
5302 if (image != (Image *) NULL)
5303 s=newSViv((ssize_t) image->iterations);
5304 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5305 continue;
5306 }
5307 if (LocaleCompare(attribute,"interlace") == 0)
5308 {
5309 j=info ? info->image_info->interlace : image ? image->interlace :
5310 UndefinedInterlace;
5311 s=newSViv(j);
5312 (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5313 j));
5314 SvIOK_on(s);
5315 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5316 continue;
5317 }
5318 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5319 attribute);
5320 break;
5321 }
5322 case 'L':
5323 case 'l':
5324 {
5325 if (LocaleCompare(attribute,"label") == 0)
5326 {
5327 const char
5328 *value;
5329
5330 if (image == (Image *) NULL)
5331 break;
Cristy935a4052017-03-31 17:45:37 -04005332 value=GetImageProperty(image,"Label",exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005333 if (value != (const char *) NULL)
5334 s=newSVpv(value,0);
5335 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5336 continue;
5337 }
5338 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
5339 {
5340 if (image != (Image *) NULL)
5341 s=newSViv((ssize_t) image->iterations);
5342 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5343 continue;
5344 }
5345 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5346 attribute);
5347 break;
5348 }
5349 case 'M':
5350 case 'm':
5351 {
5352 if (LocaleCompare(attribute,"magick") == 0)
5353 {
5354 if (info && *info->image_info->magick)
5355 s=newSVpv(info->image_info->magick,0);
5356 if (image != (Image *) NULL)
5357 s=newSVpv(image->magick,0);
5358 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5359 continue;
5360 }
5361 if (LocaleCompare(attribute,"map") == 0)
5362 {
5363 s=newSViv(GetMagickResource(MapResource));
5364 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5365 continue;
5366 }
5367 if (LocaleCompare(attribute,"maximum-error") == 0)
5368 {
5369 if (image != (Image *) NULL)
5370 s=newSVnv(image->error.normalized_maximum_error);
5371 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5372 continue;
5373 }
5374 if (LocaleCompare(attribute,"memory") == 0)
5375 {
5376 s=newSViv(GetMagickResource(MemoryResource));
5377 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5378 continue;
5379 }
5380 if (LocaleCompare(attribute,"mean-error") == 0)
5381 {
5382 if (image != (Image *) NULL)
5383 s=newSVnv(image->error.normalized_mean_error);
5384 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5385 continue;
5386 }
5387 if (LocaleCompare(attribute,"mime") == 0)
5388 {
5389 if (info && *info->image_info->magick)
5390 s=newSVpv(MagickToMime(info->image_info->magick),0);
5391 if (image != (Image *) NULL)
5392 s=newSVpv(MagickToMime(image->magick),0);
5393 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5394 continue;
5395 }
5396 if (LocaleCompare(attribute,"mattecolor") == 0)
5397 {
5398 if (image == (Image *) NULL)
5399 break;
cristy151b66d2015-04-15 10:50:31 +00005400 (void) FormatLocaleString(color,MagickPathExtent,
Cristy8645e042016-02-03 16:35:29 -05005401 "%.20g,%.20g,%.20g,%.20g",(double) image->alpha_color.red,
5402 (double) image->alpha_color.green,
5403 (double) image->alpha_color.blue,
5404 (double) image->alpha_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005405 s=newSVpv(color,0);
5406 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5407 continue;
5408 }
5409 if (LocaleCompare(attribute,"matte") == 0)
5410 {
5411 if (image != (Image *) NULL)
cristy17f11b02014-12-20 19:37:04 +00005412 s=newSViv((ssize_t) image->alpha_trait != UndefinedPixelTrait ?
cristy4a3ce0a2013-08-03 20:06:59 +00005413 1 : 0);
5414 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5415 continue;
5416 }
5417 if (LocaleCompare(attribute,"mime") == 0)
5418 {
5419 const char
5420 *magick;
5421
5422 magick=NULL;
5423 if (info && *info->image_info->magick)
5424 magick=info->image_info->magick;
5425 if (image != (Image *) NULL)
5426 magick=image->magick;
5427 if (magick)
5428 {
5429 char
5430 *mime;
5431
5432 mime=MagickToMime(magick);
5433 s=newSVpv(mime,0);
5434 mime=(char *) RelinquishMagickMemory(mime);
5435 }
5436 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5437 continue;
5438 }
5439 if (LocaleCompare(attribute,"monochrome") == 0)
5440 {
5441 if (image == (Image *) NULL)
5442 continue;
5443 j=info ? info->image_info->monochrome :
cristy932cb072015-04-13 20:06:25 +00005444 SetImageMonochrome(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005445 s=newSViv(j);
5446 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5447 continue;
5448 }
5449 if (LocaleCompare(attribute,"montage") == 0)
5450 {
5451 if (image && image->montage)
5452 s=newSVpv(image->montage,0);
5453 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5454 continue;
5455 }
5456 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5457 attribute);
5458 break;
5459 }
5460 case 'O':
5461 case 'o':
5462 {
5463 if (LocaleCompare(attribute,"orientation") == 0)
5464 {
5465 j=info ? info->image_info->orientation : image ?
5466 image->orientation : UndefinedOrientation;
5467 s=newSViv(j);
5468 (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5469 j));
5470 SvIOK_on(s);
5471 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5472 continue;
5473 }
5474 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5475 attribute);
5476 break;
5477 }
5478 case 'P':
5479 case 'p':
5480 {
5481 if (LocaleCompare(attribute,"page") == 0)
5482 {
5483 if (info && info->image_info->page)
5484 s=newSVpv(info->image_info->page,0);
5485 if (image != (Image *) NULL)
5486 {
5487 char
cristy151b66d2015-04-15 10:50:31 +00005488 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005489
cristy151b66d2015-04-15 10:50:31 +00005490 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00005491 "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5492 (double) image->page.height,(double) image->page.x,(double)
5493 image->page.y);
5494 s=newSVpv(geometry,0);
5495 }
5496 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5497 continue;
5498 }
5499 if (LocaleCompare(attribute,"page.x") == 0)
5500 {
5501 if (image != (Image *) NULL)
5502 s=newSViv((ssize_t) image->page.x);
5503 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5504 continue;
5505 }
5506 if (LocaleCompare(attribute,"page.y") == 0)
5507 {
5508 if (image != (Image *) NULL)
5509 s=newSViv((ssize_t) image->page.y);
5510 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5511 continue;
5512 }
5513 if (LocaleNCompare(attribute,"pixel",5) == 0)
5514 {
5515 char
cristy151b66d2015-04-15 10:50:31 +00005516 tuple[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005517
5518 int
5519 items;
5520
5521 long
5522 x,
5523 y;
5524
5525 register const Quantum
5526 *p;
5527
5528 if (image == (Image *) NULL)
5529 break;
5530 x=0;
5531 y=0;
5532 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5533 (void) items;
5534 p=GetVirtualPixels(image,x,y,1,1,exception);
5535 if (image->colorspace != CMYKColorspace)
cristy151b66d2015-04-15 10:50:31 +00005536 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005537 QuantumFormat "," QuantumFormat "," QuantumFormat,
5538 GetPixelRed(image,p),GetPixelGreen(image,p),
5539 GetPixelBlue(image,p),GetPixelAlpha(image,p));
5540 else
cristy151b66d2015-04-15 10:50:31 +00005541 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005542 QuantumFormat "," QuantumFormat "," QuantumFormat ","
5543 QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5544 GetPixelBlue(image,p),GetPixelBlack(image,p),
5545 GetPixelAlpha(image,p));
5546 s=newSVpv(tuple,0);
5547 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5548 continue;
5549 }
5550 if (LocaleCompare(attribute,"pointsize") == 0)
5551 {
5552 if (info)
5553 s=newSViv((ssize_t) info->image_info->pointsize);
5554 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5555 continue;
5556 }
cristy4a3ce0a2013-08-03 20:06:59 +00005557 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5558 attribute);
5559 break;
5560 }
5561 case 'Q':
5562 case 'q':
5563 {
5564 if (LocaleCompare(attribute,"quality") == 0)
5565 {
5566 if (info)
5567 s=newSViv((ssize_t) info->image_info->quality);
5568 if (image != (Image *) NULL)
5569 s=newSViv((ssize_t) image->quality);
5570 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5571 continue;
5572 }
5573 if (LocaleCompare(attribute,"quantum") == 0)
5574 {
5575 if (info)
5576 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5577 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5578 continue;
5579 }
5580 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5581 attribute);
5582 break;
5583 }
5584 case 'R':
5585 case 'r':
5586 {
5587 if (LocaleCompare(attribute,"rendering-intent") == 0)
5588 {
5589 s=newSViv(image->rendering_intent);
5590 (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5591 image->rendering_intent));
5592 SvIOK_on(s);
5593 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5594 continue;
5595 }
5596 if (LocaleCompare(attribute,"red-primary") == 0)
5597 {
5598 if (image == (Image *) NULL)
5599 break;
Cristyb1710fe2017-02-11 13:51:48 -05005600 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005601 image->chromaticity.red_primary.x,
5602 image->chromaticity.red_primary.y);
5603 s=newSVpv(color,0);
5604 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5605 continue;
5606 }
5607 if (LocaleCompare(attribute,"rows") == 0)
5608 {
5609 if (image != (Image *) NULL)
5610 s=newSViv((ssize_t) image->rows);
5611 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5612 continue;
5613 }
5614 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5615 attribute);
5616 break;
5617 }
5618 case 'S':
5619 case 's':
5620 {
5621 if (LocaleCompare(attribute,"sampling-factor") == 0)
5622 {
5623 if (info && info->image_info->sampling_factor)
5624 s=newSVpv(info->image_info->sampling_factor,0);
5625 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5626 continue;
5627 }
5628 if (LocaleCompare(attribute,"server") == 0) /* same as display */
5629 {
5630 if (info && info->image_info->server_name)
5631 s=newSVpv(info->image_info->server_name,0);
5632 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5633 continue;
5634 }
5635 if (LocaleCompare(attribute,"size") == 0)
5636 {
5637 if (info && info->image_info->size)
5638 s=newSVpv(info->image_info->size,0);
5639 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5640 continue;
5641 }
5642 if (LocaleCompare(attribute,"scene") == 0)
5643 {
5644 if (image != (Image *) NULL)
5645 s=newSViv((ssize_t) image->scene);
5646 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5647 continue;
5648 }
5649 if (LocaleCompare(attribute,"scenes") == 0)
5650 {
5651 if (image != (Image *) NULL)
5652 s=newSViv((ssize_t) info->image_info->number_scenes);
5653 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5654 continue;
5655 }
5656 if (LocaleCompare(attribute,"signature") == 0)
5657 {
5658 const char
5659 *value;
5660
5661 if (image == (Image *) NULL)
5662 break;
5663 (void) SignatureImage(image,exception);
5664 value=GetImageProperty(image,"Signature",exception);
5665 if (value != (const char *) NULL)
5666 s=newSVpv(value,0);
5667 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5668 continue;
5669 }
5670 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5671 attribute);
5672 break;
5673 }
5674 case 'T':
5675 case 't':
5676 {
5677 if (LocaleCompare(attribute,"taint") == 0)
5678 {
5679 if (image != (Image *) NULL)
5680 s=newSViv((ssize_t) IsTaintImage(image));
5681 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5682 continue;
5683 }
5684 if (LocaleCompare(attribute,"texture") == 0)
5685 {
5686 if (info && info->image_info->texture)
5687 s=newSVpv(info->image_info->texture,0);
5688 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5689 continue;
5690 }
5691 if (LocaleCompare(attribute,"total-ink-density") == 0)
5692 {
5693 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5694 if (image != (Image *) NULL)
5695 s=newSVnv(GetImageTotalInkDensity(image,exception));
5696 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5697 continue;
5698 }
5699 if (LocaleCompare(attribute,"transparent-color") == 0)
5700 {
5701 if (image == (Image *) NULL)
5702 break;
cristy151b66d2015-04-15 10:50:31 +00005703 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00005704 "%.20g,%.20g,%.20g,%.20g",(double) image->transparent_color.red,
5705 (double) image->transparent_color.green,
5706 (double) image->transparent_color.blue,
5707 (double) image->transparent_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005708 s=newSVpv(color,0);
5709 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5710 continue;
5711 }
5712 if (LocaleCompare(attribute,"type") == 0)
5713 {
5714 if (image == (Image *) NULL)
5715 break;
cristya26f54c2015-07-29 12:26:12 +00005716 j=(ssize_t) GetImageType(image);
cristy4a3ce0a2013-08-03 20:06:59 +00005717 s=newSViv(j);
5718 (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5719 SvIOK_on(s);
5720 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5721 continue;
5722 }
5723 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5724 attribute);
5725 break;
5726 }
5727 case 'U':
5728 case 'u':
5729 {
5730 if (LocaleCompare(attribute,"units") == 0)
5731 {
5732 j=info ? info->image_info->units : image ? image->units :
5733 UndefinedResolution;
5734 if (info && (info->image_info->units == UndefinedResolution))
5735 if (image)
5736 j=image->units;
5737 if (j == UndefinedResolution)
5738 s=newSVpv("undefined units",0);
5739 else
5740 if (j == PixelsPerInchResolution)
5741 s=newSVpv("pixels / inch",0);
5742 else
5743 s=newSVpv("pixels / centimeter",0);
5744 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5745 continue;
5746 }
5747 if (LocaleCompare(attribute,"user-time") == 0)
5748 {
5749 if (image != (Image *) NULL)
5750 s=newSVnv(GetUserTime(&image->timer));
5751 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5752 continue;
5753 }
5754 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5755 attribute);
5756 break;
5757 }
5758 case 'V':
5759 case 'v':
5760 {
5761 if (LocaleCompare(attribute,"verbose") == 0)
5762 {
5763 if (info)
5764 s=newSViv((ssize_t) info->image_info->verbose);
5765 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5766 continue;
5767 }
5768 if (LocaleCompare(attribute,"version") == 0)
5769 {
5770 s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5771 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5772 continue;
5773 }
cristy4a3ce0a2013-08-03 20:06:59 +00005774 if (LocaleCompare(attribute,"virtual-pixel") == 0)
5775 {
5776 if (image == (Image *) NULL)
5777 break;
5778 j=(ssize_t) GetImageVirtualPixelMethod(image);
5779 s=newSViv(j);
5780 (void) sv_setpv(s,CommandOptionToMnemonic(
5781 MagickVirtualPixelOptions,j));
5782 SvIOK_on(s);
5783 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5784 continue;
5785 }
5786 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5787 attribute);
5788 break;
5789 }
5790 case 'W':
5791 case 'w':
5792 {
5793 if (LocaleCompare(attribute,"white-point") == 0)
5794 {
5795 if (image == (Image *) NULL)
5796 break;
Cristyb1710fe2017-02-11 13:51:48 -05005797 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005798 image->chromaticity.white_point.x,
5799 image->chromaticity.white_point.y);
5800 s=newSVpv(color,0);
5801 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5802 continue;
5803 }
5804 if (LocaleCompare(attribute,"width") == 0)
5805 {
5806 if (image != (Image *) NULL)
5807 s=newSViv((ssize_t) image->columns);
5808 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5809 continue;
5810 }
5811 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5812 attribute);
5813 break;
5814 }
5815 case 'X':
5816 case 'x':
5817 {
Cristyc1f9f9f2016-01-05 08:19:28 -05005818 if (LocaleCompare(attribute,"xmp") == 0)
5819 {
5820 if (image != (Image *) NULL)
5821 {
5822 const StringInfo
5823 *profile;
5824
5825 profile=GetImageProfile(image,"xmp");
5826 if (profile != (StringInfo *) NULL)
5827 s=newSVpv((const char *) GetStringInfoDatum(profile),
5828 GetStringInfoLength(profile));
5829 }
5830 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5831 continue;
5832 }
cristy4a3ce0a2013-08-03 20:06:59 +00005833 if (LocaleCompare(attribute,"x-resolution") == 0)
5834 {
5835 if (image != (Image *) NULL)
5836 s=newSVnv(image->resolution.x);
5837 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5838 continue;
5839 }
5840 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5841 attribute);
5842 break;
5843 }
5844 case 'Y':
5845 case 'y':
5846 {
5847 if (LocaleCompare(attribute,"y-resolution") == 0)
5848 {
5849 if (image != (Image *) NULL)
5850 s=newSVnv(image->resolution.y);
5851 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5852 continue;
5853 }
5854 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5855 attribute);
5856 break;
5857 }
5858 default:
5859 break;
5860 }
5861 if (image == (Image *) NULL)
5862 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5863 attribute)
5864 else
5865 {
5866 value=GetImageProperty(image,attribute,exception);
5867 if (value != (const char *) NULL)
5868 {
5869 s=newSVpv(value,0);
5870 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5871 }
5872 else
5873 if (*attribute != '%')
5874 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5875 attribute)
5876 else
5877 {
5878 char
5879 *meta;
5880
5881 meta=InterpretImageProperties(info ? info->image_info :
5882 (ImageInfo *) NULL,image,attribute,exception);
5883 s=newSVpv(meta,0);
5884 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5885 meta=(char *) RelinquishMagickMemory(meta);
5886 }
5887 }
5888 }
5889 exception=DestroyExceptionInfo(exception);
5890 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5891 }
5892
5893#
5894###############################################################################
5895# #
5896# #
5897# #
5898# G e t A u t h e n t i c P i x e l s #
5899# #
5900# #
5901# #
5902###############################################################################
5903#
5904#
5905void *
5906GetAuthenticPixels(ref,...)
5907 Image::Magick ref = NO_INIT
5908 ALIAS:
5909 getauthenticpixels = 1
5910 GetImagePixels = 2
5911 getimagepixels = 3
5912 CODE:
5913 {
5914 char
5915 *attribute;
5916
5917 ExceptionInfo
5918 *exception;
5919
5920 Image
5921 *image;
5922
5923 RectangleInfo
5924 region;
5925
5926 ssize_t
5927 i;
5928
5929 struct PackageInfo
5930 *info;
5931
5932 SV
5933 *perl_exception,
5934 *reference;
5935
5936 void
5937 *blob = NULL;
5938
5939 PERL_UNUSED_VAR(ref);
5940 PERL_UNUSED_VAR(ix);
5941 exception=AcquireExceptionInfo();
5942 perl_exception=newSVpv("",0);
5943 if (sv_isobject(ST(0)) == 0)
5944 {
5945 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5946 PackageName);
5947 goto PerlException;
5948 }
5949 reference=SvRV(ST(0));
5950
5951 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5952 if (image == (Image *) NULL)
5953 {
5954 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5955 PackageName);
5956 goto PerlException;
5957 }
5958
5959 region.x=0;
5960 region.y=0;
5961 region.width=image->columns;
5962 region.height=1;
5963 if (items == 1)
5964 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5965 for (i=2; i < items; i+=2)
5966 {
5967 attribute=(char *) SvPV(ST(i-1),na);
5968 switch (*attribute)
5969 {
5970 case 'g':
5971 case 'G':
5972 {
5973 if (LocaleCompare(attribute,"geometry") == 0)
5974 {
5975 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5976 break;
5977 }
5978 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5979 attribute);
5980 break;
5981 }
5982 case 'H':
5983 case 'h':
5984 {
5985 if (LocaleCompare(attribute,"height") == 0)
5986 {
5987 region.height=SvIV(ST(i));
5988 continue;
5989 }
5990 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
5991 attribute);
5992 break;
5993 }
5994 case 'X':
5995 case 'x':
5996 {
5997 if (LocaleCompare(attribute,"x") == 0)
5998 {
5999 region.x=SvIV(ST(i));
6000 continue;
6001 }
6002 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6003 attribute);
6004 break;
6005 }
6006 case 'Y':
6007 case 'y':
6008 {
6009 if (LocaleCompare(attribute,"y") == 0)
6010 {
6011 region.y=SvIV(ST(i));
6012 continue;
6013 }
6014 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6015 attribute);
6016 break;
6017 }
6018 case 'W':
6019 case 'w':
6020 {
6021 if (LocaleCompare(attribute,"width") == 0)
6022 {
6023 region.width=SvIV(ST(i));
6024 continue;
6025 }
6026 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6027 attribute);
6028 break;
6029 }
6030 }
6031 }
6032 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
6033 region.height,exception);
6034 if (blob != (void *) NULL)
6035 goto PerlEnd;
6036
6037 PerlException:
6038 InheritPerlException(exception,perl_exception);
6039 exception=DestroyExceptionInfo(exception);
6040 SvREFCNT_dec(perl_exception); /* throw away all errors */
6041
6042 PerlEnd:
6043 RETVAL = blob;
6044 }
6045 OUTPUT:
6046 RETVAL
6047
6048#
6049###############################################################################
6050# #
6051# #
6052# #
6053# G e t V i r t u a l P i x e l s #
6054# #
6055# #
6056# #
6057###############################################################################
6058#
6059#
6060void *
6061GetVirtualPixels(ref,...)
6062 Image::Magick ref = NO_INIT
6063 ALIAS:
6064 getvirtualpixels = 1
6065 AcquireImagePixels = 2
6066 acquireimagepixels = 3
6067 CODE:
6068 {
6069 char
6070 *attribute;
6071
6072 const void
6073 *blob = NULL;
6074
6075 ExceptionInfo
6076 *exception;
6077
6078 Image
6079 *image;
6080
6081 RectangleInfo
6082 region;
6083
6084 ssize_t
6085 i;
6086
6087 struct PackageInfo
6088 *info;
6089
6090 SV
6091 *perl_exception,
6092 *reference;
6093
6094 PERL_UNUSED_VAR(ref);
6095 PERL_UNUSED_VAR(ix);
6096 exception=AcquireExceptionInfo();
6097 perl_exception=newSVpv("",0);
6098 if (sv_isobject(ST(0)) == 0)
6099 {
6100 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6101 PackageName);
6102 goto PerlException;
6103 }
6104 reference=SvRV(ST(0));
6105
6106 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6107 if (image == (Image *) NULL)
6108 {
6109 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6110 PackageName);
6111 goto PerlException;
6112 }
6113
6114 region.x=0;
6115 region.y=0;
6116 region.width=image->columns;
6117 region.height=1;
6118 if (items == 1)
6119 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6120 for (i=2; i < items; i+=2)
6121 {
6122 attribute=(char *) SvPV(ST(i-1),na);
6123 switch (*attribute)
6124 {
6125 case 'g':
6126 case 'G':
6127 {
6128 if (LocaleCompare(attribute,"geometry") == 0)
6129 {
6130 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6131 break;
6132 }
6133 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6134 attribute);
6135 break;
6136 }
6137 case 'H':
6138 case 'h':
6139 {
6140 if (LocaleCompare(attribute,"height") == 0)
6141 {
6142 region.height=SvIV(ST(i));
6143 continue;
6144 }
6145 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6146 attribute);
6147 break;
6148 }
6149 case 'X':
6150 case 'x':
6151 {
6152 if (LocaleCompare(attribute,"x") == 0)
6153 {
6154 region.x=SvIV(ST(i));
6155 continue;
6156 }
6157 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6158 attribute);
6159 break;
6160 }
6161 case 'Y':
6162 case 'y':
6163 {
6164 if (LocaleCompare(attribute,"y") == 0)
6165 {
6166 region.y=SvIV(ST(i));
6167 continue;
6168 }
6169 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6170 attribute);
6171 break;
6172 }
6173 case 'W':
6174 case 'w':
6175 {
6176 if (LocaleCompare(attribute,"width") == 0)
6177 {
6178 region.width=SvIV(ST(i));
6179 continue;
6180 }
6181 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6182 attribute);
6183 break;
6184 }
6185 }
6186 }
6187 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
6188 region.height,exception);
6189 if (blob != (void *) NULL)
6190 goto PerlEnd;
6191
6192 PerlException:
6193 InheritPerlException(exception,perl_exception);
6194 exception=DestroyExceptionInfo(exception);
6195 SvREFCNT_dec(perl_exception); /* throw away all errors */
6196
6197 PerlEnd:
6198 RETVAL = (void *) blob;
6199 }
6200 OUTPUT:
6201 RETVAL
6202
6203#
6204###############################################################################
6205# #
6206# #
6207# #
6208# G e t A u t h e n t i c M e t a c o n t e n t #
6209# #
6210# #
6211# #
6212###############################################################################
6213#
6214#
6215void *
6216GetAuthenticMetacontent(ref,...)
6217 Image::Magick ref = NO_INIT
6218 ALIAS:
6219 getauthenticmetacontent = 1
6220 GetMetacontent = 2
6221 getmetacontent = 3
6222 CODE:
6223 {
6224 ExceptionInfo
6225 *exception;
6226
6227 Image
6228 *image;
6229
6230 struct PackageInfo
6231 *info;
6232
6233 SV
6234 *perl_exception,
6235 *reference;
6236
6237 void
6238 *blob = NULL;
6239
6240 PERL_UNUSED_VAR(ref);
6241 PERL_UNUSED_VAR(ix);
6242 exception=AcquireExceptionInfo();
6243 perl_exception=newSVpv("",0);
6244 if (sv_isobject(ST(0)) == 0)
6245 {
6246 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6247 PackageName);
6248 goto PerlException;
6249 }
6250 reference=SvRV(ST(0));
6251
6252 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6253 if (image == (Image *) NULL)
6254 {
6255 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6256 PackageName);
6257 goto PerlException;
6258 }
6259
6260 blob=(void *) GetAuthenticMetacontent(image);
6261 if (blob != (void *) NULL)
6262 goto PerlEnd;
6263
6264 PerlException:
6265 InheritPerlException(exception,perl_exception);
6266 exception=DestroyExceptionInfo(exception);
6267 SvREFCNT_dec(perl_exception); /* throw away all errors */
6268
6269 PerlEnd:
6270 RETVAL = blob;
6271 }
6272 OUTPUT:
6273 RETVAL
6274
6275#
6276###############################################################################
6277# #
6278# #
6279# #
6280# G e t V i r t u a l M e t a c o n t e n t #
6281# #
6282# #
6283# #
6284###############################################################################
6285#
6286#
6287void *
6288GetVirtualMetacontent(ref,...)
6289 Image::Magick ref = NO_INIT
6290 ALIAS:
6291 getvirtualmetacontent = 1
6292 CODE:
6293 {
6294 ExceptionInfo
6295 *exception;
6296
6297 Image
6298 *image;
6299
6300 struct PackageInfo
6301 *info;
6302
6303 SV
6304 *perl_exception,
6305 *reference;
6306
6307 void
6308 *blob = NULL;
6309
6310 PERL_UNUSED_VAR(ref);
6311 PERL_UNUSED_VAR(ix);
6312 exception=AcquireExceptionInfo();
6313 perl_exception=newSVpv("",0);
6314 if (sv_isobject(ST(0)) == 0)
6315 {
6316 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6317 PackageName);
6318 goto PerlException;
6319 }
6320 reference=SvRV(ST(0));
6321
6322 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6323 if (image == (Image *) NULL)
6324 {
6325 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6326 PackageName);
6327 goto PerlException;
6328 }
6329
6330 blob=(void *) GetVirtualMetacontent(image);
6331 if (blob != (void *) NULL)
6332 goto PerlEnd;
6333
6334 PerlException:
6335 InheritPerlException(exception,perl_exception);
6336 exception=DestroyExceptionInfo(exception);
6337 SvREFCNT_dec(perl_exception); /* throw away all errors */
6338
6339 PerlEnd:
6340 RETVAL = blob;
6341 }
6342 OUTPUT:
6343 RETVAL
6344
6345#
6346###############################################################################
6347# #
6348# #
6349# #
6350# H i s t o g r a m #
6351# #
6352# #
6353# #
6354###############################################################################
6355#
6356#
6357void
6358Histogram(ref,...)
6359 Image::Magick ref=NO_INIT
6360 ALIAS:
6361 HistogramImage = 1
6362 histogram = 2
6363 histogramimage = 3
6364 PPCODE:
6365 {
6366 AV
6367 *av;
6368
6369 char
cristy151b66d2015-04-15 10:50:31 +00006370 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006371
6372 PixelInfo
6373 *histogram;
6374
6375 ExceptionInfo
6376 *exception;
6377
6378 Image
6379 *image;
6380
6381 register ssize_t
6382 i;
6383
6384 ssize_t
6385 count;
6386
6387 struct PackageInfo
6388 *info;
6389
6390 SV
6391 *perl_exception,
6392 *reference;
6393
6394 size_t
6395 number_colors;
6396
6397 PERL_UNUSED_VAR(ref);
6398 PERL_UNUSED_VAR(ix);
6399 exception=AcquireExceptionInfo();
6400 perl_exception=newSVpv("",0);
6401 av=NULL;
6402 if (sv_isobject(ST(0)) == 0)
6403 {
6404 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6405 PackageName);
6406 goto PerlException;
6407 }
6408 reference=SvRV(ST(0));
6409 av=newAV();
6410 SvREFCNT_dec(av);
6411 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6412 if (image == (Image *) NULL)
6413 {
6414 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6415 PackageName);
6416 goto PerlException;
6417 }
cristy4a3ce0a2013-08-03 20:06:59 +00006418 count=0;
6419 for ( ; image; image=image->next)
6420 {
6421 histogram=GetImageHistogram(image,&number_colors,exception);
6422 if (histogram == (PixelInfo *) NULL)
6423 continue;
6424 count+=(ssize_t) number_colors;
6425 EXTEND(sp,6*count);
6426 for (i=0; i < (ssize_t) number_colors; i++)
6427 {
cristy151b66d2015-04-15 10:50:31 +00006428 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006429 histogram[i].red);
6430 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006431 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006432 histogram[i].green);
6433 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006434 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006435 histogram[i].blue);
6436 PUSHs(sv_2mortal(newSVpv(message,0)));
6437 if (image->colorspace == CMYKColorspace)
6438 {
cristy151b66d2015-04-15 10:50:31 +00006439 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006440 histogram[i].black);
6441 PUSHs(sv_2mortal(newSVpv(message,0)));
6442 }
cristy151b66d2015-04-15 10:50:31 +00006443 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006444 histogram[i].alpha);
6445 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006446 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00006447 histogram[i].count);
6448 PUSHs(sv_2mortal(newSVpv(message,0)));
6449 }
6450 histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6451 }
6452
6453 PerlException:
6454 InheritPerlException(exception,perl_exception);
6455 exception=DestroyExceptionInfo(exception);
6456 SvREFCNT_dec(perl_exception);
6457 }
6458
6459#
6460###############################################################################
6461# #
6462# #
6463# #
6464# G e t P i x e l #
6465# #
6466# #
6467# #
6468###############################################################################
6469#
6470#
6471void
6472GetPixel(ref,...)
6473 Image::Magick ref=NO_INIT
6474 ALIAS:
6475 getpixel = 1
6476 getPixel = 2
6477 PPCODE:
6478 {
6479 AV
6480 *av;
6481
6482 char
6483 *attribute;
6484
6485 ExceptionInfo
6486 *exception;
6487
6488 Image
6489 *image;
6490
6491 MagickBooleanType
6492 normalize;
6493
6494 RectangleInfo
6495 region;
6496
6497 register const Quantum
6498 *p;
6499
6500 register ssize_t
6501 i;
6502
6503 ssize_t
6504 option;
6505
6506 struct PackageInfo
6507 *info;
6508
6509 SV
6510 *perl_exception,
6511 *reference; /* reference is the SV* of ref=SvIV(reference) */
6512
6513 PERL_UNUSED_VAR(ref);
6514 PERL_UNUSED_VAR(ix);
6515 exception=AcquireExceptionInfo();
6516 perl_exception=newSVpv("",0);
6517 reference=SvRV(ST(0));
6518 av=(AV *) reference;
6519 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6520 exception);
6521 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6522 if (image == (Image *) NULL)
6523 {
6524 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6525 PackageName);
6526 goto PerlException;
6527 }
6528 normalize=MagickTrue;
6529 region.x=0;
6530 region.y=0;
6531 region.width=image->columns;
6532 region.height=1;
6533 if (items == 1)
6534 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6535 for (i=2; i < items; i+=2)
6536 {
6537 attribute=(char *) SvPV(ST(i-1),na);
6538 switch (*attribute)
6539 {
6540 case 'C':
6541 case 'c':
6542 {
6543 if (LocaleCompare(attribute,"channel") == 0)
6544 {
6545 ssize_t
6546 option;
6547
6548 option=ParseChannelOption(SvPV(ST(i),na));
6549 if (option < 0)
6550 {
6551 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6552 SvPV(ST(i),na));
6553 return;
6554 }
cristybcd59342015-06-07 14:07:19 +00006555 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00006556 break;
6557 }
6558 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6559 attribute);
6560 break;
6561 }
6562 case 'g':
6563 case 'G':
6564 {
6565 if (LocaleCompare(attribute,"geometry") == 0)
6566 {
6567 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6568 break;
6569 }
6570 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6571 attribute);
6572 break;
6573 }
6574 case 'N':
6575 case 'n':
6576 {
6577 if (LocaleCompare(attribute,"normalize") == 0)
6578 {
6579 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6580 SvPV(ST(i),na));
6581 if (option < 0)
6582 {
6583 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6584 SvPV(ST(i),na));
6585 break;
6586 }
6587 normalize=option != 0 ? MagickTrue : MagickFalse;
6588 break;
6589 }
6590 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6591 attribute);
6592 break;
6593 }
6594 case 'x':
6595 case 'X':
6596 {
6597 if (LocaleCompare(attribute,"x") == 0)
6598 {
6599 region.x=SvIV(ST(i));
6600 break;
6601 }
6602 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6603 attribute);
6604 break;
6605 }
6606 case 'y':
6607 case 'Y':
6608 {
6609 if (LocaleCompare(attribute,"y") == 0)
6610 {
6611 region.y=SvIV(ST(i));
6612 break;
6613 }
6614 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6615 attribute);
6616 break;
6617 }
6618 default:
6619 {
6620 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6621 attribute);
6622 break;
6623 }
6624 }
6625 }
6626 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6627 if (p == (const Quantum *) NULL)
6628 PUSHs(&sv_undef);
6629 else
6630 {
6631 double
6632 scale;
6633
6634 scale=1.0;
6635 if (normalize != MagickFalse)
6636 scale=1.0/QuantumRange;
6637 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6638 PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6639 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6640 PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6641 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6642 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6643 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6644 (image->colorspace == CMYKColorspace))
6645 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6646 if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6647 PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6648 }
6649
6650 PerlException:
6651 InheritPerlException(exception,perl_exception);
6652 exception=DestroyExceptionInfo(exception);
6653 SvREFCNT_dec(perl_exception);
6654 }
6655
6656#
6657###############################################################################
6658# #
6659# #
6660# #
6661# G e t P i x e l s #
6662# #
6663# #
6664# #
6665###############################################################################
6666#
6667#
6668void
6669GetPixels(ref,...)
6670 Image::Magick ref=NO_INIT
6671 ALIAS:
6672 getpixels = 1
6673 getPixels = 2
6674 PPCODE:
6675 {
6676 AV
6677 *av;
6678
6679 char
6680 *attribute;
6681
6682 const char
6683 *map;
6684
6685 ExceptionInfo
6686 *exception;
6687
6688 Image
6689 *image;
6690
6691 MagickBooleanType
6692 normalize,
6693 status;
6694
6695 RectangleInfo
6696 region;
6697
6698 register ssize_t
6699 i;
6700
6701 ssize_t
6702 option;
6703
6704 struct PackageInfo
6705 *info;
6706
6707 SV
6708 *perl_exception,
6709 *reference; /* reference is the SV* of ref=SvIV(reference) */
6710
6711 PERL_UNUSED_VAR(ref);
6712 PERL_UNUSED_VAR(ix);
6713 exception=AcquireExceptionInfo();
6714 perl_exception=newSVpv("",0);
6715 reference=SvRV(ST(0));
6716 av=(AV *) reference;
6717 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6718 exception);
6719 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6720 if (image == (Image *) NULL)
6721 {
6722 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6723 PackageName);
6724 goto PerlException;
6725 }
6726 map="RGB";
cristy17f11b02014-12-20 19:37:04 +00006727 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006728 map="RGBA";
6729 if (image->colorspace == CMYKColorspace)
6730 {
6731 map="CMYK";
cristy17f11b02014-12-20 19:37:04 +00006732 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006733 map="CMYKA";
6734 }
6735 normalize=MagickFalse;
6736 region.x=0;
6737 region.y=0;
6738 region.width=image->columns;
6739 region.height=1;
6740 if (items == 1)
6741 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6742 for (i=2; i < items; i+=2)
6743 {
6744 attribute=(char *) SvPV(ST(i-1),na);
6745 switch (*attribute)
6746 {
6747 case 'g':
6748 case 'G':
6749 {
6750 if (LocaleCompare(attribute,"geometry") == 0)
6751 {
6752 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6753 break;
6754 }
6755 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6756 attribute);
6757 break;
6758 }
6759 case 'H':
6760 case 'h':
6761 {
6762 if (LocaleCompare(attribute,"height") == 0)
6763 {
6764 region.height=SvIV(ST(i));
6765 break;
6766 }
6767 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6768 attribute);
6769 break;
6770 }
6771 case 'M':
6772 case 'm':
6773 {
6774 if (LocaleCompare(attribute,"map") == 0)
6775 {
6776 map=SvPV(ST(i),na);
6777 break;
6778 }
6779 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6780 attribute);
6781 break;
6782 }
6783 case 'N':
6784 case 'n':
6785 {
6786 if (LocaleCompare(attribute,"normalize") == 0)
6787 {
6788 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6789 SvPV(ST(i),na));
6790 if (option < 0)
6791 {
6792 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6793 SvPV(ST(i),na));
6794 break;
6795 }
6796 normalize=option != 0 ? MagickTrue : MagickFalse;
6797 break;
6798 }
6799 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6800 attribute);
6801 break;
6802 }
6803 case 'W':
6804 case 'w':
6805 {
6806 if (LocaleCompare(attribute,"width") == 0)
6807 {
6808 region.width=SvIV(ST(i));
6809 break;
6810 }
6811 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6812 attribute);
6813 break;
6814 }
6815 case 'x':
6816 case 'X':
6817 {
6818 if (LocaleCompare(attribute,"x") == 0)
6819 {
6820 region.x=SvIV(ST(i));
6821 break;
6822 }
6823 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6824 attribute);
6825 break;
6826 }
6827 case 'y':
6828 case 'Y':
6829 {
6830 if (LocaleCompare(attribute,"y") == 0)
6831 {
6832 region.y=SvIV(ST(i));
6833 break;
6834 }
6835 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6836 attribute);
6837 break;
6838 }
6839 default:
6840 {
6841 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6842 attribute);
6843 break;
6844 }
6845 }
6846 }
6847 if (normalize != MagickFalse)
6848 {
6849 float
6850 *pixels;
6851
6852 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6853 region.height*sizeof(*pixels));
6854 if (pixels == (float *) NULL)
6855 {
6856 ThrowPerlException(exception,ResourceLimitError,
6857 "MemoryAllocationFailed",PackageName);
6858 goto PerlException;
6859 }
6860 status=ExportImagePixels(image,region.x,region.y,region.width,
6861 region.height,map,FloatPixel,pixels,exception);
6862 if (status == MagickFalse)
6863 PUSHs(&sv_undef);
6864 else
6865 {
6866 EXTEND(sp,strlen(map)*region.width*region.height);
6867 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6868 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6869 }
6870 pixels=(float *) RelinquishMagickMemory(pixels);
6871 }
6872 else
6873 {
6874 Quantum
6875 *pixels;
6876
6877 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6878 region.height*sizeof(*pixels));
6879 if (pixels == (Quantum *) NULL)
6880 {
6881 ThrowPerlException(exception,ResourceLimitError,
6882 "MemoryAllocationFailed",PackageName);
6883 goto PerlException;
6884 }
6885 status=ExportImagePixels(image,region.x,region.y,region.width,
6886 region.height,map,QuantumPixel,pixels,exception);
6887 if (status == MagickFalse)
6888 PUSHs(&sv_undef);
6889 else
6890 {
6891 EXTEND(sp,strlen(map)*region.width*region.height);
6892 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6893 PUSHs(sv_2mortal(newSViv(pixels[i])));
6894 }
6895 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6896 }
6897
6898 PerlException:
6899 InheritPerlException(exception,perl_exception);
6900 exception=DestroyExceptionInfo(exception);
6901 SvREFCNT_dec(perl_exception);
6902 }
6903
6904#
6905###############################################################################
6906# #
6907# #
6908# #
6909# I m a g e T o B l o b #
6910# #
6911# #
6912# #
6913###############################################################################
6914#
6915#
6916void
6917ImageToBlob(ref,...)
6918 Image::Magick ref=NO_INIT
6919 ALIAS:
6920 ImageToBlob = 1
6921 imagetoblob = 2
6922 toblob = 3
6923 blob = 4
6924 PPCODE:
6925 {
6926 char
cristy151b66d2015-04-15 10:50:31 +00006927 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006928
6929 ExceptionInfo
6930 *exception;
6931
6932 Image
6933 *image,
6934 *next;
6935
6936 register ssize_t
6937 i;
6938
6939 struct PackageInfo
6940 *info,
6941 *package_info;
6942
6943 size_t
6944 length;
6945
6946 ssize_t
6947 scene;
6948
6949 SV
6950 *perl_exception,
6951 *reference;
6952
6953 void
6954 *blob;
6955
6956 PERL_UNUSED_VAR(ref);
6957 PERL_UNUSED_VAR(ix);
6958 exception=AcquireExceptionInfo();
6959 perl_exception=newSVpv("",0);
6960 package_info=(struct PackageInfo *) NULL;
6961 if (sv_isobject(ST(0)) == 0)
6962 {
6963 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6964 PackageName);
6965 goto PerlException;
6966 }
6967 reference=SvRV(ST(0));
6968 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6969 if (image == (Image *) NULL)
6970 {
6971 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6972 PackageName);
6973 goto PerlException;
6974 }
6975 package_info=ClonePackageInfo(info,exception);
6976 for (i=2; i < items; i+=2)
6977 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6978 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00006979 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006980 scene=0;
6981 for (next=image; next; next=next->next)
6982 {
cristy151b66d2015-04-15 10:50:31 +00006983 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006984 next->scene=scene++;
6985 }
6986 SetImageInfo(package_info->image_info,(unsigned int)
6987 GetImageListLength(image),exception);
6988 EXTEND(sp,(ssize_t) GetImageListLength(image));
6989 for ( ; image; image=image->next)
6990 {
6991 length=0;
6992 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
6993 if (blob != (char *) NULL)
6994 {
6995 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
6996 blob=(unsigned char *) RelinquishMagickMemory(blob);
6997 }
6998 if (package_info->image_info->adjoin)
6999 break;
7000 }
7001
7002 PerlException:
7003 if (package_info != (struct PackageInfo *) NULL)
7004 DestroyPackageInfo(package_info);
7005 InheritPerlException(exception,perl_exception);
7006 exception=DestroyExceptionInfo(exception);
7007 SvREFCNT_dec(perl_exception); /* throw away all errors */
7008 }
7009
7010#
7011###############################################################################
7012# #
7013# #
7014# #
7015# L a y e r s #
7016# #
7017# #
7018# #
7019###############################################################################
7020#
7021#
7022void
7023Layers(ref,...)
7024 Image::Magick ref=NO_INIT
7025 ALIAS:
7026 Layers = 1
7027 layers = 2
7028 OptimizeImageLayers = 3
7029 optimizelayers = 4
7030 optimizeimagelayers = 5
7031 PPCODE:
7032 {
7033 AV
7034 *av;
7035
7036 char
7037 *attribute;
7038
7039 CompositeOperator
7040 compose;
7041
7042 ExceptionInfo
7043 *exception;
7044
7045 HV
7046 *hv;
7047
7048 Image
7049 *image,
7050 *layers;
7051
7052 LayerMethod
7053 method;
7054
7055 register ssize_t
7056 i;
7057
7058 ssize_t
7059 option,
7060 sp;
7061
7062 struct PackageInfo
7063 *info;
7064
7065 SV
7066 *av_reference,
7067 *perl_exception,
7068 *reference,
7069 *rv,
7070 *sv;
7071
7072 PERL_UNUSED_VAR(ref);
7073 PERL_UNUSED_VAR(ix);
7074 exception=AcquireExceptionInfo();
7075 perl_exception=newSVpv("",0);
7076 sv=NULL;
7077 if (sv_isobject(ST(0)) == 0)
7078 {
7079 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7080 PackageName);
7081 goto PerlException;
7082 }
7083 reference=SvRV(ST(0));
7084 hv=SvSTASH(reference);
7085 av=newAV();
7086 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
7087 SvREFCNT_dec(av);
7088 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
7089 if (image == (Image *) NULL)
7090 {
7091 ThrowPerlException(exception,OptionError,"NoImagesDefined",
7092 PackageName);
7093 goto PerlException;
7094 }
7095 compose=image->compose;
7096 method=OptimizeLayer;
7097 for (i=2; i < items; i+=2)
7098 {
7099 attribute=(char *) SvPV(ST(i-1),na);
7100 switch (*attribute)
7101 {
7102 case 'C':
7103 case 'c':
7104 {
7105 if (LocaleCompare(attribute,"compose") == 0)
7106 {
7107 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
7108 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
7109 if (sp < 0)
7110 {
7111 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7112 SvPV(ST(i),na));
7113 break;
7114 }
7115 compose=(CompositeOperator) sp;
7116 break;
7117 }
7118 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7119 attribute);
7120 break;
7121 }
7122 case 'M':
7123 case 'm':
7124 {
7125 if (LocaleCompare(attribute,"method") == 0)
7126 {
7127 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
7128 SvPV(ST(i),na));
7129 if (option < 0)
7130 {
7131 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7132 SvPV(ST(i),na));
7133 break;
7134 }
7135 method=(LayerMethod) option;
7136 break;
7137 }
7138 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7139 attribute);
7140 break;
7141 }
7142 default:
7143 {
7144 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7145 attribute);
7146 break;
7147 }
7148 }
7149 }
7150 layers=(Image *) NULL;
7151 switch (method)
7152 {
7153 case CompareAnyLayer:
7154 case CompareClearLayer:
7155 case CompareOverlayLayer:
7156 default:
7157 {
7158 layers=CompareImagesLayers(image,method,exception);
7159 break;
7160 }
7161 case MergeLayer:
7162 case FlattenLayer:
7163 case MosaicLayer:
7164 {
7165 layers=MergeImageLayers(image,method,exception);
7166 break;
7167 }
7168 case DisposeLayer:
7169 {
7170 layers=DisposeImages(image,exception);
7171 break;
7172 }
7173 case OptimizeImageLayer:
7174 {
7175 layers=OptimizeImageLayers(image,exception);
7176 break;
7177 }
7178 case OptimizePlusLayer:
7179 {
7180 layers=OptimizePlusImageLayers(image,exception);
7181 break;
7182 }
7183 case OptimizeTransLayer:
7184 {
7185 OptimizeImageTransparency(image,exception);
7186 break;
7187 }
7188 case RemoveDupsLayer:
7189 {
7190 RemoveDuplicateLayers(&image,exception);
7191 break;
7192 }
7193 case RemoveZeroLayer:
7194 {
7195 RemoveZeroDelayLayers(&image,exception);
7196 break;
7197 }
7198 case OptimizeLayer:
7199 {
7200 QuantizeInfo
7201 *quantize_info;
7202
7203 /*
7204 General Purpose, GIF Animation Optimizer.
7205 */
7206 layers=CoalesceImages(image,exception);
7207 if (layers == (Image *) NULL)
7208 break;
7209 image=layers;
7210 layers=OptimizeImageLayers(image,exception);
7211 if (layers == (Image *) NULL)
7212 break;
7213 image=DestroyImageList(image);
7214 image=layers;
7215 layers=(Image *) NULL;
7216 OptimizeImageTransparency(image,exception);
7217 quantize_info=AcquireQuantizeInfo(info->image_info);
7218 (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
7219 quantize_info=DestroyQuantizeInfo(quantize_info);
7220 break;
7221 }
7222 case CompositeLayer:
7223 {
7224 Image
7225 *source;
7226
7227 RectangleInfo
7228 geometry;
7229
7230 /*
7231 Split image sequence at the first 'NULL:' image.
7232 */
7233 source=image;
7234 while (source != (Image *) NULL)
7235 {
7236 source=GetNextImageInList(source);
7237 if ((source != (Image *) NULL) &&
7238 (LocaleCompare(source->magick,"NULL") == 0))
7239 break;
7240 }
7241 if (source != (Image *) NULL)
7242 {
7243 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7244 (GetNextImageInList(source) == (Image *) NULL))
7245 source=(Image *) NULL;
7246 else
7247 {
7248 /*
7249 Separate the two lists, junk the null: image.
7250 */
7251 source=SplitImageList(source->previous);
7252 DeleteImageFromList(&source);
7253 }
7254 }
7255 if (source == (Image *) NULL)
7256 {
7257 (void) ThrowMagickException(exception,GetMagickModule(),
7258 OptionError,"MissingNullSeparator","layers Composite");
7259 break;
7260 }
7261 /*
7262 Adjust offset with gravity and virtual canvas.
7263 */
7264 SetGeometry(image,&geometry);
7265 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7266 geometry.width=source->page.width != 0 ? source->page.width :
7267 source->columns;
7268 geometry.height=source->page.height != 0 ? source->page.height :
7269 source->rows;
7270 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7271 image->columns,image->page.height != 0 ? image->page.height :
7272 image->rows,image->gravity,&geometry);
7273 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7274 source=DestroyImageList(source);
7275 break;
7276 }
7277 }
7278 if (layers != (Image *) NULL)
7279 image=layers;
cristy83a28a02013-08-03 20:25:48 +00007280 else
7281 image=CloneImage(image,0,0,MagickTrue,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007282 if (image == (Image *) NULL)
7283 goto PerlException;
7284 for ( ; image; image=image->next)
7285 {
7286 AddImageToRegistry(sv,image);
7287 rv=newRV(sv);
7288 av_push(av,sv_bless(rv,hv));
7289 SvREFCNT_dec(sv);
7290 }
7291 exception=DestroyExceptionInfo(exception);
7292 ST(0)=av_reference;
7293 SvREFCNT_dec(perl_exception);
7294 XSRETURN(1);
7295
7296 PerlException:
7297 InheritPerlException(exception,perl_exception);
7298 exception=DestroyExceptionInfo(exception);
7299 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7300 SvPOK_on(perl_exception);
7301 ST(0)=sv_2mortal(perl_exception);
7302 XSRETURN(1);
7303 }
7304
7305#
7306###############################################################################
7307# #
7308# #
7309# #
7310# M a g i c k T o M i m e #
7311# #
7312# #
7313# #
7314###############################################################################
7315#
7316#
7317SV *
7318MagickToMime(ref,name)
7319 Image::Magick ref=NO_INIT
7320 char *name
7321 ALIAS:
7322 magicktomime = 1
7323 CODE:
7324 {
7325 char
7326 *mime;
7327
7328 PERL_UNUSED_VAR(ref);
7329 PERL_UNUSED_VAR(ix);
7330 mime=MagickToMime(name);
7331 RETVAL=newSVpv(mime,0);
7332 mime=(char *) RelinquishMagickMemory(mime);
7333 }
7334 OUTPUT:
7335 RETVAL
7336
7337#
7338###############################################################################
7339# #
7340# #
7341# #
7342# M o g r i f y #
7343# #
7344# #
7345# #
7346###############################################################################
7347#
7348#
7349void
7350Mogrify(ref,...)
7351 Image::Magick ref=NO_INIT
7352 ALIAS:
7353 Comment = 1
7354 CommentImage = 2
7355 Label = 3
7356 LabelImage = 4
7357 AddNoise = 5
7358 AddNoiseImage = 6
7359 Colorize = 7
7360 ColorizeImage = 8
7361 Border = 9
7362 BorderImage = 10
7363 Blur = 11
7364 BlurImage = 12
7365 Chop = 13
7366 ChopImage = 14
7367 Crop = 15
7368 CropImage = 16
7369 Despeckle = 17
7370 DespeckleImage = 18
7371 Edge = 19
7372 EdgeImage = 20
7373 Emboss = 21
7374 EmbossImage = 22
7375 Enhance = 23
7376 EnhanceImage = 24
7377 Flip = 25
7378 FlipImage = 26
7379 Flop = 27
7380 FlopImage = 28
7381 Frame = 29
7382 FrameImage = 30
7383 Implode = 31
7384 ImplodeImage = 32
7385 Magnify = 33
7386 MagnifyImage = 34
7387 MedianFilter = 35
7388 MedianConvolveImage = 36
7389 Minify = 37
7390 MinifyImage = 38
7391 OilPaint = 39
7392 OilPaintImage = 40
7393 ReduceNoise = 41
7394 ReduceNoiseImage = 42
7395 Roll = 43
7396 RollImage = 44
7397 Rotate = 45
7398 RotateImage = 46
7399 Sample = 47
7400 SampleImage = 48
7401 Scale = 49
7402 ScaleImage = 50
7403 Shade = 51
7404 ShadeImage = 52
7405 Sharpen = 53
7406 SharpenImage = 54
7407 Shear = 55
7408 ShearImage = 56
7409 Spread = 57
7410 SpreadImage = 58
7411 Swirl = 59
7412 SwirlImage = 60
7413 Resize = 61
7414 ResizeImage = 62
7415 Zoom = 63
7416 ZoomImage = 64
7417 Annotate = 65
7418 AnnotateImage = 66
7419 ColorFloodfill = 67
7420 ColorFloodfillImage= 68
7421 Composite = 69
7422 CompositeImage = 70
7423 Contrast = 71
7424 ContrastImage = 72
7425 CycleColormap = 73
7426 CycleColormapImage = 74
7427 Draw = 75
7428 DrawImage = 76
7429 Equalize = 77
7430 EqualizeImage = 78
7431 Gamma = 79
7432 GammaImage = 80
7433 Map = 81
7434 MapImage = 82
7435 MatteFloodfill = 83
7436 MatteFloodfillImage= 84
7437 Modulate = 85
7438 ModulateImage = 86
7439 Negate = 87
7440 NegateImage = 88
7441 Normalize = 89
7442 NormalizeImage = 90
7443 NumberColors = 91
7444 NumberColorsImage = 92
7445 Opaque = 93
7446 OpaqueImage = 94
7447 Quantize = 95
7448 QuantizeImage = 96
7449 Raise = 97
7450 RaiseImage = 98
7451 Segment = 99
7452 SegmentImage = 100
7453 Signature = 101
7454 SignatureImage = 102
7455 Solarize = 103
7456 SolarizeImage = 104
7457 Sync = 105
7458 SyncImage = 106
7459 Texture = 107
7460 TextureImage = 108
7461 Evaluate = 109
7462 EvaluateImage = 110
7463 Transparent = 111
7464 TransparentImage = 112
7465 Threshold = 113
7466 ThresholdImage = 114
7467 Charcoal = 115
7468 CharcoalImage = 116
7469 Trim = 117
7470 TrimImage = 118
7471 Wave = 119
7472 WaveImage = 120
7473 Separate = 121
7474 SeparateImage = 122
7475 Stereo = 125
7476 StereoImage = 126
7477 Stegano = 127
7478 SteganoImage = 128
7479 Deconstruct = 129
7480 DeconstructImage = 130
7481 GaussianBlur = 131
7482 GaussianBlurImage = 132
7483 Convolve = 133
7484 ConvolveImage = 134
7485 Profile = 135
7486 ProfileImage = 136
7487 UnsharpMask = 137
7488 UnsharpMaskImage = 138
7489 MotionBlur = 139
7490 MotionBlurImage = 140
7491 OrderedDither = 141
7492 OrderedDitherImage = 142
7493 Shave = 143
7494 ShaveImage = 144
7495 Level = 145
7496 LevelImage = 146
7497 Clip = 147
7498 ClipImage = 148
7499 AffineTransform = 149
7500 AffineTransformImage = 150
7501 Difference = 151
7502 DifferenceImage = 152
7503 AdaptiveThreshold = 153
7504 AdaptiveThresholdImage = 154
7505 Resample = 155
7506 ResampleImage = 156
7507 Describe = 157
7508 DescribeImage = 158
7509 BlackThreshold = 159
7510 BlackThresholdImage= 160
7511 WhiteThreshold = 161
7512 WhiteThresholdImage= 162
cristy60c73c02014-03-25 12:09:58 +00007513 RotationalBlur = 163
7514 RotationalBlurImage= 164
cristy4a3ce0a2013-08-03 20:06:59 +00007515 Thumbnail = 165
7516 ThumbnailImage = 166
7517 Strip = 167
7518 StripImage = 168
7519 Tint = 169
7520 TintImage = 170
7521 Channel = 171
7522 ChannelImage = 172
7523 Splice = 173
7524 SpliceImage = 174
7525 Posterize = 175
7526 PosterizeImage = 176
7527 Shadow = 177
7528 ShadowImage = 178
7529 Identify = 179
7530 IdentifyImage = 180
7531 SepiaTone = 181
7532 SepiaToneImage = 182
7533 SigmoidalContrast = 183
7534 SigmoidalContrastImage = 184
7535 Extent = 185
7536 ExtentImage = 186
7537 Vignette = 187
7538 VignetteImage = 188
7539 ContrastStretch = 189
7540 ContrastStretchImage = 190
7541 Sans0 = 191
7542 Sans0Image = 192
7543 Sans1 = 193
7544 Sans1Image = 194
7545 AdaptiveSharpen = 195
7546 AdaptiveSharpenImage = 196
7547 Transpose = 197
7548 TransposeImage = 198
7549 Transverse = 199
7550 TransverseImage = 200
7551 AutoOrient = 201
7552 AutoOrientImage = 202
7553 AdaptiveBlur = 203
7554 AdaptiveBlurImage = 204
7555 Sketch = 205
7556 SketchImage = 206
7557 UniqueColors = 207
7558 UniqueColorsImage = 208
7559 AdaptiveResize = 209
7560 AdaptiveResizeImage= 210
7561 ClipMask = 211
7562 ClipMaskImage = 212
7563 LinearStretch = 213
7564 LinearStretchImage = 214
7565 ColorMatrix = 215
7566 ColorMatrixImage = 216
7567 Mask = 217
7568 MaskImage = 218
7569 Polaroid = 219
7570 PolaroidImage = 220
7571 FloodfillPaint = 221
7572 FloodfillPaintImage= 222
7573 Distort = 223
7574 DistortImage = 224
7575 Clut = 225
7576 ClutImage = 226
7577 LiquidRescale = 227
7578 LiquidRescaleImage = 228
7579 Encipher = 229
7580 EncipherImage = 230
7581 Decipher = 231
7582 DecipherImage = 232
7583 Deskew = 233
7584 DeskewImage = 234
7585 Remap = 235
7586 RemapImage = 236
7587 SparseColor = 237
7588 SparseColorImage = 238
7589 Function = 239
7590 FunctionImage = 240
7591 SelectiveBlur = 241
7592 SelectiveBlurImage = 242
7593 HaldClut = 243
7594 HaldClutImage = 244
7595 BlueShift = 245
7596 BlueShiftImage = 246
7597 ForwardFourierTransform = 247
7598 ForwardFourierTransformImage = 248
7599 InverseFourierTransform = 249
7600 InverseFourierTransformImage = 250
7601 ColorDecisionList = 251
7602 ColorDecisionListImage = 252
7603 AutoGamma = 253
7604 AutoGammaImage = 254
7605 AutoLevel = 255
7606 AutoLevelImage = 256
7607 LevelColors = 257
7608 LevelImageColors = 258
7609 Clamp = 259
7610 ClampImage = 260
7611 BrightnessContrast = 261
7612 BrightnessContrastImage = 262
7613 Morphology = 263
7614 MorphologyImage = 264
Cristy3ca633e2016-02-13 12:49:01 -05007615 Mode = 265
7616 ModeImage = 266
7617 Statistic = 267
7618 StatisticImage = 268
7619 Perceptible = 269
7620 PerceptibleImage = 270
7621 Poly = 271
7622 PolyImage = 272
7623 Grayscale = 273
7624 GrayscaleImage = 274
7625 CannyEdge = 275
7626 CannyEdgeImage = 276
7627 HoughLine = 277
7628 HoughLineImage = 278
7629 MeanShift = 279
7630 MeanShiftImage = 280
7631 Kuwahara = 281
7632 KuwaharaImage = 282
Cristy0f5df812017-07-04 18:30:05 -04007633 ConnectedComponents = 283
7634 ConnectedComponentsImage = 284
Cristy3ca633e2016-02-13 12:49:01 -05007635 CopyPixels = 285
7636 CopyImagePixels = 286
Cristy5488c982016-02-13 14:07:50 -05007637 Color = 287
7638 ColorImage = 288
Cristy2d830ed2016-02-21 10:54:16 -05007639 WaveletDenoise = 289
7640 WaveletDenoiseImage= 290
Cristy99a57162016-12-05 11:47:57 -05007641 Colorspace = 291
7642 ColorspaceImage = 292
Cristy53353872017-07-02 12:24:24 -04007643 AutoThreshold = 293
7644 AutoThresholdImage = 294
Cristy532b3382018-08-05 17:56:56 -04007645 RangeThreshold = 295
7646 RangeThresholdImage= 296
Cristy9f252542018-11-21 19:13:46 -05007647 CLAHE = 297
7648 CLAHEImage = 298
cristy4a3ce0a2013-08-03 20:06:59 +00007649 MogrifyRegion = 666
7650 PPCODE:
7651 {
7652 AffineMatrix
7653 affine,
7654 current;
7655
7656 char
7657 attribute_flag[MaxArguments],
cristy151b66d2015-04-15 10:50:31 +00007658 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00007659
7660 ChannelType
7661 channel,
7662 channel_mask;
7663
7664 CompositeOperator
7665 compose;
7666
7667 const char
7668 *attribute,
7669 *value;
7670
7671 double
7672 angle;
7673
7674 ExceptionInfo
7675 *exception;
7676
7677 GeometryInfo
7678 geometry_info;
7679
7680 Image
7681 *image,
Cristy7e567962018-02-03 12:42:20 -05007682 *next;
cristy4a3ce0a2013-08-03 20:06:59 +00007683
cristy4a3ce0a2013-08-03 20:06:59 +00007684 MagickStatusType
7685 flags;
7686
7687 PixelInfo
7688 fill_color;
7689
7690 RectangleInfo
7691 geometry,
7692 region_info;
7693
7694 register ssize_t
7695 i;
7696
7697 ssize_t
7698 base,
7699 j,
7700 number_images;
7701
7702 struct Methods
7703 *rp;
7704
7705 struct PackageInfo
7706 *info;
7707
7708 SV
7709 *perl_exception,
7710 **pv,
7711 *reference,
7712 **reference_vector;
7713
7714 struct ArgumentList
7715 argument_list[MaxArguments];
7716
7717 PERL_UNUSED_VAR(ref);
7718 PERL_UNUSED_VAR(ix);
7719 exception=AcquireExceptionInfo();
7720 perl_exception=newSVpv("",0);
7721 reference_vector=NULL;
cristy4a3ce0a2013-08-03 20:06:59 +00007722 number_images=0;
7723 base=2;
7724 if (sv_isobject(ST(0)) == 0)
7725 {
7726 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7727 PackageName);
7728 goto PerlException;
7729 }
7730 reference=SvRV(ST(0));
7731 region_info.width=0;
7732 region_info.height=0;
7733 region_info.x=0;
7734 region_info.y=0;
cristy4a3ce0a2013-08-03 20:06:59 +00007735 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7736 if (ix && (ix != 666))
7737 {
7738 /*
7739 Called as Method(...)
7740 */
7741 ix=(ix+1)/2;
7742 rp=(&Methods[ix-1]);
7743 attribute=rp->name;
7744 }
7745 else
7746 {
7747 /*
7748 Called as Mogrify("Method",...)
7749 */
7750 attribute=(char *) SvPV(ST(1),na);
7751 if (ix)
7752 {
7753 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
7754 attribute=(char *) SvPV(ST(2),na);
7755 base++;
7756 }
7757 for (rp=Methods; ; rp++)
7758 {
7759 if (rp >= EndOf(Methods))
7760 {
7761 ThrowPerlException(exception,OptionError,
7762 "UnrecognizedPerlMagickMethod",attribute);
7763 goto PerlException;
7764 }
7765 if (strEQcase(attribute,rp->name))
7766 break;
7767 }
7768 ix=rp-Methods+1;
7769 base++;
7770 }
7771 if (image == (Image *) NULL)
7772 {
7773 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7774 goto PerlException;
7775 }
7776 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7777 Zero(&attribute_flag,NumberOf(attribute_flag),char);
7778 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7779 {
7780 Arguments
7781 *pp,
7782 *qq;
7783
7784 ssize_t
7785 ssize_test;
7786
7787 struct ArgumentList
7788 *al;
7789
7790 SV
7791 *sv;
7792
7793 sv=NULL;
7794 ssize_test=0;
7795 pp=(Arguments *) NULL;
7796 qq=rp->arguments;
7797 if (i == items)
7798 {
7799 pp=rp->arguments,
7800 sv=ST(i-1);
7801 }
7802 else
7803 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7804 {
7805 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7806 break;
7807 if (strEQcase(attribute,qq->method) > ssize_test)
7808 {
7809 pp=qq;
7810 ssize_test=strEQcase(attribute,qq->method);
7811 }
7812 }
7813 if (pp == (Arguments *) NULL)
7814 {
7815 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7816 attribute);
7817 goto continue_outer_loop;
7818 }
7819 al=(&argument_list[pp-rp->arguments]);
7820 switch (pp->type)
7821 {
7822 case ArrayReference:
7823 {
7824 if (SvTYPE(sv) != SVt_RV)
7825 {
cristy151b66d2015-04-15 10:50:31 +00007826 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007827 "invalid %.60s value",pp->method);
7828 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7829 goto continue_outer_loop;
7830 }
7831 al->array_reference=SvRV(sv);
7832 break;
7833 }
7834 case RealReference:
7835 {
7836 al->real_reference=SvNV(sv);
7837 break;
7838 }
7839 case FileReference:
7840 {
7841 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7842 break;
7843 }
7844 case ImageReference:
7845 {
7846 if (!sv_isobject(sv) ||
7847 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7848 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7849 {
7850 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7851 PackageName);
7852 goto PerlException;
7853 }
7854 break;
7855 }
7856 case IntegerReference:
7857 {
7858 al->integer_reference=SvIV(sv);
7859 break;
7860 }
7861 case StringReference:
7862 {
7863 al->string_reference=(char *) SvPV(sv,al->length);
7864 if (sv_isobject(sv))
7865 al->image_reference=SetupList(aTHX_ SvRV(sv),
7866 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7867 break;
7868 }
7869 default:
7870 {
7871 /*
7872 Is a string; look up name.
7873 */
7874 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7875 {
7876 al->string_reference=(char *) SvPV(sv,al->length);
7877 al->integer_reference=(-1);
7878 break;
7879 }
7880 al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7881 MagickFalse,SvPV(sv,na));
7882 if (pp->type == MagickChannelOptions)
7883 al->integer_reference=ParseChannelOption(SvPV(sv,na));
7884 if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7885 {
cristy151b66d2015-04-15 10:50:31 +00007886 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007887 "invalid %.60s value",pp->method);
7888 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7889 goto continue_outer_loop;
7890 }
7891 break;
7892 }
7893 }
7894 attribute_flag[pp-rp->arguments]++;
7895 continue_outer_loop: ;
7896 }
7897 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7898 pv=reference_vector;
7899 SetGeometryInfo(&geometry_info);
7900 channel=DefaultChannels;
7901 for (next=image; next; next=next->next)
7902 {
7903 image=next;
7904 SetGeometry(image,&geometry);
7905 if ((region_info.width*region_info.height) != 0)
Cristy7e567962018-02-03 12:42:20 -05007906 (void) SetImageRegionMask(image,WritePixelMask,&region_info,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007907 switch (ix)
7908 {
7909 default:
7910 {
cristy151b66d2015-04-15 10:50:31 +00007911 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double) ix);
cristy4a3ce0a2013-08-03 20:06:59 +00007912 ThrowPerlException(exception,OptionError,
7913 "UnrecognizedPerlMagickMethod",message);
7914 goto PerlException;
7915 }
7916 case 1: /* Comment */
7917 {
7918 if (attribute_flag[0] == 0)
7919 argument_list[0].string_reference=(char *) NULL;
Cristy935a4052017-03-31 17:45:37 -04007920 (void) SetImageProperty(image,"comment",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00007921 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04007922 argument_list[0].string_reference,exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007923 break;
7924 }
7925 case 2: /* Label */
7926 {
7927 if (attribute_flag[0] == 0)
7928 argument_list[0].string_reference=(char *) NULL;
Cristy935a4052017-03-31 17:45:37 -04007929 (void) SetImageProperty(image,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00007930 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04007931 argument_list[0].string_reference,exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007932 break;
7933 }
7934 case 3: /* AddNoise */
7935 {
7936 double
7937 attenuate;
7938
7939 if (attribute_flag[0] == 0)
7940 argument_list[0].integer_reference=UniformNoise;
7941 attenuate=1.0;
7942 if (attribute_flag[1] != 0)
7943 attenuate=argument_list[1].real_reference;
7944 if (attribute_flag[2] != 0)
7945 channel=(ChannelType) argument_list[2].integer_reference;
7946 channel_mask=SetImageChannelMask(image,channel);
7947 image=AddNoiseImage(image,(NoiseType)
7948 argument_list[0].integer_reference,attenuate,exception);
7949 if (image != (Image *) NULL)
7950 (void) SetImageChannelMask(image,channel_mask);
7951 break;
7952 }
7953 case 4: /* Colorize */
7954 {
7955 PixelInfo
7956 target;
7957
7958 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7959 0,0,&target,exception);
7960 if (attribute_flag[0] != 0)
7961 (void) QueryColorCompliance(argument_list[0].string_reference,
7962 AllCompliance,&target,exception);
7963 if (attribute_flag[1] == 0)
7964 argument_list[1].string_reference="100%";
7965 image=ColorizeImage(image,argument_list[1].string_reference,&target,
7966 exception);
7967 break;
7968 }
7969 case 5: /* Border */
7970 {
7971 CompositeOperator
7972 compose;
7973
7974 geometry.width=0;
7975 geometry.height=0;
7976 if (attribute_flag[0] != 0)
7977 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7978 &geometry,exception);
7979 if (attribute_flag[1] != 0)
7980 geometry.width=argument_list[1].integer_reference;
7981 if (attribute_flag[2] != 0)
7982 geometry.height=argument_list[2].integer_reference;
7983 if (attribute_flag[3] != 0)
7984 QueryColorCompliance(argument_list[3].string_reference,
7985 AllCompliance,&image->border_color,exception);
7986 if (attribute_flag[4] != 0)
7987 QueryColorCompliance(argument_list[4].string_reference,
7988 AllCompliance,&image->border_color,exception);
7989 if (attribute_flag[5] != 0)
7990 QueryColorCompliance(argument_list[5].string_reference,
7991 AllCompliance,&image->border_color,exception);
7992 compose=image->compose;
7993 if (attribute_flag[6] != 0)
7994 compose=(CompositeOperator) argument_list[6].integer_reference;
7995 image=BorderImage(image,&geometry,compose,exception);
7996 break;
7997 }
7998 case 6: /* Blur */
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 if (attribute_flag[3] != 0)
8012 channel=(ChannelType) argument_list[3].integer_reference;
8013 channel_mask=SetImageChannelMask(image,channel);
8014 image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
8015 exception);
8016 if (image != (Image *) NULL)
8017 (void) SetImageChannelMask(image,channel_mask);
8018 break;
8019 }
8020 case 7: /* Chop */
8021 {
cristy260bd762014-08-15 12:46:34 +00008022 if (attribute_flag[5] != 0)
8023 image->gravity=(GravityType) argument_list[5].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00008024 if (attribute_flag[0] != 0)
8025 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
8026 &geometry,exception);
8027 if (attribute_flag[1] != 0)
8028 geometry.width=argument_list[1].integer_reference;
8029 if (attribute_flag[2] != 0)
8030 geometry.height=argument_list[2].integer_reference;
8031 if (attribute_flag[3] != 0)
8032 geometry.x=argument_list[3].integer_reference;
8033 if (attribute_flag[4] != 0)
8034 geometry.y=argument_list[4].integer_reference;
8035 image=ChopImage(image,&geometry,exception);
8036 break;
8037 }
8038 case 8: /* Crop */
8039 {
8040 if (attribute_flag[6] != 0)
8041 image->gravity=(GravityType) argument_list[6].integer_reference;
8042 if (attribute_flag[0] != 0)
8043 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
8044 &geometry,exception);
8045 if (attribute_flag[1] != 0)
8046 geometry.width=argument_list[1].integer_reference;
8047 if (attribute_flag[2] != 0)
8048 geometry.height=argument_list[2].integer_reference;
8049 if (attribute_flag[3] != 0)
8050 geometry.x=argument_list[3].integer_reference;
8051 if (attribute_flag[4] != 0)
8052 geometry.y=argument_list[4].integer_reference;
8053 if (attribute_flag[5] != 0)
8054 image->fuzz=StringToDoubleInterval(
8055 argument_list[5].string_reference,(double) QuantumRange+1.0);
8056 image=CropImage(image,&geometry,exception);
8057 break;
8058 }
8059 case 9: /* Despeckle */
8060 {
8061 image=DespeckleImage(image,exception);
8062 break;
8063 }
8064 case 10: /* Edge */
8065 {
8066 if (attribute_flag[0] != 0)
8067 geometry_info.rho=argument_list[0].real_reference;
8068 image=EdgeImage(image,geometry_info.rho,exception);
8069 break;
8070 }
8071 case 11: /* Emboss */
8072 {
8073 if (attribute_flag[0] != 0)
8074 {
8075 flags=ParseGeometry(argument_list[0].string_reference,
8076 &geometry_info);
8077 if ((flags & SigmaValue) == 0)
8078 geometry_info.sigma=1.0;
8079 }
8080 if (attribute_flag[1] != 0)
8081 geometry_info.rho=argument_list[1].real_reference;
8082 if (attribute_flag[2] != 0)
8083 geometry_info.sigma=argument_list[2].real_reference;
8084 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
8085 exception);
8086 break;
8087 }
8088 case 12: /* Enhance */
8089 {
8090 image=EnhanceImage(image,exception);
8091 break;
8092 }
8093 case 13: /* Flip */
8094 {
8095 image=FlipImage(image,exception);
8096 break;
8097 }
8098 case 14: /* Flop */
8099 {
8100 image=FlopImage(image,exception);
8101 break;
8102 }
8103 case 15: /* Frame */
8104 {
8105 CompositeOperator
8106 compose;
8107
8108 FrameInfo
8109 frame_info;
8110
8111 if (attribute_flag[0] != 0)
8112 {
8113 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8114 &geometry,exception);
8115 frame_info.width=geometry.width;
8116 frame_info.height=geometry.height;
8117 frame_info.outer_bevel=geometry.x;
8118 frame_info.inner_bevel=geometry.y;
8119 }
8120 if (attribute_flag[1] != 0)
8121 frame_info.width=argument_list[1].integer_reference;
8122 if (attribute_flag[2] != 0)
8123 frame_info.height=argument_list[2].integer_reference;
8124 if (attribute_flag[3] != 0)
8125 frame_info.inner_bevel=argument_list[3].integer_reference;
8126 if (attribute_flag[4] != 0)
8127 frame_info.outer_bevel=argument_list[4].integer_reference;
8128 if (attribute_flag[5] != 0)
8129 QueryColorCompliance(argument_list[5].string_reference,
8130 AllCompliance,&fill_color,exception);
8131 if (attribute_flag[6] != 0)
8132 QueryColorCompliance(argument_list[6].string_reference,
8133 AllCompliance,&fill_color,exception);
8134 frame_info.x=(ssize_t) frame_info.width;
8135 frame_info.y=(ssize_t) frame_info.height;
8136 frame_info.width=image->columns+2*frame_info.x;
8137 frame_info.height=image->rows+2*frame_info.y;
8138 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
Cristy8645e042016-02-03 16:35:29 -05008139 image->alpha_color=fill_color;
cristy4a3ce0a2013-08-03 20:06:59 +00008140 compose=image->compose;
8141 if (attribute_flag[7] != 0)
8142 compose=(CompositeOperator) argument_list[7].integer_reference;
8143 image=FrameImage(image,&frame_info,compose,exception);
8144 break;
8145 }
8146 case 16: /* Implode */
8147 {
8148 PixelInterpolateMethod
8149 method;
8150
8151 if (attribute_flag[0] == 0)
8152 argument_list[0].real_reference=0.5;
8153 method=UndefinedInterpolatePixel;
8154 if (attribute_flag[1] != 0)
8155 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8156 image=ImplodeImage(image,argument_list[0].real_reference,
8157 method,exception);
8158 break;
8159 }
8160 case 17: /* Magnify */
8161 {
8162 image=MagnifyImage(image,exception);
8163 break;
8164 }
8165 case 18: /* MedianFilter */
8166 {
8167 if (attribute_flag[0] != 0)
8168 {
8169 flags=ParseGeometry(argument_list[0].string_reference,
8170 &geometry_info);
8171 if ((flags & SigmaValue) == 0)
8172 geometry_info.sigma=geometry_info.rho;
8173 }
8174 if (attribute_flag[1] != 0)
8175 geometry_info.rho=argument_list[1].real_reference;
8176 if (attribute_flag[2] != 0)
8177 geometry_info.sigma=argument_list[2].real_reference;
8178 if (attribute_flag[3] != 0)
8179 channel=(ChannelType) argument_list[3].integer_reference;
8180 channel_mask=SetImageChannelMask(image,channel);
8181 image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
8182 (size_t) geometry_info.sigma,exception);
8183 if (image != (Image *) NULL)
8184 (void) SetImageChannelMask(image,channel_mask);
8185 break;
8186 }
8187 case 19: /* Minify */
8188 {
8189 image=MinifyImage(image,exception);
8190 break;
8191 }
8192 case 20: /* OilPaint */
8193 {
8194 if (attribute_flag[0] == 0)
8195 argument_list[0].real_reference=0.0;
8196 if (attribute_flag[1] == 0)
8197 argument_list[1].real_reference=1.0;
8198 image=OilPaintImage(image,argument_list[0].real_reference,
8199 argument_list[1].real_reference,exception);
8200 break;
8201 }
8202 case 21: /* ReduceNoise */
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=1.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 if (attribute_flag[3] != 0)
8216 channel=(ChannelType) argument_list[3].integer_reference;
8217 channel_mask=SetImageChannelMask(image,channel);
8218 image=StatisticImage(image,NonpeakStatistic,(size_t)
8219 geometry_info.rho,(size_t) geometry_info.sigma,exception);
8220 if (image != (Image *) NULL)
8221 (void) SetImageChannelMask(image,channel_mask);
8222 break;
8223 }
8224 case 22: /* Roll */
8225 {
8226 if (attribute_flag[0] != 0)
Cristyf94b0842017-07-14 07:05:02 -04008227 {
8228 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8229 &geometry,exception);
8230 if ((flags & PercentValue) != 0)
8231 {
8232 geometry.x*=(double) image->columns/100.0;
8233 geometry.y*=(double) image->rows/100.0;
8234 }
8235 }
cristy4a3ce0a2013-08-03 20:06:59 +00008236 if (attribute_flag[1] != 0)
8237 geometry.x=argument_list[1].integer_reference;
8238 if (attribute_flag[2] != 0)
8239 geometry.y=argument_list[2].integer_reference;
8240 image=RollImage(image,geometry.x,geometry.y,exception);
8241 break;
8242 }
8243 case 23: /* Rotate */
8244 {
8245 if (attribute_flag[0] == 0)
8246 argument_list[0].real_reference=90.0;
8247 if (attribute_flag[1] != 0)
8248 {
8249 QueryColorCompliance(argument_list[1].string_reference,
8250 AllCompliance,&image->background_color,exception);
cristy17f11b02014-12-20 19:37:04 +00008251 if ((image->background_color.alpha_trait != UndefinedPixelTrait) &&
8252 (image->alpha_trait == UndefinedPixelTrait))
cristy4a3ce0a2013-08-03 20:06:59 +00008253 (void) SetImageAlpha(image,OpaqueAlpha,exception);
8254 }
8255 image=RotateImage(image,argument_list[0].real_reference,exception);
8256 break;
8257 }
8258 case 24: /* Sample */
8259 {
8260 if (attribute_flag[0] != 0)
8261 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8262 &geometry,exception);
8263 if (attribute_flag[1] != 0)
8264 geometry.width=argument_list[1].integer_reference;
8265 if (attribute_flag[2] != 0)
8266 geometry.height=argument_list[2].integer_reference;
8267 image=SampleImage(image,geometry.width,geometry.height,exception);
8268 break;
8269 }
8270 case 25: /* Scale */
8271 {
8272 if (attribute_flag[0] != 0)
8273 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8274 &geometry,exception);
8275 if (attribute_flag[1] != 0)
8276 geometry.width=argument_list[1].integer_reference;
8277 if (attribute_flag[2] != 0)
8278 geometry.height=argument_list[2].integer_reference;
8279 image=ScaleImage(image,geometry.width,geometry.height,exception);
8280 break;
8281 }
8282 case 26: /* Shade */
8283 {
8284 if (attribute_flag[0] != 0)
8285 {
8286 flags=ParseGeometry(argument_list[0].string_reference,
8287 &geometry_info);
8288 if ((flags & SigmaValue) == 0)
8289 geometry_info.sigma=0.0;
8290 }
8291 if (attribute_flag[1] != 0)
8292 geometry_info.rho=argument_list[1].real_reference;
8293 if (attribute_flag[2] != 0)
8294 geometry_info.sigma=argument_list[2].real_reference;
8295 image=ShadeImage(image,
8296 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8297 geometry_info.rho,geometry_info.sigma,exception);
8298 break;
8299 }
8300 case 27: /* Sharpen */
8301 {
8302 if (attribute_flag[0] != 0)
8303 {
8304 flags=ParseGeometry(argument_list[0].string_reference,
8305 &geometry_info);
8306 if ((flags & SigmaValue) == 0)
8307 geometry_info.sigma=1.0;
8308 }
8309 if (attribute_flag[1] != 0)
8310 geometry_info.rho=argument_list[1].real_reference;
8311 if (attribute_flag[2] != 0)
8312 geometry_info.sigma=argument_list[2].real_reference;
8313 if (attribute_flag[3] != 0)
8314 channel=(ChannelType) argument_list[3].integer_reference;
8315 channel_mask=SetImageChannelMask(image,channel);
8316 image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8317 exception);
8318 if (image != (Image *) NULL)
8319 (void) SetImageChannelMask(image,channel_mask);
8320 break;
8321 }
8322 case 28: /* Shear */
8323 {
8324 if (attribute_flag[0] != 0)
8325 {
8326 flags=ParseGeometry(argument_list[0].string_reference,
8327 &geometry_info);
8328 if ((flags & SigmaValue) == 0)
8329 geometry_info.sigma=geometry_info.rho;
8330 }
8331 if (attribute_flag[1] != 0)
8332 geometry_info.rho=argument_list[1].real_reference;
8333 if (attribute_flag[2] != 0)
8334 geometry_info.sigma=argument_list[2].real_reference;
8335 if (attribute_flag[3] != 0)
8336 QueryColorCompliance(argument_list[3].string_reference,
8337 AllCompliance,&image->background_color,exception);
8338 if (attribute_flag[4] != 0)
8339 QueryColorCompliance(argument_list[4].string_reference,
8340 AllCompliance,&image->background_color,exception);
8341 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8342 exception);
8343 break;
8344 }
8345 case 29: /* Spread */
8346 {
Cristye3319c12015-08-24 07:11:48 -04008347 PixelInterpolateMethod
8348 method;
8349
cristy4a3ce0a2013-08-03 20:06:59 +00008350 if (attribute_flag[0] == 0)
8351 argument_list[0].real_reference=1.0;
Cristye3319c12015-08-24 07:11:48 -04008352 method=UndefinedInterpolatePixel;
8353 if (attribute_flag[1] != 0)
8354 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8355 image=SpreadImage(image,method,argument_list[0].real_reference,
8356 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008357 break;
8358 }
8359 case 30: /* Swirl */
8360 {
8361 PixelInterpolateMethod
8362 method;
8363
8364 if (attribute_flag[0] == 0)
8365 argument_list[0].real_reference=50.0;
8366 method=UndefinedInterpolatePixel;
8367 if (attribute_flag[1] != 0)
8368 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8369 image=SwirlImage(image,argument_list[0].real_reference,
8370 method,exception);
8371 break;
8372 }
8373 case 31: /* Resize */
8374 case 32: /* Zoom */
8375 {
8376 if (attribute_flag[0] != 0)
8377 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8378 &geometry,exception);
8379 if (attribute_flag[1] != 0)
8380 geometry.width=argument_list[1].integer_reference;
8381 if (attribute_flag[2] != 0)
8382 geometry.height=argument_list[2].integer_reference;
8383 if (attribute_flag[3] == 0)
8384 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8385 if (attribute_flag[4] != 0)
8386 SetImageArtifact(image,"filter:support",
8387 argument_list[4].string_reference);
8388 image=ResizeImage(image,geometry.width,geometry.height,
Cristy8645e042016-02-03 16:35:29 -05008389 (FilterType) argument_list[3].integer_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00008390 exception);
8391 break;
8392 }
8393 case 33: /* Annotate */
8394 {
8395 DrawInfo
8396 *draw_info;
8397
8398 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8399 (DrawInfo *) NULL);
8400 if (attribute_flag[0] != 0)
8401 {
8402 char
8403 *text;
8404
8405 text=InterpretImageProperties(info ? info->image_info :
8406 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8407 exception);
8408 (void) CloneString(&draw_info->text,text);
8409 text=DestroyString(text);
8410 }
8411 if (attribute_flag[1] != 0)
8412 (void) CloneString(&draw_info->font,
8413 argument_list[1].string_reference);
8414 if (attribute_flag[2] != 0)
8415 draw_info->pointsize=argument_list[2].real_reference;
8416 if (attribute_flag[3] != 0)
8417 (void) CloneString(&draw_info->density,
8418 argument_list[3].string_reference);
8419 if (attribute_flag[4] != 0)
8420 (void) QueryColorCompliance(argument_list[4].string_reference,
8421 AllCompliance,&draw_info->undercolor,exception);
8422 if (attribute_flag[5] != 0)
8423 {
8424 (void) QueryColorCompliance(argument_list[5].string_reference,
8425 AllCompliance,&draw_info->stroke,exception);
8426 if (argument_list[5].image_reference != (Image *) NULL)
8427 draw_info->stroke_pattern=CloneImage(
8428 argument_list[5].image_reference,0,0,MagickTrue,exception);
8429 }
8430 if (attribute_flag[6] != 0)
8431 {
8432 (void) QueryColorCompliance(argument_list[6].string_reference,
8433 AllCompliance,&draw_info->fill,exception);
8434 if (argument_list[6].image_reference != (Image *) NULL)
8435 draw_info->fill_pattern=CloneImage(
8436 argument_list[6].image_reference,0,0,MagickTrue,exception);
8437 }
8438 if (attribute_flag[7] != 0)
8439 {
8440 (void) CloneString(&draw_info->geometry,
8441 argument_list[7].string_reference);
8442 flags=ParsePageGeometry(image,argument_list[7].string_reference,
8443 &geometry,exception);
8444 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8445 geometry_info.sigma=geometry_info.xi;
8446 }
8447 if (attribute_flag[8] != 0)
8448 (void) QueryColorCompliance(argument_list[8].string_reference,
8449 AllCompliance,&draw_info->fill,exception);
8450 if (attribute_flag[11] != 0)
8451 draw_info->gravity=(GravityType)
8452 argument_list[11].integer_reference;
8453 if (attribute_flag[25] != 0)
8454 {
8455 AV
8456 *av;
8457
8458 av=(AV *) argument_list[25].array_reference;
8459 if ((av_len(av) != 3) && (av_len(av) != 5))
8460 {
8461 ThrowPerlException(exception,OptionError,
8462 "affine matrix must have 4 or 6 elements",PackageName);
8463 goto PerlException;
8464 }
8465 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8466 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8467 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8468 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8469 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8470 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8471 {
8472 ThrowPerlException(exception,OptionError,
8473 "affine matrix is singular",PackageName);
8474 goto PerlException;
8475 }
8476 if (av_len(av) == 5)
8477 {
8478 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8479 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8480 }
8481 }
8482 for (j=12; j < 17; j++)
8483 {
8484 if (attribute_flag[j] == 0)
8485 continue;
8486 value=argument_list[j].string_reference;
8487 angle=argument_list[j].real_reference;
8488 current=draw_info->affine;
8489 GetAffineMatrix(&affine);
8490 switch (j)
8491 {
8492 case 12:
8493 {
8494 /*
8495 Translate.
8496 */
8497 flags=ParseGeometry(value,&geometry_info);
8498 affine.tx=geometry_info.xi;
8499 affine.ty=geometry_info.psi;
8500 if ((flags & PsiValue) == 0)
8501 affine.ty=affine.tx;
8502 break;
8503 }
8504 case 13:
8505 {
8506 /*
8507 Scale.
8508 */
8509 flags=ParseGeometry(value,&geometry_info);
8510 affine.sx=geometry_info.rho;
8511 affine.sy=geometry_info.sigma;
8512 if ((flags & SigmaValue) == 0)
8513 affine.sy=affine.sx;
8514 break;
8515 }
8516 case 14:
8517 {
8518 /*
8519 Rotate.
8520 */
8521 if (angle == 0.0)
8522 break;
8523 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8524 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8525 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8526 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8527 break;
8528 }
8529 case 15:
8530 {
8531 /*
8532 SkewX.
8533 */
8534 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8535 break;
8536 }
8537 case 16:
8538 {
8539 /*
8540 SkewY.
8541 */
8542 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8543 break;
8544 }
8545 }
8546 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8547 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8548 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8549 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8550 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8551 current.tx;
8552 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8553 current.ty;
8554 }
8555 if (attribute_flag[9] == 0)
8556 argument_list[9].real_reference=0.0;
8557 if (attribute_flag[10] == 0)
8558 argument_list[10].real_reference=0.0;
8559 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8560 {
8561 char
cristy151b66d2015-04-15 10:50:31 +00008562 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008563
cristy151b66d2015-04-15 10:50:31 +00008564 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
cristy4a3ce0a2013-08-03 20:06:59 +00008565 (double) argument_list[9].real_reference+draw_info->affine.tx,
8566 (double) argument_list[10].real_reference+draw_info->affine.ty);
8567 (void) CloneString(&draw_info->geometry,geometry);
8568 }
8569 if (attribute_flag[17] != 0)
8570 draw_info->stroke_width=argument_list[17].real_reference;
8571 if (attribute_flag[18] != 0)
8572 {
8573 draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8574 MagickTrue : MagickFalse;
8575 draw_info->stroke_antialias=draw_info->text_antialias;
8576 }
8577 if (attribute_flag[19] != 0)
8578 (void) CloneString(&draw_info->family,
8579 argument_list[19].string_reference);
8580 if (attribute_flag[20] != 0)
8581 draw_info->style=(StyleType) argument_list[20].integer_reference;
8582 if (attribute_flag[21] != 0)
8583 draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8584 if (attribute_flag[22] != 0)
8585 draw_info->weight=argument_list[22].integer_reference;
8586 if (attribute_flag[23] != 0)
8587 draw_info->align=(AlignType) argument_list[23].integer_reference;
8588 if (attribute_flag[24] != 0)
8589 (void) CloneString(&draw_info->encoding,
8590 argument_list[24].string_reference);
8591 if (attribute_flag[25] != 0)
8592 draw_info->fill_pattern=CloneImage(
8593 argument_list[25].image_reference,0,0,MagickTrue,exception);
8594 if (attribute_flag[26] != 0)
8595 draw_info->fill_pattern=CloneImage(
8596 argument_list[26].image_reference,0,0,MagickTrue,exception);
8597 if (attribute_flag[27] != 0)
8598 draw_info->stroke_pattern=CloneImage(
8599 argument_list[27].image_reference,0,0,MagickTrue,exception);
8600 if (attribute_flag[29] != 0)
8601 draw_info->kerning=argument_list[29].real_reference;
8602 if (attribute_flag[30] != 0)
8603 draw_info->interline_spacing=argument_list[30].real_reference;
8604 if (attribute_flag[31] != 0)
8605 draw_info->interword_spacing=argument_list[31].real_reference;
8606 if (attribute_flag[32] != 0)
8607 draw_info->direction=(DirectionType)
8608 argument_list[32].integer_reference;
8609 (void) AnnotateImage(image,draw_info,exception);
8610 draw_info=DestroyDrawInfo(draw_info);
8611 break;
8612 }
8613 case 34: /* ColorFloodfill */
8614 {
8615 DrawInfo
8616 *draw_info;
8617
8618 MagickBooleanType
8619 invert;
8620
8621 PixelInfo
8622 target;
8623
8624 draw_info=CloneDrawInfo(info ? info->image_info :
8625 (ImageInfo *) NULL,(DrawInfo *) NULL);
8626 if (attribute_flag[0] != 0)
8627 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8628 &geometry,exception);
8629 if (attribute_flag[1] != 0)
8630 geometry.x=argument_list[1].integer_reference;
8631 if (attribute_flag[2] != 0)
8632 geometry.y=argument_list[2].integer_reference;
8633 if (attribute_flag[3] != 0)
8634 (void) QueryColorCompliance(argument_list[3].string_reference,
8635 AllCompliance,&draw_info->fill,exception);
8636 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8637 geometry.x,geometry.y,&target,exception);
8638 invert=MagickFalse;
8639 if (attribute_flag[4] != 0)
8640 {
8641 QueryColorCompliance(argument_list[4].string_reference,
8642 AllCompliance,&target,exception);
8643 invert=MagickTrue;
8644 }
8645 if (attribute_flag[5] != 0)
8646 image->fuzz=StringToDoubleInterval(
8647 argument_list[5].string_reference,(double) QuantumRange+1.0);
8648 if (attribute_flag[6] != 0)
8649 invert=(MagickBooleanType) argument_list[6].integer_reference;
8650 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8651 geometry.y,invert,exception);
8652 draw_info=DestroyDrawInfo(draw_info);
8653 break;
8654 }
8655 case 35: /* Composite */
8656 {
8657 char
cristy151b66d2015-04-15 10:50:31 +00008658 composite_geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008659
8660 Image
8661 *composite_image,
8662 *rotate_image;
8663
8664 MagickBooleanType
8665 clip_to_self;
8666
8667 compose=OverCompositeOp;
8668 if (attribute_flag[0] != 0)
8669 composite_image=argument_list[0].image_reference;
8670 else
8671 {
8672 ThrowPerlException(exception,OptionError,
8673 "CompositeImageRequired",PackageName);
8674 goto PerlException;
8675 }
8676 /*
8677 Parameter Handling used for BOTH normal and tiled composition.
8678 */
8679 if (attribute_flag[1] != 0) /* compose */
8680 compose=(CompositeOperator) argument_list[1].integer_reference;
8681 if (attribute_flag[6] != 0) /* opacity */
8682 {
8683 if (compose != DissolveCompositeOp)
8684 (void) SetImageAlpha(composite_image,(Quantum)
8685 StringToDoubleInterval(argument_list[6].string_reference,
8686 (double) QuantumRange+1.0),exception);
8687 else
8688 {
8689 CacheView
8690 *composite_view;
8691
8692 double
8693 opacity;
8694
8695 MagickBooleanType
8696 sync;
8697
8698 register ssize_t
8699 x;
8700
8701 register Quantum
8702 *q;
8703
8704 ssize_t
8705 y;
8706
8707 /*
8708 Handle dissolve composite operator (patch by
8709 Kevin A. McGrail).
8710 */
8711 (void) CloneString(&image->geometry,
8712 argument_list[6].string_reference);
8713 opacity=(Quantum) StringToDoubleInterval(
8714 argument_list[6].string_reference,(double) QuantumRange+
8715 1.0);
cristy17f11b02014-12-20 19:37:04 +00008716 if (composite_image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00008717 (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8718 composite_view=AcquireAuthenticCacheView(composite_image,exception);
8719 for (y=0; y < (ssize_t) composite_image->rows ; y++)
8720 {
8721 q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8722 composite_image->columns,1,exception);
8723 for (x=0; x < (ssize_t) composite_image->columns; x++)
8724 {
8725 if (GetPixelAlpha(image,q) == OpaqueAlpha)
8726 SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8727 q);
8728 q+=GetPixelChannels(composite_image);
8729 }
8730 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8731 if (sync == MagickFalse)
8732 break;
8733 }
8734 composite_view=DestroyCacheView(composite_view);
8735 }
8736 }
8737 if (attribute_flag[9] != 0) /* "color=>" */
8738 QueryColorCompliance(argument_list[9].string_reference,
8739 AllCompliance,&composite_image->background_color,exception);
8740 if (attribute_flag[12] != 0) /* "interpolate=>" */
8741 image->interpolate=(PixelInterpolateMethod)
8742 argument_list[12].integer_reference;
8743 if (attribute_flag[13] != 0) /* "args=>" */
8744 (void) SetImageArtifact(composite_image,"compose:args",
8745 argument_list[13].string_reference);
8746 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
8747 (void) SetImageArtifact(composite_image,"compose:args",
8748 argument_list[14].string_reference);
Cristy72aed842018-07-08 18:25:50 -04008749 clip_to_self=MagickTrue;
8750 switch (compose)
8751 {
8752 case ClearCompositeOp:
8753 case SrcCompositeOp:
8754 case InCompositeOp:
8755 case SrcInCompositeOp:
8756 case OutCompositeOp:
8757 case SrcOutCompositeOp:
8758 case DstInCompositeOp:
8759 case DstAtopCompositeOp:
Cristy901f5212018-07-08 18:43:34 -04008760 case CopyAlphaCompositeOp:
Cristy72aed842018-07-08 18:25:50 -04008761 case ChangeMaskCompositeOp:
8762 case DissolveCompositeOp:
8763 case BlendCompositeOp:
8764 {
Cristy901f5212018-07-08 18:43:34 -04008765 clip_to_self=MagickFalse;
Cristy72aed842018-07-08 18:25:50 -04008766 break;
8767 }
8768 default:
8769 break;
8770 }
cristy4a3ce0a2013-08-03 20:06:59 +00008771 if (attribute_flag[15] != 0)
8772 clip_to_self=(MagickBooleanType)
8773 argument_list[15].integer_reference;
8774 /*
8775 Tiling Composition (with orthogonal rotate).
8776 */
8777 rotate_image=(Image *) NULL;
8778 if (attribute_flag[8] != 0) /* "rotate=>" */
8779 {
8780 /*
8781 Rotate image.
8782 */
8783 rotate_image=RotateImage(composite_image,
8784 argument_list[8].real_reference,exception);
8785 if (rotate_image == (Image *) NULL)
8786 break;
8787 }
8788 if ((attribute_flag[7] != 0) &&
8789 (argument_list[7].integer_reference != 0)) /* tile */
8790 {
8791 ssize_t
8792 x,
8793 y;
8794
8795 /*
8796 Tile the composite image.
8797 */
cristy4a3ce0a2013-08-03 20:06:59 +00008798 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8799 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8800 {
8801 if (attribute_flag[8] != 0) /* rotate */
8802 (void) CompositeImage(image,rotate_image,compose,
Cristyde6c67d2018-07-08 19:14:08 -04008803 MagickTrue,x,y,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008804 else
8805 (void) CompositeImage(image,composite_image,compose,
Cristyde6c67d2018-07-08 19:14:08 -04008806 MagickTrue,x,y,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008807 }
8808 if (attribute_flag[8] != 0) /* rotate */
8809 rotate_image=DestroyImage(rotate_image);
8810 break;
8811 }
8812 /*
8813 Parameter Handling used used ONLY for normal composition.
8814 */
8815 if (attribute_flag[5] != 0) /* gravity */
8816 image->gravity=(GravityType) argument_list[5].integer_reference;
8817 if (attribute_flag[2] != 0) /* geometry offset */
8818 {
8819 SetGeometry(image,&geometry);
8820 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8821 &geometry);
8822 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8823 &geometry);
8824 }
8825 if (attribute_flag[3] != 0) /* x offset */
8826 geometry.x=argument_list[3].integer_reference;
8827 if (attribute_flag[4] != 0) /* y offset */
8828 geometry.y=argument_list[4].integer_reference;
8829 if (attribute_flag[10] != 0) /* mask */
8830 {
8831 if ((image->compose == DisplaceCompositeOp) ||
8832 (image->compose == DistortCompositeOp))
8833 {
8834 /*
8835 Merge Y displacement into X displacement image.
8836 */
8837 composite_image=CloneImage(composite_image,0,0,MagickTrue,
8838 exception);
8839 (void) CompositeImage(composite_image,
8840 argument_list[10].image_reference,CopyGreenCompositeOp,
Cristy74e39292018-07-08 13:13:20 -04008841 clip_to_self,0,0,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008842 }
8843 else
8844 {
8845 Image
8846 *mask_image;
8847
8848 /*
8849 Set a blending mask for the composition.
8850 */
8851 mask_image=CloneImage(argument_list[10].image_reference,0,0,
8852 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +00008853 (void) SetImageMask(composite_image,ReadPixelMask,mask_image,
cristyf3023752015-07-28 17:13:22 +00008854 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008855 mask_image=DestroyImage(mask_image);
8856 }
8857 }
8858 if (attribute_flag[11] != 0) /* channel */
8859 channel=(ChannelType) argument_list[11].integer_reference;
8860 /*
8861 Composite two images (normal composition).
8862 */
cristy151b66d2015-04-15 10:50:31 +00008863 (void) FormatLocaleString(composite_geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00008864 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8865 (double) composite_image->rows,(double) geometry.x,(double)
8866 geometry.y);
8867 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8868 exception);
8869 channel_mask=SetImageChannelMask(image,channel);
8870 if (attribute_flag[8] == 0) /* no rotate */
8871 CompositeImage(image,composite_image,compose,clip_to_self,
8872 geometry.x,geometry.y,exception);
8873 else
8874 {
8875 /*
8876 Position adjust rotated image then composite.
8877 */
8878 geometry.x-=(ssize_t) (rotate_image->columns-
8879 composite_image->columns)/2;
8880 geometry.y-=(ssize_t) (rotate_image->rows-
8881 composite_image->rows)/2;
8882 CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8883 geometry.y,exception);
8884 rotate_image=DestroyImage(rotate_image);
8885 }
8886 if (attribute_flag[10] != 0) /* mask */
8887 {
8888 if ((image->compose == DisplaceCompositeOp) ||
8889 (image->compose == DistortCompositeOp))
8890 composite_image=DestroyImage(composite_image);
8891 else
cristy1f7ffb72015-07-29 11:07:03 +00008892 (void) SetImageMask(image,ReadPixelMask,(Image *) NULL,
cristyf3023752015-07-28 17:13:22 +00008893 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008894 }
8895 (void) SetImageChannelMask(image,channel_mask);
8896 break;
8897 }
8898 case 36: /* Contrast */
8899 {
8900 if (attribute_flag[0] == 0)
8901 argument_list[0].integer_reference=0;
8902 (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8903 MagickTrue : MagickFalse,exception);
8904 break;
8905 }
8906 case 37: /* CycleColormap */
8907 {
8908 if (attribute_flag[0] == 0)
8909 argument_list[0].integer_reference=6;
8910 (void) CycleColormapImage(image,argument_list[0].integer_reference,
8911 exception);
8912 break;
8913 }
8914 case 38: /* Draw */
8915 {
8916 DrawInfo
8917 *draw_info;
8918
8919 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8920 (DrawInfo *) NULL);
8921 (void) CloneString(&draw_info->primitive,"point");
8922 if (attribute_flag[0] != 0)
8923 {
8924 if (argument_list[0].integer_reference < 0)
8925 (void) CloneString(&draw_info->primitive,
8926 argument_list[0].string_reference);
8927 else
8928 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8929 MagickPrimitiveOptions,argument_list[0].integer_reference));
8930 }
8931 if (attribute_flag[1] != 0)
8932 {
8933 if (LocaleCompare(draw_info->primitive,"path") == 0)
8934 {
8935 (void) ConcatenateString(&draw_info->primitive," '");
8936 ConcatenateString(&draw_info->primitive,
8937 argument_list[1].string_reference);
8938 (void) ConcatenateString(&draw_info->primitive,"'");
8939 }
8940 else
8941 {
8942 (void) ConcatenateString(&draw_info->primitive," ");
8943 ConcatenateString(&draw_info->primitive,
8944 argument_list[1].string_reference);
8945 }
8946 }
8947 if (attribute_flag[2] != 0)
8948 {
8949 (void) ConcatenateString(&draw_info->primitive," ");
8950 (void) ConcatenateString(&draw_info->primitive,
8951 CommandOptionToMnemonic(MagickMethodOptions,
8952 argument_list[2].integer_reference));
8953 }
8954 if (attribute_flag[3] != 0)
8955 {
8956 (void) QueryColorCompliance(argument_list[3].string_reference,
8957 AllCompliance,&draw_info->stroke,exception);
8958 if (argument_list[3].image_reference != (Image *) NULL)
8959 draw_info->stroke_pattern=CloneImage(
8960 argument_list[3].image_reference,0,0,MagickTrue,exception);
8961 }
8962 if (attribute_flag[4] != 0)
8963 {
8964 (void) QueryColorCompliance(argument_list[4].string_reference,
8965 AllCompliance,&draw_info->fill,exception);
8966 if (argument_list[4].image_reference != (Image *) NULL)
8967 draw_info->fill_pattern=CloneImage(
8968 argument_list[4].image_reference,0,0,MagickTrue,exception);
8969 }
8970 if (attribute_flag[5] != 0)
8971 draw_info->stroke_width=argument_list[5].real_reference;
8972 if (attribute_flag[6] != 0)
8973 (void) CloneString(&draw_info->font,
8974 argument_list[6].string_reference);
8975 if (attribute_flag[7] != 0)
8976 (void) QueryColorCompliance(argument_list[7].string_reference,
8977 AllCompliance,&draw_info->border_color,exception);
8978 if (attribute_flag[8] != 0)
8979 draw_info->affine.tx=argument_list[8].real_reference;
8980 if (attribute_flag[9] != 0)
8981 draw_info->affine.ty=argument_list[9].real_reference;
8982 if (attribute_flag[20] != 0)
8983 {
8984 AV
8985 *av;
8986
8987 av=(AV *) argument_list[20].array_reference;
8988 if ((av_len(av) != 3) && (av_len(av) != 5))
8989 {
8990 ThrowPerlException(exception,OptionError,
8991 "affine matrix must have 4 or 6 elements",PackageName);
8992 goto PerlException;
8993 }
8994 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8995 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8996 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8997 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8998 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8999 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9000 {
9001 ThrowPerlException(exception,OptionError,
9002 "affine matrix is singular",PackageName);
9003 goto PerlException;
9004 }
9005 if (av_len(av) == 5)
9006 {
9007 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9008 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9009 }
9010 }
9011 for (j=10; j < 15; j++)
9012 {
9013 if (attribute_flag[j] == 0)
9014 continue;
9015 value=argument_list[j].string_reference;
9016 angle=argument_list[j].real_reference;
9017 current=draw_info->affine;
9018 GetAffineMatrix(&affine);
9019 switch (j)
9020 {
9021 case 10:
9022 {
9023 /*
9024 Translate.
9025 */
9026 flags=ParseGeometry(value,&geometry_info);
9027 affine.tx=geometry_info.xi;
9028 affine.ty=geometry_info.psi;
9029 if ((flags & PsiValue) == 0)
9030 affine.ty=affine.tx;
9031 break;
9032 }
9033 case 11:
9034 {
9035 /*
9036 Scale.
9037 */
9038 flags=ParseGeometry(value,&geometry_info);
9039 affine.sx=geometry_info.rho;
9040 affine.sy=geometry_info.sigma;
9041 if ((flags & SigmaValue) == 0)
9042 affine.sy=affine.sx;
9043 break;
9044 }
9045 case 12:
9046 {
9047 /*
9048 Rotate.
9049 */
9050 if (angle == 0.0)
9051 break;
9052 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9053 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9054 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9055 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9056 break;
9057 }
9058 case 13:
9059 {
9060 /*
9061 SkewX.
9062 */
9063 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9064 break;
9065 }
9066 case 14:
9067 {
9068 /*
9069 SkewY.
9070 */
9071 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9072 break;
9073 }
9074 }
9075 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9076 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9077 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9078 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9079 draw_info->affine.tx=
9080 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9081 draw_info->affine.ty=
9082 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9083 }
9084 if (attribute_flag[15] != 0)
9085 draw_info->fill_pattern=CloneImage(
9086 argument_list[15].image_reference,0,0,MagickTrue,exception);
9087 if (attribute_flag[16] != 0)
9088 draw_info->pointsize=argument_list[16].real_reference;
9089 if (attribute_flag[17] != 0)
9090 {
Cristy36c30b62018-11-22 09:33:30 -05009091 draw_info->stroke_antialias=argument_list[17].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009092 draw_info->text_antialias=draw_info->stroke_antialias;
9093 }
9094 if (attribute_flag[18] != 0)
9095 (void) CloneString(&draw_info->density,
9096 argument_list[18].string_reference);
9097 if (attribute_flag[19] != 0)
9098 draw_info->stroke_width=argument_list[19].real_reference;
9099 if (attribute_flag[21] != 0)
9100 draw_info->dash_offset=argument_list[21].real_reference;
9101 if (attribute_flag[22] != 0)
9102 {
9103 AV
9104 *av;
9105
9106 av=(AV *) argument_list[22].array_reference;
9107 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
9108 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
9109 if (draw_info->dash_pattern != (double *) NULL)
9110 {
9111 for (i=0; i <= av_len(av); i++)
9112 draw_info->dash_pattern[i]=(double)
9113 SvNV(*(av_fetch(av,i,0)));
9114 draw_info->dash_pattern[i]=0.0;
9115 }
9116 }
9117 if (attribute_flag[23] != 0)
9118 image->interpolate=(PixelInterpolateMethod)
9119 argument_list[23].integer_reference;
9120 if ((attribute_flag[24] != 0) &&
9121 (draw_info->fill_pattern != (Image *) NULL))
9122 flags=ParsePageGeometry(draw_info->fill_pattern,
9123 argument_list[24].string_reference,
9124 &draw_info->fill_pattern->tile_offset,exception);
9125 if (attribute_flag[25] != 0)
9126 {
9127 (void) ConcatenateString(&draw_info->primitive," '");
9128 (void) ConcatenateString(&draw_info->primitive,
9129 argument_list[25].string_reference);
9130 (void) ConcatenateString(&draw_info->primitive,"'");
9131 }
9132 if (attribute_flag[26] != 0)
9133 draw_info->fill_pattern=CloneImage(
9134 argument_list[26].image_reference,0,0,MagickTrue,exception);
9135 if (attribute_flag[27] != 0)
9136 draw_info->stroke_pattern=CloneImage(
9137 argument_list[27].image_reference,0,0,MagickTrue,exception);
9138 if (attribute_flag[28] != 0)
9139 (void) CloneString(&draw_info->primitive,
9140 argument_list[28].string_reference);
9141 if (attribute_flag[29] != 0)
9142 draw_info->kerning=argument_list[29].real_reference;
9143 if (attribute_flag[30] != 0)
9144 draw_info->interline_spacing=argument_list[30].real_reference;
9145 if (attribute_flag[31] != 0)
9146 draw_info->interword_spacing=argument_list[31].real_reference;
9147 if (attribute_flag[32] != 0)
9148 draw_info->direction=(DirectionType)
9149 argument_list[32].integer_reference;
Cristy36c30b62018-11-22 09:33:30 -05009150 (void) DrawImage(image,draw_info,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009151 draw_info=DestroyDrawInfo(draw_info);
9152 break;
9153 }
9154 case 39: /* Equalize */
9155 {
9156 if (attribute_flag[0] != 0)
9157 channel=(ChannelType) argument_list[0].integer_reference;
9158 channel_mask=SetImageChannelMask(image,channel);
Cristy36c30b62018-11-22 09:33:30 -05009159 (void) EqualizeImage(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009160 (void) SetImageChannelMask(image,channel_mask);
9161 break;
9162 }
9163 case 40: /* Gamma */
9164 {
9165 if (attribute_flag[1] != 0)
9166 channel=(ChannelType) argument_list[1].integer_reference;
9167 if (attribute_flag[2] == 0)
9168 argument_list[2].real_reference=1.0;
9169 if (attribute_flag[3] == 0)
9170 argument_list[3].real_reference=1.0;
9171 if (attribute_flag[4] == 0)
9172 argument_list[4].real_reference=1.0;
9173 if (attribute_flag[0] == 0)
9174 {
cristy151b66d2015-04-15 10:50:31 +00009175 (void) FormatLocaleString(message,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -05009176 "%.20g,%.20g,%.20g",(double) argument_list[2].real_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009177 (double) argument_list[3].real_reference,
9178 (double) argument_list[4].real_reference);
9179 argument_list[0].string_reference=message;
9180 }
9181 (void) GammaImage(image,StringToDouble(
9182 argument_list[0].string_reference,(char **) NULL),exception);
9183 break;
9184 }
9185 case 41: /* Map */
9186 {
9187 QuantizeInfo
9188 *quantize_info;
9189
9190 if (attribute_flag[0] == 0)
9191 {
9192 ThrowPerlException(exception,OptionError,"MapImageRequired",
9193 PackageName);
9194 goto PerlException;
9195 }
9196 quantize_info=AcquireQuantizeInfo(info->image_info);
9197 if (attribute_flag[1] != 0)
9198 quantize_info->dither_method=(DitherMethod)
9199 argument_list[1].integer_reference;
9200 (void) RemapImages(quantize_info,image,
9201 argument_list[0].image_reference,exception);
9202 quantize_info=DestroyQuantizeInfo(quantize_info);
9203 break;
9204 }
9205 case 42: /* MatteFloodfill */
9206 {
9207 DrawInfo
9208 *draw_info;
9209
9210 MagickBooleanType
9211 invert;
9212
9213 PixelInfo
9214 target;
9215
9216 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9217 (DrawInfo *) NULL);
9218 if (attribute_flag[0] != 0)
9219 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9220 &geometry,exception);
9221 if (attribute_flag[1] != 0)
9222 geometry.x=argument_list[1].integer_reference;
9223 if (attribute_flag[2] != 0)
9224 geometry.y=argument_list[2].integer_reference;
cristy17f11b02014-12-20 19:37:04 +00009225 if (image->alpha_trait == UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00009226 (void) SetImageAlpha(image,OpaqueAlpha,exception);
9227 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
9228 geometry.x,geometry.y,&target,exception);
9229 if (attribute_flag[4] != 0)
9230 QueryColorCompliance(argument_list[4].string_reference,
9231 AllCompliance,&target,exception);
9232 if (attribute_flag[3] != 0)
9233 target.alpha=StringToDoubleInterval(
9234 argument_list[3].string_reference,(double) (double) QuantumRange+
9235 1.0);
9236 if (attribute_flag[5] != 0)
9237 image->fuzz=StringToDoubleInterval(
9238 argument_list[5].string_reference,(double) QuantumRange+1.0);
9239 invert=MagickFalse;
9240 if (attribute_flag[6] != 0)
9241 invert=(MagickBooleanType) argument_list[6].integer_reference;
9242 channel_mask=SetImageChannelMask(image,AlphaChannel);
9243 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
9244 geometry.y,invert,exception);
9245 (void) SetImageChannelMask(image,channel_mask);
9246 draw_info=DestroyDrawInfo(draw_info);
9247 break;
9248 }
9249 case 43: /* Modulate */
9250 {
9251 char
cristy151b66d2015-04-15 10:50:31 +00009252 modulate[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00009253
9254 geometry_info.rho=100.0;
9255 geometry_info.sigma=100.0;
9256 geometry_info.xi=100.0;
9257 if (attribute_flag[0] != 0)
9258 (void)ParseGeometry(argument_list[0].string_reference,
9259 &geometry_info);
9260 if (attribute_flag[1] != 0)
9261 geometry_info.xi=argument_list[1].real_reference;
9262 if (attribute_flag[2] != 0)
9263 geometry_info.sigma=argument_list[2].real_reference;
9264 if (attribute_flag[3] != 0)
9265 {
9266 geometry_info.sigma=argument_list[3].real_reference;
9267 SetImageArtifact(image,"modulate:colorspace","HWB");
9268 }
9269 if (attribute_flag[4] != 0)
9270 {
9271 geometry_info.rho=argument_list[4].real_reference;
9272 SetImageArtifact(image,"modulate:colorspace","HSB");
9273 }
9274 if (attribute_flag[5] != 0)
9275 {
9276 geometry_info.sigma=argument_list[5].real_reference;
9277 SetImageArtifact(image,"modulate:colorspace","HSL");
9278 }
9279 if (attribute_flag[6] != 0)
9280 {
9281 geometry_info.rho=argument_list[6].real_reference;
9282 SetImageArtifact(image,"modulate:colorspace","HWB");
9283 }
Cristy935a4052017-03-31 17:45:37 -04009284 (void) FormatLocaleString(modulate,MagickPathExtent,"%.20g,%.20g,%.20g",
9285 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
cristy4a3ce0a2013-08-03 20:06:59 +00009286 (void) ModulateImage(image,modulate,exception);
9287 break;
9288 }
9289 case 44: /* Negate */
9290 {
9291 if (attribute_flag[0] == 0)
9292 argument_list[0].integer_reference=0;
9293 if (attribute_flag[1] != 0)
9294 channel=(ChannelType) argument_list[1].integer_reference;
9295 channel_mask=SetImageChannelMask(image,channel);
9296 (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9297 MagickTrue : MagickFalse,exception);
9298 (void) SetImageChannelMask(image,channel_mask);
9299 break;
9300 }
9301 case 45: /* Normalize */
9302 {
9303 if (attribute_flag[0] != 0)
9304 channel=(ChannelType) argument_list[0].integer_reference;
9305 channel_mask=SetImageChannelMask(image,channel);
9306 NormalizeImage(image,exception);
9307 (void) SetImageChannelMask(image,channel_mask);
9308 break;
9309 }
9310 case 46: /* NumberColors */
9311 break;
9312 case 47: /* Opaque */
9313 {
9314 MagickBooleanType
9315 invert;
9316
9317 PixelInfo
9318 fill_color,
9319 target;
9320
9321 (void) QueryColorCompliance("none",AllCompliance,&target,
9322 exception);
9323 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9324 exception);
9325 if (attribute_flag[0] != 0)
9326 (void) QueryColorCompliance(argument_list[0].string_reference,
9327 AllCompliance,&target,exception);
9328 if (attribute_flag[1] != 0)
9329 (void) QueryColorCompliance(argument_list[1].string_reference,
9330 AllCompliance,&fill_color,exception);
9331 if (attribute_flag[2] != 0)
9332 image->fuzz=StringToDoubleInterval(
9333 argument_list[2].string_reference,(double) QuantumRange+1.0);
9334 if (attribute_flag[3] != 0)
9335 channel=(ChannelType) argument_list[3].integer_reference;
9336 invert=MagickFalse;
9337 if (attribute_flag[4] != 0)
9338 invert=(MagickBooleanType) argument_list[4].integer_reference;
9339 channel_mask=SetImageChannelMask(image,channel);
9340 (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9341 (void) SetImageChannelMask(image,channel_mask);
9342 break;
9343 }
9344 case 48: /* Quantize */
9345 {
9346 QuantizeInfo
9347 *quantize_info;
9348
9349 quantize_info=AcquireQuantizeInfo(info->image_info);
9350 if (attribute_flag[0] != 0)
9351 quantize_info->number_colors=(size_t)
9352 argument_list[0].integer_reference;
9353 if (attribute_flag[1] != 0)
9354 quantize_info->tree_depth=(size_t)
9355 argument_list[1].integer_reference;
9356 if (attribute_flag[2] != 0)
9357 quantize_info->colorspace=(ColorspaceType)
9358 argument_list[2].integer_reference;
9359 if (attribute_flag[3] != 0)
cristy785c9342014-03-19 22:06:39 +00009360 quantize_info->dither_method=(DitherMethod)
9361 argument_list[3].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00009362 if (attribute_flag[4] != 0)
cristy71716d52014-03-19 10:11:11 +00009363 quantize_info->measure_error=
9364 argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009365 if (attribute_flag[6] != 0)
cristyd472dd82014-03-19 22:04:36 +00009366 (void) QueryColorCompliance(argument_list[6].string_reference,
cristyf7563392014-03-25 13:54:04 +00009367 AllCompliance,&image->transparent_color,exception);
cristy71716d52014-03-19 10:11:11 +00009368 if (attribute_flag[7] != 0)
cristy4a3ce0a2013-08-03 20:06:59 +00009369 quantize_info->dither_method=(DitherMethod)
cristy71716d52014-03-19 10:11:11 +00009370 argument_list[7].integer_reference;
9371 if (attribute_flag[5] && argument_list[5].integer_reference)
cristyf7563392014-03-25 13:54:04 +00009372 (void) QuantizeImages(quantize_info,image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009373 else
cristyf7563392014-03-25 13:54:04 +00009374 if ((image->storage_class == DirectClass) ||
9375 (image->colors > quantize_info->number_colors) ||
9376 (quantize_info->colorspace == GRAYColorspace))
9377 (void) QuantizeImage(quantize_info,image,exception);
9378 else
9379 CompressImageColormap(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009380 quantize_info=DestroyQuantizeInfo(quantize_info);
9381 break;
9382 }
9383 case 49: /* Raise */
9384 {
9385 if (attribute_flag[0] != 0)
9386 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9387 &geometry,exception);
9388 if (attribute_flag[1] != 0)
9389 geometry.width=argument_list[1].integer_reference;
9390 if (attribute_flag[2] != 0)
9391 geometry.height=argument_list[2].integer_reference;
9392 if (attribute_flag[3] == 0)
9393 argument_list[3].integer_reference=1;
9394 (void) RaiseImage(image,&geometry,
9395 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9396 exception);
9397 break;
9398 }
9399 case 50: /* Segment */
9400 {
9401 ColorspaceType
9402 colorspace;
9403
9404 double
9405 cluster_threshold,
9406 smoothing_threshold;
9407
9408 MagickBooleanType
9409 verbose;
9410
9411 cluster_threshold=1.0;
9412 smoothing_threshold=1.5;
9413 colorspace=sRGBColorspace;
9414 verbose=MagickFalse;
9415 if (attribute_flag[0] != 0)
9416 {
9417 flags=ParseGeometry(argument_list[0].string_reference,
9418 &geometry_info);
9419 cluster_threshold=geometry_info.rho;
9420 if (flags & SigmaValue)
9421 smoothing_threshold=geometry_info.sigma;
9422 }
9423 if (attribute_flag[1] != 0)
9424 cluster_threshold=argument_list[1].real_reference;
9425 if (attribute_flag[2] != 0)
9426 smoothing_threshold=argument_list[2].real_reference;
9427 if (attribute_flag[3] != 0)
9428 colorspace=(ColorspaceType) argument_list[3].integer_reference;
9429 if (attribute_flag[4] != 0)
9430 verbose=argument_list[4].integer_reference != 0 ?
9431 MagickTrue : MagickFalse;
9432 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9433 smoothing_threshold,exception);
9434 break;
9435 }
9436 case 51: /* Signature */
9437 {
9438 (void) SignatureImage(image,exception);
9439 break;
9440 }
9441 case 52: /* Solarize */
9442 {
9443 geometry_info.rho=QuantumRange/2.0;
9444 if (attribute_flag[0] != 0)
9445 flags=ParseGeometry(argument_list[0].string_reference,
9446 &geometry_info);
9447 if (attribute_flag[1] != 0)
9448 geometry_info.rho=StringToDoubleInterval(
9449 argument_list[1].string_reference,(double) QuantumRange+1.0);
9450 (void) SolarizeImage(image,geometry_info.rho,exception);
9451 break;
9452 }
9453 case 53: /* Sync */
9454 {
9455 (void) SyncImage(image,exception);
9456 break;
9457 }
9458 case 54: /* Texture */
9459 {
9460 if (attribute_flag[0] == 0)
9461 break;
9462 TextureImage(image,argument_list[0].image_reference,exception);
9463 break;
9464 }
9465 case 55: /* Evalute */
9466 {
9467 MagickEvaluateOperator
9468 op;
9469
9470 op=SetEvaluateOperator;
9471 if (attribute_flag[0] == MagickFalse)
9472 argument_list[0].real_reference=0.0;
9473 if (attribute_flag[1] != MagickFalse)
9474 op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9475 if (attribute_flag[2] != MagickFalse)
9476 channel=(ChannelType) argument_list[2].integer_reference;
9477 channel_mask=SetImageChannelMask(image,channel);
9478 (void) EvaluateImage(image,op,argument_list[0].real_reference,
9479 exception);
9480 (void) SetImageChannelMask(image,channel_mask);
9481 break;
9482 }
9483 case 56: /* Transparent */
9484 {
9485 double
9486 opacity;
9487
9488 MagickBooleanType
9489 invert;
9490
9491 PixelInfo
9492 target;
9493
9494 (void) QueryColorCompliance("none",AllCompliance,&target,
9495 exception);
9496 if (attribute_flag[0] != 0)
9497 (void) QueryColorCompliance(argument_list[0].string_reference,
9498 AllCompliance,&target,exception);
9499 opacity=TransparentAlpha;
9500 if (attribute_flag[1] != 0)
9501 opacity=StringToDoubleInterval(argument_list[1].string_reference,
9502 (double) QuantumRange+1.0);
9503 if (attribute_flag[2] != 0)
9504 image->fuzz=StringToDoubleInterval(
9505 argument_list[2].string_reference,(double) QuantumRange+1.0);
9506 if (attribute_flag[3] == 0)
9507 argument_list[3].integer_reference=0;
9508 invert=MagickFalse;
9509 if (attribute_flag[3] != 0)
9510 invert=(MagickBooleanType) argument_list[3].integer_reference;
9511 (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9512 invert,exception);
9513 break;
9514 }
9515 case 57: /* Threshold */
9516 {
9517 double
9518 threshold;
9519
9520 if (attribute_flag[0] == 0)
9521 argument_list[0].string_reference="50%";
9522 if (attribute_flag[1] != 0)
9523 channel=(ChannelType) argument_list[1].integer_reference;
9524 threshold=StringToDoubleInterval(argument_list[0].string_reference,
9525 (double) QuantumRange+1.0);
9526 channel_mask=SetImageChannelMask(image,channel);
9527 (void) BilevelImage(image,threshold,exception);
9528 (void) SetImageChannelMask(image,channel_mask);
9529 break;
9530 }
9531 case 58: /* Charcoal */
9532 {
9533 if (attribute_flag[0] != 0)
9534 {
9535 flags=ParseGeometry(argument_list[0].string_reference,
9536 &geometry_info);
9537 if ((flags & SigmaValue) == 0)
9538 geometry_info.sigma=1.0;
9539 }
9540 if (attribute_flag[1] != 0)
9541 geometry_info.rho=argument_list[1].real_reference;
9542 if (attribute_flag[2] != 0)
9543 geometry_info.sigma=argument_list[2].real_reference;
9544 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9545 exception);
9546 break;
9547 }
9548 case 59: /* Trim */
9549 {
9550 if (attribute_flag[0] != 0)
9551 image->fuzz=StringToDoubleInterval(
9552 argument_list[0].string_reference,(double) QuantumRange+1.0);
9553 image=TrimImage(image,exception);
9554 break;
9555 }
9556 case 60: /* Wave */
9557 {
9558 PixelInterpolateMethod
9559 method;
9560
9561 if (attribute_flag[0] != 0)
9562 {
9563 flags=ParseGeometry(argument_list[0].string_reference,
9564 &geometry_info);
9565 if ((flags & SigmaValue) == 0)
9566 geometry_info.sigma=1.0;
9567 }
9568 if (attribute_flag[1] != 0)
9569 geometry_info.rho=argument_list[1].real_reference;
9570 if (attribute_flag[2] != 0)
9571 geometry_info.sigma=argument_list[2].real_reference;
9572 method=UndefinedInterpolatePixel;
9573 if (attribute_flag[3] != 0)
9574 method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9575 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9576 method,exception);
9577 break;
9578 }
9579 case 61: /* Separate */
9580 {
9581 if (attribute_flag[0] != 0)
9582 channel=(ChannelType) argument_list[0].integer_reference;
9583 image=SeparateImage(image,channel,exception);
9584 break;
9585 }
9586 case 63: /* Stereo */
9587 {
9588 if (attribute_flag[0] == 0)
9589 {
9590 ThrowPerlException(exception,OptionError,"StereoImageRequired",
9591 PackageName);
9592 goto PerlException;
9593 }
9594 if (attribute_flag[1] != 0)
9595 geometry.x=argument_list[1].integer_reference;
9596 if (attribute_flag[2] != 0)
9597 geometry.y=argument_list[2].integer_reference;
9598 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9599 geometry.x,geometry.y,exception);
9600 break;
9601 }
9602 case 64: /* Stegano */
9603 {
9604 if (attribute_flag[0] == 0)
9605 {
9606 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9607 PackageName);
9608 goto PerlException;
9609 }
9610 if (attribute_flag[1] == 0)
9611 argument_list[1].integer_reference=0;
9612 image->offset=argument_list[1].integer_reference;
9613 image=SteganoImage(image,argument_list[0].image_reference,exception);
9614 break;
9615 }
9616 case 65: /* Deconstruct */
9617 {
9618 image=CompareImagesLayers(image,CompareAnyLayer,exception);
9619 break;
9620 }
9621 case 66: /* GaussianBlur */
9622 {
9623 if (attribute_flag[0] != 0)
9624 {
9625 flags=ParseGeometry(argument_list[0].string_reference,
9626 &geometry_info);
9627 if ((flags & SigmaValue) == 0)
9628 geometry_info.sigma=1.0;
9629 }
9630 if (attribute_flag[1] != 0)
9631 geometry_info.rho=argument_list[1].real_reference;
9632 if (attribute_flag[2] != 0)
9633 geometry_info.sigma=argument_list[2].real_reference;
9634 if (attribute_flag[3] != 0)
9635 channel=(ChannelType) argument_list[3].integer_reference;
9636 channel_mask=SetImageChannelMask(image,channel);
9637 image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9638 exception);
9639 if (image != (Image *) NULL)
9640 (void) SetImageChannelMask(image,channel_mask);
9641 break;
9642 }
9643 case 67: /* Convolve */
9644 {
9645 KernelInfo
9646 *kernel;
9647
9648 kernel=(KernelInfo *) NULL;
9649 if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9650 break;
9651 if (attribute_flag[0] != 0)
9652 {
9653 AV
9654 *av;
9655
9656 size_t
9657 order;
9658
cristy2c57b742014-10-31 00:40:34 +00009659 kernel=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009660 if (kernel == (KernelInfo *) NULL)
9661 break;
9662 av=(AV *) argument_list[0].array_reference;
9663 order=(size_t) sqrt(av_len(av)+1);
9664 kernel->width=order;
9665 kernel->height=order;
9666 kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9667 order*sizeof(*kernel->values));
9668 if (kernel->values == (MagickRealType *) NULL)
9669 {
9670 kernel=DestroyKernelInfo(kernel);
9671 ThrowPerlException(exception,ResourceLimitFatalError,
9672 "MemoryAllocationFailed",PackageName);
9673 goto PerlException;
9674 }
9675 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9676 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9677 for ( ; j < (ssize_t) (order*order); j++)
9678 kernel->values[j]=0.0;
9679 }
9680 if (attribute_flag[1] != 0)
9681 channel=(ChannelType) argument_list[1].integer_reference;
9682 if (attribute_flag[2] != 0)
Cristyc4ff6bd2017-07-05 21:00:11 -04009683 SetImageArtifact(image,"convolve:bias",
cristy4a3ce0a2013-08-03 20:06:59 +00009684 argument_list[2].string_reference);
9685 if (attribute_flag[3] != 0)
9686 {
cristy2c57b742014-10-31 00:40:34 +00009687 kernel=AcquireKernelInfo(argument_list[3].string_reference,
9688 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009689 if (kernel == (KernelInfo *) NULL)
9690 break;
9691 }
9692 channel_mask=SetImageChannelMask(image,channel);
9693 image=ConvolveImage(image,kernel,exception);
9694 if (image != (Image *) NULL)
9695 (void) SetImageChannelMask(image,channel_mask);
9696 kernel=DestroyKernelInfo(kernel);
9697 break;
9698 }
9699 case 68: /* Profile */
9700 {
9701 const char
9702 *name;
9703
9704 Image
9705 *profile_image;
9706
9707 ImageInfo
9708 *profile_info;
9709
9710 StringInfo
9711 *profile;
9712
9713 name="*";
9714 if (attribute_flag[0] != 0)
9715 name=argument_list[0].string_reference;
9716 if (attribute_flag[2] != 0)
9717 image->rendering_intent=(RenderingIntent)
9718 argument_list[2].integer_reference;
9719 if (attribute_flag[3] != 0)
9720 image->black_point_compensation=
9721 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9722 if (attribute_flag[1] != 0)
9723 {
9724 if (argument_list[1].length == 0)
9725 {
9726 /*
9727 Remove a profile from the image.
9728 */
9729 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9730 exception);
9731 break;
9732 }
9733 /*
9734 Associate user supplied profile with the image.
9735 */
9736 profile=AcquireStringInfo(argument_list[1].length);
9737 SetStringInfoDatum(profile,(const unsigned char *)
9738 argument_list[1].string_reference);
9739 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9740 (size_t) GetStringInfoLength(profile),exception);
9741 profile=DestroyStringInfo(profile);
9742 break;
9743 }
9744 /*
9745 Associate a profile with the image.
9746 */
9747 profile_info=CloneImageInfo(info ? info->image_info :
9748 (ImageInfo *) NULL);
9749 profile_image=ReadImages(profile_info,name,exception);
9750 if (profile_image == (Image *) NULL)
9751 break;
9752 ResetImageProfileIterator(profile_image);
9753 name=GetNextImageProfile(profile_image);
9754 while (name != (const char *) NULL)
9755 {
9756 const StringInfo
9757 *profile;
9758
9759 profile=GetImageProfile(profile_image,name);
9760 if (profile != (const StringInfo *) NULL)
9761 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9762 (size_t) GetStringInfoLength(profile),exception);
9763 name=GetNextImageProfile(profile_image);
9764 }
9765 profile_image=DestroyImage(profile_image);
9766 profile_info=DestroyImageInfo(profile_info);
9767 break;
9768 }
9769 case 69: /* UnsharpMask */
9770 {
9771 if (attribute_flag[0] != 0)
9772 {
9773 flags=ParseGeometry(argument_list[0].string_reference,
9774 &geometry_info);
9775 if ((flags & SigmaValue) == 0)
9776 geometry_info.sigma=1.0;
9777 if ((flags & XiValue) == 0)
9778 geometry_info.xi=1.0;
9779 if ((flags & PsiValue) == 0)
9780 geometry_info.psi=0.5;
9781 }
9782 if (attribute_flag[1] != 0)
9783 geometry_info.rho=argument_list[1].real_reference;
9784 if (attribute_flag[2] != 0)
9785 geometry_info.sigma=argument_list[2].real_reference;
9786 if (attribute_flag[3] != 0)
9787 geometry_info.xi=argument_list[3].real_reference;
9788 if (attribute_flag[4] != 0)
9789 geometry_info.psi=argument_list[4].real_reference;
9790 if (attribute_flag[5] != 0)
9791 channel=(ChannelType) argument_list[5].integer_reference;
9792 channel_mask=SetImageChannelMask(image,channel);
9793 image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9794 geometry_info.xi,geometry_info.psi,exception);
9795 if (image != (Image *) NULL)
9796 (void) SetImageChannelMask(image,channel_mask);
9797 break;
9798 }
9799 case 70: /* MotionBlur */
9800 {
9801 if (attribute_flag[0] != 0)
9802 {
9803 flags=ParseGeometry(argument_list[0].string_reference,
9804 &geometry_info);
9805 if ((flags & SigmaValue) == 0)
9806 geometry_info.sigma=1.0;
9807 if ((flags & XiValue) == 0)
9808 geometry_info.xi=1.0;
9809 }
9810 if (attribute_flag[1] != 0)
9811 geometry_info.rho=argument_list[1].real_reference;
9812 if (attribute_flag[2] != 0)
9813 geometry_info.sigma=argument_list[2].real_reference;
9814 if (attribute_flag[3] != 0)
9815 geometry_info.xi=argument_list[3].real_reference;
9816 if (attribute_flag[4] != 0)
9817 channel=(ChannelType) argument_list[4].integer_reference;
9818 channel_mask=SetImageChannelMask(image,channel);
9819 image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9820 geometry_info.xi,exception);
9821 if (image != (Image *) NULL)
9822 (void) SetImageChannelMask(image,channel_mask);
9823 break;
9824 }
9825 case 71: /* OrderedDither */
9826 {
9827 if (attribute_flag[0] == 0)
9828 argument_list[0].string_reference="o8x8";
9829 if (attribute_flag[1] != 0)
9830 channel=(ChannelType) argument_list[1].integer_reference;
9831 channel_mask=SetImageChannelMask(image,channel);
Cristy6b93c072016-02-04 07:45:48 -05009832 (void) OrderedDitherImage(image,argument_list[0].string_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009833 exception);
9834 (void) SetImageChannelMask(image,channel_mask);
9835 break;
9836 }
9837 case 72: /* Shave */
9838 {
9839 if (attribute_flag[0] != 0)
9840 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9841 &geometry,exception);
9842 if (attribute_flag[1] != 0)
9843 geometry.width=argument_list[1].integer_reference;
9844 if (attribute_flag[2] != 0)
9845 geometry.height=argument_list[2].integer_reference;
9846 image=ShaveImage(image,&geometry,exception);
9847 break;
9848 }
9849 case 73: /* Level */
9850 {
9851 double
9852 black_point,
9853 gamma,
9854 white_point;
9855
9856 black_point=0.0;
9857 white_point=(double) image->columns*image->rows;
9858 gamma=1.0;
9859 if (attribute_flag[0] != 0)
9860 {
9861 flags=ParseGeometry(argument_list[0].string_reference,
9862 &geometry_info);
9863 black_point=geometry_info.rho;
9864 if ((flags & SigmaValue) != 0)
9865 white_point=geometry_info.sigma;
9866 if ((flags & XiValue) != 0)
9867 gamma=geometry_info.xi;
9868 if ((flags & PercentValue) != 0)
9869 {
9870 black_point*=(double) (QuantumRange/100.0);
9871 white_point*=(double) (QuantumRange/100.0);
9872 }
9873 if ((flags & SigmaValue) == 0)
9874 white_point=(double) QuantumRange-black_point;
9875 }
9876 if (attribute_flag[1] != 0)
9877 black_point=argument_list[1].real_reference;
9878 if (attribute_flag[2] != 0)
9879 white_point=argument_list[2].real_reference;
9880 if (attribute_flag[3] != 0)
9881 gamma=argument_list[3].real_reference;
9882 if (attribute_flag[4] != 0)
9883 channel=(ChannelType) argument_list[4].integer_reference;
9884 if (attribute_flag[5] != 0)
9885 {
9886 argument_list[0].real_reference=argument_list[5].real_reference;
9887 attribute_flag[0]=attribute_flag[5];
9888 }
9889 channel_mask=SetImageChannelMask(image,channel);
9890 (void) LevelImage(image,black_point,white_point,gamma,exception);
9891 (void) SetImageChannelMask(image,channel_mask);
9892 break;
9893 }
9894 case 74: /* Clip */
9895 {
9896 if (attribute_flag[0] == 0)
9897 argument_list[0].string_reference="#1";
9898 if (attribute_flag[1] == 0)
9899 argument_list[1].integer_reference=MagickTrue;
9900 (void) ClipImagePath(image,argument_list[0].string_reference,
9901 argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9902 exception);
9903 break;
9904 }
9905 case 75: /* AffineTransform */
9906 {
9907 DrawInfo
9908 *draw_info;
9909
9910 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9911 (DrawInfo *) NULL);
9912 if (attribute_flag[0] != 0)
9913 {
9914 AV
9915 *av;
9916
9917 av=(AV *) argument_list[0].array_reference;
9918 if ((av_len(av) != 3) && (av_len(av) != 5))
9919 {
9920 ThrowPerlException(exception,OptionError,
9921 "affine matrix must have 4 or 6 elements",PackageName);
9922 goto PerlException;
9923 }
9924 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9925 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9926 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9927 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9928 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9929 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9930 {
9931 ThrowPerlException(exception,OptionError,
9932 "affine matrix is singular",PackageName);
9933 goto PerlException;
9934 }
9935 if (av_len(av) == 5)
9936 {
9937 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9938 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9939 }
9940 }
9941 for (j=1; j < 6; j++)
9942 {
9943 if (attribute_flag[j] == 0)
9944 continue;
9945 value=argument_list[j].string_reference;
9946 angle=argument_list[j].real_reference;
9947 current=draw_info->affine;
9948 GetAffineMatrix(&affine);
9949 switch (j)
9950 {
9951 case 1:
9952 {
9953 /*
9954 Translate.
9955 */
9956 flags=ParseGeometry(value,&geometry_info);
9957 affine.tx=geometry_info.xi;
9958 affine.ty=geometry_info.psi;
9959 if ((flags & PsiValue) == 0)
9960 affine.ty=affine.tx;
9961 break;
9962 }
9963 case 2:
9964 {
9965 /*
9966 Scale.
9967 */
9968 flags=ParseGeometry(value,&geometry_info);
9969 affine.sx=geometry_info.rho;
9970 affine.sy=geometry_info.sigma;
9971 if ((flags & SigmaValue) == 0)
9972 affine.sy=affine.sx;
9973 break;
9974 }
9975 case 3:
9976 {
9977 /*
9978 Rotate.
9979 */
9980 if (angle == 0.0)
9981 break;
9982 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9983 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9984 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9985 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9986 break;
9987 }
9988 case 4:
9989 {
9990 /*
9991 SkewX.
9992 */
9993 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9994 break;
9995 }
9996 case 5:
9997 {
9998 /*
9999 SkewY.
10000 */
10001 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
10002 break;
10003 }
10004 }
10005 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
10006 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
10007 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
10008 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
10009 draw_info->affine.tx=
10010 current.sx*affine.tx+current.ry*affine.ty+current.tx;
10011 draw_info->affine.ty=
10012 current.rx*affine.tx+current.sy*affine.ty+current.ty;
10013 }
10014 if (attribute_flag[6] != 0)
10015 image->interpolate=(PixelInterpolateMethod)
10016 argument_list[6].integer_reference;
10017 if (attribute_flag[7] != 0)
10018 QueryColorCompliance(argument_list[7].string_reference,
10019 AllCompliance,&image->background_color,exception);
10020 image=AffineTransformImage(image,&draw_info->affine,exception);
10021 draw_info=DestroyDrawInfo(draw_info);
10022 break;
10023 }
10024 case 76: /* Difference */
10025 {
10026 if (attribute_flag[0] == 0)
10027 {
10028 ThrowPerlException(exception,OptionError,
10029 "ReferenceImageRequired",PackageName);
10030 goto PerlException;
10031 }
10032 if (attribute_flag[1] != 0)
10033 image->fuzz=StringToDoubleInterval(
10034 argument_list[1].string_reference,(double) QuantumRange+1.0);
Cristyf2479812015-12-12 12:17:43 -050010035 (void) SetImageColorMetric(image,argument_list[0].image_reference,
cristy4a3ce0a2013-08-03 20:06:59 +000010036 exception);
10037 break;
10038 }
10039 case 77: /* AdaptiveThreshold */
10040 {
10041 if (attribute_flag[0] != 0)
10042 {
10043 flags=ParseGeometry(argument_list[0].string_reference,
10044 &geometry_info);
10045 if ((flags & PercentValue) != 0)
10046 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10047 }
10048 if (attribute_flag[1] != 0)
10049 geometry_info.rho=argument_list[1].integer_reference;
10050 if (attribute_flag[2] != 0)
10051 geometry_info.sigma=argument_list[2].integer_reference;
10052 if (attribute_flag[3] != 0)
10053 geometry_info.xi=argument_list[3].integer_reference;;
10054 image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
10055 (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
10056 break;
10057 }
10058 case 78: /* Resample */
10059 {
10060 size_t
10061 height,
10062 width;
10063
10064 if (attribute_flag[0] != 0)
10065 {
10066 flags=ParseGeometry(argument_list[0].string_reference,
10067 &geometry_info);
10068 if ((flags & SigmaValue) == 0)
10069 geometry_info.sigma=geometry_info.rho;
10070 }
10071 if (attribute_flag[1] != 0)
10072 geometry_info.rho=argument_list[1].real_reference;
10073 if (attribute_flag[2] != 0)
10074 geometry_info.sigma=argument_list[2].real_reference;
10075 if (attribute_flag[3] == 0)
10076 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
10077 if (attribute_flag[4] == 0)
10078 SetImageArtifact(image,"filter:support",
10079 argument_list[4].string_reference);
10080 width=(size_t) (geometry_info.rho*image->columns/
10081 (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
10082 height=(size_t) (geometry_info.sigma*image->rows/
10083 (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
Cristy8645e042016-02-03 16:35:29 -050010084 image=ResizeImage(image,width,height,(FilterType)
cristy4a3ce0a2013-08-03 20:06:59 +000010085 argument_list[3].integer_reference,exception);
10086 if (image != (Image *) NULL)
10087 {
10088 image->resolution.x=geometry_info.rho;
10089 image->resolution.y=geometry_info.sigma;
10090 }
10091 break;
10092 }
10093 case 79: /* Describe */
10094 {
10095 if (attribute_flag[0] == 0)
10096 argument_list[0].file_reference=(FILE *) NULL;
10097 if (attribute_flag[1] != 0)
10098 (void) SetImageArtifact(image,"identify:features",
10099 argument_list[1].string_reference);
10100 (void) IdentifyImage(image,argument_list[0].file_reference,
10101 MagickTrue,exception);
10102 break;
10103 }
10104 case 80: /* BlackThreshold */
10105 {
10106 if (attribute_flag[0] == 0)
10107 argument_list[0].string_reference="50%";
10108 if (attribute_flag[2] != 0)
10109 channel=(ChannelType) argument_list[2].integer_reference;
10110 channel_mask=SetImageChannelMask(image,channel);
10111 BlackThresholdImage(image,argument_list[0].string_reference,
10112 exception);
10113 (void) SetImageChannelMask(image,channel_mask);
10114 break;
10115 }
10116 case 81: /* WhiteThreshold */
10117 {
10118 if (attribute_flag[0] == 0)
10119 argument_list[0].string_reference="50%";
10120 if (attribute_flag[2] != 0)
10121 channel=(ChannelType) argument_list[2].integer_reference;
10122 channel_mask=SetImageChannelMask(image,channel);
10123 WhiteThresholdImage(image,argument_list[0].string_reference,
10124 exception);
10125 (void) SetImageChannelMask(image,channel_mask);
10126 break;
10127 }
cristy60c73c02014-03-25 12:09:58 +000010128 case 82: /* RotationalBlur */
cristy4a3ce0a2013-08-03 20:06:59 +000010129 {
10130 if (attribute_flag[0] != 0)
10131 {
10132 flags=ParseGeometry(argument_list[0].string_reference,
10133 &geometry_info);
10134 }
10135 if (attribute_flag[1] != 0)
10136 geometry_info.rho=argument_list[1].real_reference;
10137 if (attribute_flag[2] != 0)
10138 channel=(ChannelType) argument_list[2].integer_reference;
10139 channel_mask=SetImageChannelMask(image,channel);
cristy49d4d222014-03-16 00:37:58 +000010140 image=RotationalBlurImage(image,geometry_info.rho,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010141 if (image != (Image *) NULL)
10142 (void) SetImageChannelMask(image,channel_mask);
10143 break;
10144 }
10145 case 83: /* Thumbnail */
10146 {
10147 if (attribute_flag[0] != 0)
10148 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10149 &geometry,exception);
10150 if (attribute_flag[1] != 0)
10151 geometry.width=argument_list[1].integer_reference;
10152 if (attribute_flag[2] != 0)
10153 geometry.height=argument_list[2].integer_reference;
10154 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10155 break;
10156 }
10157 case 84: /* Strip */
10158 {
10159 (void) StripImage(image,exception);
10160 break;
10161 }
10162 case 85: /* Tint */
10163 {
10164 PixelInfo
10165 tint;
10166
10167 GetPixelInfo(image,&tint);
10168 if (attribute_flag[0] != 0)
10169 (void) QueryColorCompliance(argument_list[0].string_reference,
10170 AllCompliance,&tint,exception);
10171 if (attribute_flag[1] == 0)
10172 argument_list[1].string_reference="100";
10173 image=TintImage(image,argument_list[1].string_reference,&tint,
10174 exception);
10175 break;
10176 }
10177 case 86: /* Channel */
10178 {
10179 if (attribute_flag[0] != 0)
10180 channel=(ChannelType) argument_list[0].integer_reference;
10181 image=SeparateImage(image,channel,exception);
10182 break;
10183 }
10184 case 87: /* Splice */
10185 {
cristy260bd762014-08-15 12:46:34 +000010186 if (attribute_flag[7] != 0)
10187 image->gravity=(GravityType) argument_list[7].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010188 if (attribute_flag[0] != 0)
10189 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10190 &geometry,exception);
10191 if (attribute_flag[1] != 0)
10192 geometry.width=argument_list[1].integer_reference;
10193 if (attribute_flag[2] != 0)
10194 geometry.height=argument_list[2].integer_reference;
10195 if (attribute_flag[3] != 0)
10196 geometry.x=argument_list[3].integer_reference;
10197 if (attribute_flag[4] != 0)
10198 geometry.y=argument_list[4].integer_reference;
10199 if (attribute_flag[5] != 0)
10200 image->fuzz=StringToDoubleInterval(
10201 argument_list[5].string_reference,(double) QuantumRange+1.0);
10202 if (attribute_flag[6] != 0)
10203 (void) QueryColorCompliance(argument_list[6].string_reference,
10204 AllCompliance,&image->background_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010205 image=SpliceImage(image,&geometry,exception);
10206 break;
10207 }
10208 case 88: /* Posterize */
10209 {
10210 if (attribute_flag[0] == 0)
10211 argument_list[0].integer_reference=3;
10212 if (attribute_flag[1] == 0)
10213 argument_list[1].integer_reference=0;
10214 (void) PosterizeImage(image,argument_list[0].integer_reference,
10215 argument_list[1].integer_reference ? RiemersmaDitherMethod :
10216 NoDitherMethod,exception);
10217 break;
10218 }
10219 case 89: /* Shadow */
10220 {
10221 if (attribute_flag[0] != 0)
10222 {
10223 flags=ParseGeometry(argument_list[0].string_reference,
10224 &geometry_info);
10225 if ((flags & SigmaValue) == 0)
10226 geometry_info.sigma=1.0;
10227 if ((flags & XiValue) == 0)
10228 geometry_info.xi=4.0;
10229 if ((flags & PsiValue) == 0)
10230 geometry_info.psi=4.0;
10231 }
10232 if (attribute_flag[1] != 0)
10233 geometry_info.rho=argument_list[1].real_reference;
10234 if (attribute_flag[2] != 0)
10235 geometry_info.sigma=argument_list[2].real_reference;
10236 if (attribute_flag[3] != 0)
10237 geometry_info.xi=argument_list[3].integer_reference;
10238 if (attribute_flag[4] != 0)
10239 geometry_info.psi=argument_list[4].integer_reference;
10240 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10241 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10242 ceil(geometry_info.psi-0.5),exception);
10243 break;
10244 }
10245 case 90: /* Identify */
10246 {
10247 if (attribute_flag[0] == 0)
10248 argument_list[0].file_reference=(FILE *) NULL;
10249 if (attribute_flag[1] != 0)
10250 (void) SetImageArtifact(image,"identify:features",
10251 argument_list[1].string_reference);
10252 if ((attribute_flag[2] != 0) &&
10253 (argument_list[2].integer_reference != 0))
10254 (void) SetImageArtifact(image,"identify:unique","true");
10255 (void) IdentifyImage(image,argument_list[0].file_reference,
10256 MagickTrue,exception);
10257 break;
10258 }
10259 case 91: /* SepiaTone */
10260 {
10261 if (attribute_flag[0] == 0)
10262 argument_list[0].real_reference=80.0*QuantumRange/100.0;
10263 image=SepiaToneImage(image,argument_list[0].real_reference,
10264 exception);
10265 break;
10266 }
10267 case 92: /* SigmoidalContrast */
10268 {
10269 MagickBooleanType
10270 sharpen;
10271
10272 if (attribute_flag[0] != 0)
10273 {
10274 flags=ParseGeometry(argument_list[0].string_reference,
10275 &geometry_info);
10276 if ((flags & SigmaValue) == 0)
10277 geometry_info.sigma=QuantumRange/2.0;
10278 if ((flags & PercentValue) != 0)
10279 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10280 }
10281 if (attribute_flag[1] != 0)
10282 geometry_info.rho=argument_list[1].real_reference;
10283 if (attribute_flag[2] != 0)
10284 geometry_info.sigma=argument_list[2].real_reference;
10285 if (attribute_flag[3] != 0)
10286 channel=(ChannelType) argument_list[3].integer_reference;
10287 sharpen=MagickTrue;
10288 if (attribute_flag[4] != 0)
10289 sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10290 MagickFalse;
10291 channel_mask=SetImageChannelMask(image,channel);
10292 (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10293 geometry_info.sigma,exception);
10294 (void) SetImageChannelMask(image,channel_mask);
10295 break;
10296 }
10297 case 93: /* Extent */
10298 {
10299 if (attribute_flag[7] != 0)
10300 image->gravity=(GravityType) argument_list[7].integer_reference;
10301 if (attribute_flag[0] != 0)
10302 {
10303 int
10304 flags;
10305
10306 flags=ParseGravityGeometry(image,
10307 argument_list[0].string_reference,&geometry,exception);
10308 (void) flags;
10309 if (geometry.width == 0)
10310 geometry.width=image->columns;
10311 if (geometry.height == 0)
10312 geometry.height=image->rows;
10313 }
10314 if (attribute_flag[1] != 0)
10315 geometry.width=argument_list[1].integer_reference;
10316 if (attribute_flag[2] != 0)
10317 geometry.height=argument_list[2].integer_reference;
10318 if (attribute_flag[3] != 0)
10319 geometry.x=argument_list[3].integer_reference;
10320 if (attribute_flag[4] != 0)
10321 geometry.y=argument_list[4].integer_reference;
10322 if (attribute_flag[5] != 0)
10323 image->fuzz=StringToDoubleInterval(
10324 argument_list[5].string_reference,(double) QuantumRange+1.0);
10325 if (attribute_flag[6] != 0)
10326 (void) QueryColorCompliance(argument_list[6].string_reference,
10327 AllCompliance,&image->background_color,exception);
10328 image=ExtentImage(image,&geometry,exception);
10329 break;
10330 }
10331 case 94: /* Vignette */
10332 {
10333 if (attribute_flag[0] != 0)
10334 {
10335 flags=ParseGeometry(argument_list[0].string_reference,
10336 &geometry_info);
10337 if ((flags & SigmaValue) == 0)
10338 geometry_info.sigma=1.0;
10339 if ((flags & XiValue) == 0)
10340 geometry_info.xi=0.1*image->columns;
10341 if ((flags & PsiValue) == 0)
10342 geometry_info.psi=0.1*image->rows;
10343 }
10344 if (attribute_flag[1] != 0)
10345 geometry_info.rho=argument_list[1].real_reference;
10346 if (attribute_flag[2] != 0)
10347 geometry_info.sigma=argument_list[2].real_reference;
10348 if (attribute_flag[3] != 0)
10349 geometry_info.xi=argument_list[3].integer_reference;
10350 if (attribute_flag[4] != 0)
10351 geometry_info.psi=argument_list[4].integer_reference;
10352 if (attribute_flag[5] != 0)
10353 (void) QueryColorCompliance(argument_list[5].string_reference,
10354 AllCompliance,&image->background_color,exception);
10355 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10356 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10357 ceil(geometry_info.psi-0.5),exception);
10358 break;
10359 }
10360 case 95: /* ContrastStretch */
10361 {
10362 double
10363 black_point,
10364 white_point;
10365
10366 black_point=0.0;
10367 white_point=(double) image->columns*image->rows;
10368 if (attribute_flag[0] != 0)
10369 {
10370 flags=ParseGeometry(argument_list[0].string_reference,
10371 &geometry_info);
10372 black_point=geometry_info.rho;
10373 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10374 black_point;
10375 if ((flags & PercentValue) != 0)
10376 {
10377 black_point*=(double) image->columns*image->rows/100.0;
10378 white_point*=(double) image->columns*image->rows/100.0;
10379 }
10380 white_point=(double) image->columns*image->rows-
10381 white_point;
10382 }
10383 if (attribute_flag[1] != 0)
10384 black_point=argument_list[1].real_reference;
10385 if (attribute_flag[2] != 0)
10386 white_point=argument_list[2].real_reference;
10387 if (attribute_flag[4] != 0)
10388 channel=(ChannelType) argument_list[4].integer_reference;
10389 channel_mask=SetImageChannelMask(image,channel);
10390 (void) ContrastStretchImage(image,black_point,white_point,exception);
10391 (void) SetImageChannelMask(image,channel_mask);
10392 break;
10393 }
10394 case 96: /* Sans0 */
10395 {
10396 break;
10397 }
10398 case 97: /* Sans1 */
10399 {
10400 break;
10401 }
10402 case 98: /* AdaptiveSharpen */
10403 {
10404 if (attribute_flag[0] != 0)
10405 {
10406 flags=ParseGeometry(argument_list[0].string_reference,
10407 &geometry_info);
10408 if ((flags & SigmaValue) == 0)
10409 geometry_info.sigma=1.0;
10410 if ((flags & XiValue) == 0)
10411 geometry_info.xi=0.0;
10412 }
10413 if (attribute_flag[1] != 0)
10414 geometry_info.rho=argument_list[1].real_reference;
10415 if (attribute_flag[2] != 0)
10416 geometry_info.sigma=argument_list[2].real_reference;
10417 if (attribute_flag[3] != 0)
10418 geometry_info.xi=argument_list[3].real_reference;
10419 if (attribute_flag[4] != 0)
10420 channel=(ChannelType) argument_list[4].integer_reference;
10421 channel_mask=SetImageChannelMask(image,channel);
10422 image=AdaptiveSharpenImage(image,geometry_info.rho,
10423 geometry_info.sigma,exception);
10424 if (image != (Image *) NULL)
10425 (void) SetImageChannelMask(image,channel_mask);
10426 break;
10427 }
10428 case 99: /* Transpose */
10429 {
10430 image=TransposeImage(image,exception);
10431 break;
10432 }
10433 case 100: /* Tranverse */
10434 {
10435 image=TransverseImage(image,exception);
10436 break;
10437 }
10438 case 101: /* AutoOrient */
10439 {
10440 image=AutoOrientImage(image,image->orientation,exception);
10441 break;
10442 }
10443 case 102: /* AdaptiveBlur */
10444 {
10445 if (attribute_flag[0] != 0)
10446 {
10447 flags=ParseGeometry(argument_list[0].string_reference,
10448 &geometry_info);
10449 if ((flags & SigmaValue) == 0)
10450 geometry_info.sigma=1.0;
10451 if ((flags & XiValue) == 0)
10452 geometry_info.xi=0.0;
10453 }
10454 if (attribute_flag[1] != 0)
10455 geometry_info.rho=argument_list[1].real_reference;
10456 if (attribute_flag[2] != 0)
10457 geometry_info.sigma=argument_list[2].real_reference;
10458 if (attribute_flag[3] != 0)
10459 channel=(ChannelType) argument_list[3].integer_reference;
10460 channel_mask=SetImageChannelMask(image,channel);
10461 image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10462 exception);
10463 if (image != (Image *) NULL)
10464 (void) SetImageChannelMask(image,channel_mask);
10465 break;
10466 }
10467 case 103: /* Sketch */
10468 {
10469 if (attribute_flag[0] != 0)
10470 {
10471 flags=ParseGeometry(argument_list[0].string_reference,
10472 &geometry_info);
10473 if ((flags & SigmaValue) == 0)
10474 geometry_info.sigma=1.0;
10475 if ((flags & XiValue) == 0)
10476 geometry_info.xi=1.0;
10477 }
10478 if (attribute_flag[1] != 0)
10479 geometry_info.rho=argument_list[1].real_reference;
10480 if (attribute_flag[2] != 0)
10481 geometry_info.sigma=argument_list[2].real_reference;
10482 if (attribute_flag[3] != 0)
10483 geometry_info.xi=argument_list[3].real_reference;
10484 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10485 geometry_info.xi,exception);
10486 break;
10487 }
10488 case 104: /* UniqueColors */
10489 {
10490 image=UniqueImageColors(image,exception);
10491 break;
10492 }
10493 case 105: /* AdaptiveResize */
10494 {
10495 if (attribute_flag[0] != 0)
10496 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10497 &geometry,exception);
10498 if (attribute_flag[1] != 0)
10499 geometry.width=argument_list[1].integer_reference;
10500 if (attribute_flag[2] != 0)
10501 geometry.height=argument_list[2].integer_reference;
10502 if (attribute_flag[3] != 0)
Cristy8645e042016-02-03 16:35:29 -050010503 image->filter=(FilterType) argument_list[4].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010504 if (attribute_flag[4] != 0)
10505 SetImageArtifact(image,"filter:support",
10506 argument_list[4].string_reference);
10507 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10508 exception);
10509 break;
10510 }
10511 case 106: /* ClipMask */
10512 {
10513 Image
10514 *mask_image;
10515
10516 if (attribute_flag[0] == 0)
10517 {
10518 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10519 PackageName);
10520 goto PerlException;
10521 }
10522 mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10523 exception);
cristy1f7ffb72015-07-29 11:07:03 +000010524 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010525 mask_image=DestroyImage(mask_image);
10526 break;
10527 }
10528 case 107: /* LinearStretch */
10529 {
10530 double
10531 black_point,
10532 white_point;
10533
10534 black_point=0.0;
10535 white_point=(double) image->columns*image->rows;
10536 if (attribute_flag[0] != 0)
10537 {
10538 flags=ParseGeometry(argument_list[0].string_reference,
10539 &geometry_info);
10540 if ((flags & SigmaValue) != 0)
10541 white_point=geometry_info.sigma;
10542 if ((flags & PercentValue) != 0)
10543 {
10544 black_point*=(double) image->columns*image->rows/100.0;
10545 white_point*=(double) image->columns*image->rows/100.0;
10546 }
10547 if ((flags & SigmaValue) == 0)
10548 white_point=(double) image->columns*image->rows-black_point;
10549 }
10550 if (attribute_flag[1] != 0)
10551 black_point=argument_list[1].real_reference;
10552 if (attribute_flag[2] != 0)
10553 white_point=argument_list[2].real_reference;
10554 (void) LinearStretchImage(image,black_point,white_point,exception);
10555 break;
10556 }
10557 case 108: /* ColorMatrix */
10558 {
10559 AV
10560 *av;
10561
10562 double
10563 *color_matrix;
10564
10565 KernelInfo
10566 *kernel_info;
10567
10568 size_t
10569 order;
10570
10571 if (attribute_flag[0] == 0)
10572 break;
10573 av=(AV *) argument_list[0].array_reference;
10574 order=(size_t) sqrt(av_len(av)+1);
10575 color_matrix=(double *) AcquireQuantumMemory(order,order*
10576 sizeof(*color_matrix));
10577 if (color_matrix == (double *) NULL)
10578 {
10579 ThrowPerlException(exception,ResourceLimitFatalError,
10580 "MemoryAllocationFailed",PackageName);
10581 goto PerlException;
10582 }
10583 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10584 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10585 for ( ; j < (ssize_t) (order*order); j++)
10586 color_matrix[j]=0.0;
cristy2c57b742014-10-31 00:40:34 +000010587 kernel_info=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010588 if (kernel_info == (KernelInfo *) NULL)
10589 break;
10590 kernel_info->width=order;
10591 kernel_info->height=order;
10592 kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10593 order*sizeof(*kernel_info->values));
10594 if (kernel_info->values != (MagickRealType *) NULL)
10595 {
10596 for (i=0; i < (ssize_t) (order*order); i++)
10597 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10598 image=ColorMatrixImage(image,kernel_info,exception);
10599 }
10600 kernel_info=DestroyKernelInfo(kernel_info);
10601 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10602 break;
10603 }
10604 case 109: /* Mask */
10605 {
10606 Image
10607 *mask_image;
10608
10609 if (attribute_flag[0] == 0)
10610 {
10611 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10612 PackageName);
10613 goto PerlException;
10614 }
10615 mask_image=CloneImage(argument_list[0].image_reference,0,0,
10616 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +000010617 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010618 mask_image=DestroyImage(mask_image);
10619 break;
10620 }
10621 case 110: /* Polaroid */
10622 {
10623 char
10624 *caption;
10625
10626 DrawInfo
10627 *draw_info;
10628
10629 double
10630 angle;
10631
10632 PixelInterpolateMethod
10633 method;
10634
10635 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10636 (DrawInfo *) NULL);
10637 caption=(char *) NULL;
10638 if (attribute_flag[0] != 0)
10639 caption=InterpretImageProperties(info ? info->image_info :
10640 (ImageInfo *) NULL,image,argument_list[0].string_reference,
10641 exception);
10642 angle=0.0;
10643 if (attribute_flag[1] != 0)
10644 angle=argument_list[1].real_reference;
10645 if (attribute_flag[2] != 0)
10646 (void) CloneString(&draw_info->font,
10647 argument_list[2].string_reference);
10648 if (attribute_flag[3] != 0)
10649 (void) QueryColorCompliance(argument_list[3].string_reference,
10650 AllCompliance,&draw_info->stroke,exception);
10651 if (attribute_flag[4] != 0)
10652 (void) QueryColorCompliance(argument_list[4].string_reference,
10653 AllCompliance,&draw_info->fill,exception);
10654 if (attribute_flag[5] != 0)
10655 draw_info->stroke_width=argument_list[5].real_reference;
10656 if (attribute_flag[6] != 0)
10657 draw_info->pointsize=argument_list[6].real_reference;
10658 if (attribute_flag[7] != 0)
10659 draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10660 if (attribute_flag[8] != 0)
10661 (void) QueryColorCompliance(argument_list[8].string_reference,
10662 AllCompliance,&image->background_color,exception);
10663 method=UndefinedInterpolatePixel;
10664 if (attribute_flag[9] != 0)
10665 method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10666 image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10667 draw_info=DestroyDrawInfo(draw_info);
10668 if (caption != (char *) NULL)
10669 caption=DestroyString(caption);
10670 break;
10671 }
10672 case 111: /* FloodfillPaint */
10673 {
10674 DrawInfo
10675 *draw_info;
10676
10677 MagickBooleanType
10678 invert;
10679
10680 PixelInfo
10681 target;
10682
10683 draw_info=CloneDrawInfo(info ? info->image_info :
10684 (ImageInfo *) NULL,(DrawInfo *) NULL);
10685 if (attribute_flag[0] != 0)
10686 flags=ParsePageGeometry(image,argument_list[0].string_reference,
10687 &geometry,exception);
10688 if (attribute_flag[1] != 0)
10689 geometry.x=argument_list[1].integer_reference;
10690 if (attribute_flag[2] != 0)
10691 geometry.y=argument_list[2].integer_reference;
10692 if (attribute_flag[3] != 0)
10693 (void) QueryColorCompliance(argument_list[3].string_reference,
10694 AllCompliance,&draw_info->fill,exception);
10695 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10696 geometry.x,geometry.y,&target,exception);
10697 if (attribute_flag[4] != 0)
10698 QueryColorCompliance(argument_list[4].string_reference,
10699 AllCompliance,&target,exception);
10700 if (attribute_flag[5] != 0)
10701 image->fuzz=StringToDoubleInterval(
10702 argument_list[5].string_reference,(double) QuantumRange+1.0);
10703 if (attribute_flag[6] != 0)
10704 channel=(ChannelType) argument_list[6].integer_reference;
10705 invert=MagickFalse;
10706 if (attribute_flag[7] != 0)
10707 invert=(MagickBooleanType) argument_list[7].integer_reference;
10708 channel_mask=SetImageChannelMask(image,channel);
10709 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10710 geometry.y,invert,exception);
10711 (void) SetImageChannelMask(image,channel_mask);
10712 draw_info=DestroyDrawInfo(draw_info);
10713 break;
10714 }
10715 case 112: /* Distort */
10716 {
10717 AV
10718 *av;
10719
10720 double
10721 *coordinates;
10722
Cristy8645e042016-02-03 16:35:29 -050010723 DistortMethod
cristy4a3ce0a2013-08-03 20:06:59 +000010724 method;
10725
10726 size_t
10727 number_coordinates;
10728
10729 VirtualPixelMethod
10730 virtual_pixel;
10731
10732 if (attribute_flag[0] == 0)
10733 break;
10734 method=UndefinedDistortion;
10735 if (attribute_flag[1] != 0)
Cristy8645e042016-02-03 16:35:29 -050010736 method=(DistortMethod) argument_list[1].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010737 av=(AV *) argument_list[0].array_reference;
10738 number_coordinates=(size_t) av_len(av)+1;
10739 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10740 sizeof(*coordinates));
10741 if (coordinates == (double *) NULL)
10742 {
10743 ThrowPerlException(exception,ResourceLimitFatalError,
10744 "MemoryAllocationFailed",PackageName);
10745 goto PerlException;
10746 }
10747 for (j=0; j < (ssize_t) number_coordinates; j++)
10748 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10749 virtual_pixel=UndefinedVirtualPixelMethod;
10750 if (attribute_flag[2] != 0)
10751 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10752 argument_list[2].integer_reference,exception);
10753 image=DistortImage(image,method,number_coordinates,coordinates,
10754 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10755 exception);
10756 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10757 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10758 exception);
10759 coordinates=(double *) RelinquishMagickMemory(coordinates);
10760 break;
10761 }
10762 case 113: /* Clut */
10763 {
10764 PixelInterpolateMethod
10765 method;
10766
10767 if (attribute_flag[0] == 0)
10768 {
10769 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10770 PackageName);
10771 goto PerlException;
10772 }
10773 method=UndefinedInterpolatePixel;
10774 if (attribute_flag[1] != 0)
10775 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10776 if (attribute_flag[2] != 0)
10777 channel=(ChannelType) argument_list[2].integer_reference;
10778 channel_mask=SetImageChannelMask(image,channel);
10779 (void) ClutImage(image,argument_list[0].image_reference,method,
10780 exception);
10781 (void) SetImageChannelMask(image,channel_mask);
10782 break;
10783 }
10784 case 114: /* LiquidRescale */
10785 {
10786 if (attribute_flag[0] != 0)
10787 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10788 &geometry,exception);
10789 if (attribute_flag[1] != 0)
10790 geometry.width=argument_list[1].integer_reference;
10791 if (attribute_flag[2] != 0)
10792 geometry.height=argument_list[2].integer_reference;
10793 if (attribute_flag[3] == 0)
10794 argument_list[3].real_reference=1.0;
10795 if (attribute_flag[4] == 0)
10796 argument_list[4].real_reference=0.0;
10797 image=LiquidRescaleImage(image,geometry.width,geometry.height,
10798 argument_list[3].real_reference,argument_list[4].real_reference,
10799 exception);
10800 break;
10801 }
10802 case 115: /* EncipherImage */
10803 {
10804 (void) EncipherImage(image,argument_list[0].string_reference,
10805 exception);
10806 break;
10807 }
10808 case 116: /* DecipherImage */
10809 {
10810 (void) DecipherImage(image,argument_list[0].string_reference,
10811 exception);
10812 break;
10813 }
10814 case 117: /* Deskew */
10815 {
10816 geometry_info.rho=QuantumRange/2.0;
10817 if (attribute_flag[0] != 0)
10818 flags=ParseGeometry(argument_list[0].string_reference,
10819 &geometry_info);
10820 if (attribute_flag[1] != 0)
10821 geometry_info.rho=StringToDoubleInterval(
10822 argument_list[1].string_reference,(double) QuantumRange+1.0);
10823 image=DeskewImage(image,geometry_info.rho,exception);
10824 break;
10825 }
10826 case 118: /* Remap */
10827 {
10828 QuantizeInfo
10829 *quantize_info;
10830
10831 if (attribute_flag[0] == 0)
10832 {
10833 ThrowPerlException(exception,OptionError,"RemapImageRequired",
10834 PackageName);
10835 goto PerlException;
10836 }
10837 quantize_info=AcquireQuantizeInfo(info->image_info);
10838 if (attribute_flag[1] != 0)
10839 quantize_info->dither_method=(DitherMethod)
10840 argument_list[1].integer_reference;
10841 (void) RemapImages(quantize_info,image,
10842 argument_list[0].image_reference,exception);
10843 quantize_info=DestroyQuantizeInfo(quantize_info);
10844 break;
10845 }
10846 case 119: /* SparseColor */
10847 {
10848 AV
10849 *av;
10850
10851 double
10852 *coordinates;
10853
10854 SparseColorMethod
10855 method;
10856
10857 size_t
10858 number_coordinates;
10859
10860 VirtualPixelMethod
10861 virtual_pixel;
10862
10863 if (attribute_flag[0] == 0)
10864 break;
10865 method=UndefinedColorInterpolate;
10866 if (attribute_flag[1] != 0)
10867 method=(SparseColorMethod) argument_list[1].integer_reference;
10868 av=(AV *) argument_list[0].array_reference;
10869 number_coordinates=(size_t) av_len(av)+1;
10870 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10871 sizeof(*coordinates));
10872 if (coordinates == (double *) NULL)
10873 {
10874 ThrowPerlException(exception,ResourceLimitFatalError,
10875 "MemoryAllocationFailed",PackageName);
10876 goto PerlException;
10877 }
10878 for (j=0; j < (ssize_t) number_coordinates; j++)
10879 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10880 virtual_pixel=UndefinedVirtualPixelMethod;
10881 if (attribute_flag[2] != 0)
10882 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10883 argument_list[2].integer_reference,exception);
10884 if (attribute_flag[3] != 0)
10885 channel=(ChannelType) argument_list[3].integer_reference;
10886 channel_mask=SetImageChannelMask(image,channel);
10887 image=SparseColorImage(image,method,number_coordinates,coordinates,
10888 exception);
10889 if (image != (Image *) NULL)
10890 (void) SetImageChannelMask(image,channel_mask);
10891 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10892 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10893 exception);
10894 coordinates=(double *) RelinquishMagickMemory(coordinates);
10895 break;
10896 }
10897 case 120: /* Function */
10898 {
10899 AV
10900 *av;
10901
10902 double
10903 *parameters;
10904
10905 MagickFunction
10906 function;
10907
10908 size_t
10909 number_parameters;
10910
10911 VirtualPixelMethod
10912 virtual_pixel;
10913
10914 if (attribute_flag[0] == 0)
10915 break;
10916 function=UndefinedFunction;
10917 if (attribute_flag[1] != 0)
10918 function=(MagickFunction) argument_list[1].integer_reference;
10919 av=(AV *) argument_list[0].array_reference;
10920 number_parameters=(size_t) av_len(av)+1;
10921 parameters=(double *) AcquireQuantumMemory(number_parameters,
10922 sizeof(*parameters));
10923 if (parameters == (double *) NULL)
10924 {
10925 ThrowPerlException(exception,ResourceLimitFatalError,
10926 "MemoryAllocationFailed",PackageName);
10927 goto PerlException;
10928 }
10929 for (j=0; j < (ssize_t) number_parameters; j++)
10930 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10931 virtual_pixel=UndefinedVirtualPixelMethod;
10932 if (attribute_flag[2] != 0)
10933 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10934 argument_list[2].integer_reference,exception);
10935 (void) FunctionImage(image,function,number_parameters,parameters,
10936 exception);
10937 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10938 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10939 exception);
10940 parameters=(double *) RelinquishMagickMemory(parameters);
10941 break;
10942 }
10943 case 121: /* SelectiveBlur */
10944 {
10945 if (attribute_flag[0] != 0)
10946 {
10947 flags=ParseGeometry(argument_list[0].string_reference,
10948 &geometry_info);
10949 if ((flags & SigmaValue) == 0)
10950 geometry_info.sigma=1.0;
10951 if ((flags & PercentValue) != 0)
10952 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10953 }
10954 if (attribute_flag[1] != 0)
10955 geometry_info.rho=argument_list[1].real_reference;
10956 if (attribute_flag[2] != 0)
10957 geometry_info.sigma=argument_list[2].real_reference;
10958 if (attribute_flag[3] != 0)
10959 geometry_info.xi=argument_list[3].integer_reference;;
10960 if (attribute_flag[5] != 0)
10961 channel=(ChannelType) argument_list[5].integer_reference;
10962 channel_mask=SetImageChannelMask(image,channel);
10963 image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10964 geometry_info.xi,exception);
10965 if (image != (Image *) NULL)
10966 (void) SetImageChannelMask(image,channel_mask);
10967 break;
10968 }
10969 case 122: /* HaldClut */
10970 {
10971 if (attribute_flag[0] == 0)
10972 {
10973 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10974 PackageName);
10975 goto PerlException;
10976 }
10977 if (attribute_flag[1] != 0)
10978 channel=(ChannelType) argument_list[1].integer_reference;
10979 channel_mask=SetImageChannelMask(image,channel);
10980 (void) HaldClutImage(image,argument_list[0].image_reference,
10981 exception);
10982 (void) SetImageChannelMask(image,channel_mask);
10983 break;
10984 }
10985 case 123: /* BlueShift */
10986 {
10987 if (attribute_flag[0] != 0)
10988 (void) ParseGeometry(argument_list[0].string_reference,
10989 &geometry_info);
10990 image=BlueShiftImage(image,geometry_info.rho,exception);
10991 break;
10992 }
10993 case 124: /* ForwardFourierTransformImage */
10994 {
10995 image=ForwardFourierTransformImage(image,
10996 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
10997 exception);
10998 break;
10999 }
11000 case 125: /* InverseFourierTransformImage */
11001 {
11002 image=InverseFourierTransformImage(image,image->next,
11003 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
11004 exception);
11005 break;
11006 }
11007 case 126: /* ColorDecisionList */
11008 {
11009 if (attribute_flag[0] == 0)
11010 argument_list[0].string_reference=(char *) NULL;
11011 (void) ColorDecisionListImage(image,
11012 argument_list[0].string_reference,exception);
11013 break;
11014 }
11015 case 127: /* AutoGamma */
11016 {
11017 if (attribute_flag[0] != 0)
11018 channel=(ChannelType) argument_list[0].integer_reference;
11019 channel_mask=SetImageChannelMask(image,channel);
11020 (void) AutoGammaImage(image,exception);
11021 (void) SetImageChannelMask(image,channel_mask);
11022 break;
11023 }
11024 case 128: /* AutoLevel */
11025 {
11026 if (attribute_flag[0] != 0)
11027 channel=(ChannelType) argument_list[0].integer_reference;
11028 channel_mask=SetImageChannelMask(image,channel);
11029 (void) AutoLevelImage(image,exception);
11030 (void) SetImageChannelMask(image,channel_mask);
11031 break;
11032 }
11033 case 129: /* LevelColors */
11034 {
11035 PixelInfo
11036 black_point,
11037 white_point;
11038
11039 (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
11040 exception);
11041 (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
11042 exception);
11043 if (attribute_flag[1] != 0)
11044 (void) QueryColorCompliance(
11045 argument_list[1].string_reference,AllCompliance,&black_point,
11046 exception);
11047 if (attribute_flag[2] != 0)
11048 (void) QueryColorCompliance(
11049 argument_list[2].string_reference,AllCompliance,&white_point,
11050 exception);
11051 if (attribute_flag[3] != 0)
11052 channel=(ChannelType) argument_list[3].integer_reference;
11053 channel_mask=SetImageChannelMask(image,channel);
11054 (void) LevelImageColors(image,&black_point,&white_point,
11055 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
11056 exception);
11057 (void) SetImageChannelMask(image,channel_mask);
11058 break;
11059 }
11060 case 130: /* Clamp */
11061 {
11062 if (attribute_flag[0] != 0)
11063 channel=(ChannelType) argument_list[0].integer_reference;
11064 channel_mask=SetImageChannelMask(image,channel);
11065 (void) ClampImage(image,exception);
11066 (void) SetImageChannelMask(image,channel_mask);
11067 break;
11068 }
11069 case 131: /* BrightnessContrast */
11070 {
11071 double
11072 brightness,
11073 contrast;
11074
11075 brightness=0.0;
11076 contrast=0.0;
11077 if (attribute_flag[0] != 0)
11078 {
11079 flags=ParseGeometry(argument_list[0].string_reference,
11080 &geometry_info);
11081 brightness=geometry_info.rho;
11082 if ((flags & SigmaValue) == 0)
11083 contrast=geometry_info.sigma;
11084 }
11085 if (attribute_flag[1] != 0)
11086 brightness=argument_list[1].real_reference;
11087 if (attribute_flag[2] != 0)
11088 contrast=argument_list[2].real_reference;
11089 if (attribute_flag[4] != 0)
11090 channel=(ChannelType) argument_list[4].integer_reference;
11091 channel_mask=SetImageChannelMask(image,channel);
11092 (void) BrightnessContrastImage(image,brightness,contrast,exception);
11093 (void) SetImageChannelMask(image,channel_mask);
11094 break;
11095 }
11096 case 132: /* Morphology */
11097 {
11098 KernelInfo
11099 *kernel;
11100
11101 MorphologyMethod
11102 method;
11103
11104 ssize_t
11105 iterations;
11106
11107 if (attribute_flag[0] == 0)
11108 break;
cristy2c57b742014-10-31 00:40:34 +000011109 kernel=AcquireKernelInfo(argument_list[0].string_reference,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011110 if (kernel == (KernelInfo *) NULL)
11111 break;
11112 if (attribute_flag[1] != 0)
11113 channel=(ChannelType) argument_list[1].integer_reference;
11114 method=UndefinedMorphology;
11115 if (attribute_flag[2] != 0)
11116 method=argument_list[2].integer_reference;
11117 iterations=1;
11118 if (attribute_flag[3] != 0)
11119 iterations=argument_list[3].integer_reference;
11120 channel_mask=SetImageChannelMask(image,channel);
11121 image=MorphologyImage(image,method,iterations,kernel,exception);
11122 if (image != (Image *) NULL)
11123 (void) SetImageChannelMask(image,channel_mask);
11124 kernel=DestroyKernelInfo(kernel);
11125 break;
11126 }
11127 case 133: /* Mode */
11128 {
11129 if (attribute_flag[0] != 0)
11130 {
11131 flags=ParseGeometry(argument_list[0].string_reference,
11132 &geometry_info);
11133 if ((flags & SigmaValue) == 0)
11134 geometry_info.sigma=1.0;
11135 }
11136 if (attribute_flag[1] != 0)
11137 geometry_info.rho=argument_list[1].real_reference;
11138 if (attribute_flag[2] != 0)
11139 geometry_info.sigma=argument_list[2].real_reference;
11140 if (attribute_flag[3] != 0)
11141 channel=(ChannelType) argument_list[3].integer_reference;
11142 channel_mask=SetImageChannelMask(image,channel);
11143 image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11144 (size_t) geometry_info.sigma,exception);
11145 if (image != (Image *) NULL)
11146 (void) SetImageChannelMask(image,channel_mask);
11147 break;
11148 }
11149 case 134: /* Statistic */
11150 {
11151 StatisticType
11152 statistic;
11153
11154 statistic=UndefinedStatistic;
11155 if (attribute_flag[0] != 0)
11156 {
11157 flags=ParseGeometry(argument_list[0].string_reference,
11158 &geometry_info);
11159 if ((flags & SigmaValue) == 0)
11160 geometry_info.sigma=1.0;
11161 }
11162 if (attribute_flag[1] != 0)
11163 geometry_info.rho=argument_list[1].real_reference;
11164 if (attribute_flag[2] != 0)
11165 geometry_info.sigma=argument_list[2].real_reference;
11166 if (attribute_flag[3] != 0)
11167 channel=(ChannelType) argument_list[3].integer_reference;
11168 if (attribute_flag[4] != 0)
11169 statistic=(StatisticType) argument_list[4].integer_reference;
11170 channel_mask=SetImageChannelMask(image,channel);
11171 image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11172 (size_t) geometry_info.sigma,exception);
11173 if (image != (Image *) NULL)
11174 (void) SetImageChannelMask(image,channel_mask);
11175 break;
11176 }
11177 case 135: /* Perceptible */
11178 {
11179 double
11180 epsilon;
11181
11182 epsilon=MagickEpsilon;
11183 if (attribute_flag[0] != 0)
11184 epsilon=argument_list[0].real_reference;
11185 if (attribute_flag[1] != 0)
11186 channel=(ChannelType) argument_list[1].integer_reference;
11187 channel_mask=SetImageChannelMask(image,channel);
11188 (void) PerceptibleImage(image,epsilon,exception);
11189 (void) SetImageChannelMask(image,channel_mask);
11190 break;
11191 }
11192 case 136: /* Poly */
11193 {
11194 AV
11195 *av;
11196
11197 double
11198 *terms;
11199
11200 size_t
11201 number_terms;
11202
11203 if (attribute_flag[0] == 0)
11204 break;
11205 if (attribute_flag[1] != 0)
11206 channel=(ChannelType) argument_list[1].integer_reference;
11207 av=(AV *) argument_list[0].array_reference;
11208 number_terms=(size_t) av_len(av);
11209 terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11210 if (terms == (double *) NULL)
11211 {
11212 ThrowPerlException(exception,ResourceLimitFatalError,
11213 "MemoryAllocationFailed",PackageName);
11214 goto PerlException;
11215 }
11216 for (j=0; j < av_len(av); j++)
11217 terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11218 image=PolynomialImage(image,number_terms >> 1,terms,exception);
11219 terms=(double *) RelinquishMagickMemory(terms);
11220 break;
11221 }
11222 case 137: /* Grayscale */
11223 {
11224 PixelIntensityMethod
11225 method;
11226
11227 method=UndefinedPixelIntensityMethod;
11228 if (attribute_flag[0] != 0)
11229 method=(PixelIntensityMethod) argument_list[0].integer_reference;
11230 (void) GrayscaleImage(image,method,exception);
11231 break;
11232 }
cristy4ceadb82014-03-29 15:30:43 +000011233 case 138: /* Canny */
11234 {
11235 if (attribute_flag[0] != 0)
11236 {
11237 flags=ParseGeometry(argument_list[0].string_reference,
11238 &geometry_info);
11239 if ((flags & SigmaValue) == 0)
11240 geometry_info.sigma=1.0;
11241 if ((flags & XiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011242 geometry_info.xi=0.10;
cristy4ceadb82014-03-29 15:30:43 +000011243 if ((flags & PsiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011244 geometry_info.psi=0.30;
cristy41814f22014-04-09 20:53:11 +000011245 if ((flags & PercentValue) != 0)
11246 {
11247 geometry_info.xi/=100.0;
11248 geometry_info.psi/=100.0;
11249 }
cristy4ceadb82014-03-29 15:30:43 +000011250 }
11251 if (attribute_flag[1] != 0)
11252 geometry_info.rho=argument_list[1].real_reference;
11253 if (attribute_flag[2] != 0)
11254 geometry_info.sigma=argument_list[2].real_reference;
11255 if (attribute_flag[3] != 0)
11256 geometry_info.xi=argument_list[3].real_reference;
11257 if (attribute_flag[4] != 0)
11258 geometry_info.psi=argument_list[4].real_reference;
11259 if (attribute_flag[5] != 0)
11260 channel=(ChannelType) argument_list[5].integer_reference;
11261 channel_mask=SetImageChannelMask(image,channel);
11262 image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11263 geometry_info.xi,geometry_info.psi,exception);
11264 if (image != (Image *) NULL)
11265 (void) SetImageChannelMask(image,channel_mask);
11266 break;
11267 }
cristy2fc10e52014-04-26 14:13:53 +000011268 case 139: /* HoughLine */
cristy4e215022014-04-19 18:02:35 +000011269 {
11270 if (attribute_flag[0] != 0)
11271 {
11272 flags=ParseGeometry(argument_list[0].string_reference,
11273 &geometry_info);
11274 if ((flags & SigmaValue) == 0)
11275 geometry_info.sigma=geometry_info.rho;
cristy20f90422014-04-27 13:34:21 +000011276 if ((flags & XiValue) == 0)
11277 geometry_info.xi=40;
cristy4e215022014-04-19 18:02:35 +000011278 }
11279 if (attribute_flag[1] != 0)
11280 geometry_info.rho=(double) argument_list[1].integer_reference;
11281 if (attribute_flag[2] != 0)
11282 geometry_info.sigma=(double) argument_list[2].integer_reference;
11283 if (attribute_flag[3] != 0)
11284 geometry_info.xi=(double) argument_list[3].integer_reference;
cristy2fc10e52014-04-26 14:13:53 +000011285 image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t)
11286 geometry_info.sigma,(size_t) geometry_info.xi,exception);
11287 break;
11288 }
11289 case 140: /* MeanShift */
11290 {
11291 if (attribute_flag[0] != 0)
11292 {
11293 flags=ParseGeometry(argument_list[0].string_reference,
11294 &geometry_info);
11295 if ((flags & SigmaValue) == 0)
11296 geometry_info.sigma=geometry_info.rho;
cristy2fc10e52014-04-26 14:13:53 +000011297 if ((flags & XiValue) == 0)
cristy1309fc32014-04-26 18:48:37 +000011298 geometry_info.xi=0.10*QuantumRange;
11299 if ((flags & PercentValue) != 0)
11300 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
cristy2fc10e52014-04-26 14:13:53 +000011301 }
11302 if (attribute_flag[1] != 0)
11303 geometry_info.rho=(double) argument_list[1].integer_reference;
11304 if (attribute_flag[2] != 0)
11305 geometry_info.sigma=(double) argument_list[2].integer_reference;
11306 if (attribute_flag[3] != 0)
11307 geometry_info.xi=(double) argument_list[3].integer_reference;
11308 image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t)
cristy1309fc32014-04-26 18:48:37 +000011309 geometry_info.sigma,geometry_info.xi,exception);
cristy4e215022014-04-19 18:02:35 +000011310 break;
11311 }
cristy3b207f82014-09-27 14:21:20 +000011312 case 141: /* Kuwahara */
11313 {
11314 if (attribute_flag[0] != 0)
11315 {
11316 flags=ParseGeometry(argument_list[0].string_reference,
11317 &geometry_info);
11318 if ((flags & SigmaValue) == 0)
cristy3a9903c2014-10-04 01:14:20 +000011319 geometry_info.sigma=geometry_info.rho-0.5;
cristy3b207f82014-09-27 14:21:20 +000011320 }
11321 if (attribute_flag[1] != 0)
11322 geometry_info.rho=argument_list[1].real_reference;
11323 if (attribute_flag[2] != 0)
11324 geometry_info.sigma=argument_list[2].real_reference;
11325 if (attribute_flag[3] != 0)
11326 channel=(ChannelType) argument_list[3].integer_reference;
11327 channel_mask=SetImageChannelMask(image,channel);
11328 image=KuwaharaImage(image,geometry_info.rho,geometry_info.sigma,
11329 exception);
11330 if (image != (Image *) NULL)
11331 (void) SetImageChannelMask(image,channel_mask);
11332 break;
11333 }
Cristy0f5df812017-07-04 18:30:05 -040011334 case 142: /* ConnectedComponents */
cristy6e0b3bc2014-10-19 17:51:42 +000011335 {
11336 size_t
11337 connectivity;
11338
11339 connectivity=4;
11340 if (attribute_flag[0] != 0)
11341 connectivity=argument_list[0].integer_reference;
Cristy2ca0e9a2016-01-01 08:36:14 -050011342 image=ConnectedComponentsImage(image,connectivity,
Cristy4f83be82015-12-31 08:40:53 -050011343 (CCObjectInfo **) NULL,exception);
cristy6e0b3bc2014-10-19 17:51:42 +000011344 break;
11345 }
cristy0b94b392015-06-22 18:56:37 +000011346 case 143: /* Copy */
11347 {
11348 Image
11349 *source_image;
11350
11351 OffsetInfo
11352 offset;
11353
cristy2ffdb092015-06-25 14:31:20 +000011354 RectangleInfo
11355 offset_geometry;
11356
cristyf3a724a2015-06-25 13:02:53 +000011357 source_image=image;
cristy0b94b392015-06-22 18:56:37 +000011358 if (attribute_flag[0] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011359 source_image=argument_list[0].image_reference;
cristy2ffdb092015-06-25 14:31:20 +000011360 SetGeometry(source_image,&geometry);
cristy0b94b392015-06-22 18:56:37 +000011361 if (attribute_flag[1] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011362 flags=ParseGravityGeometry(source_image,
11363 argument_list[1].string_reference,&geometry,exception);
cristy0b94b392015-06-22 18:56:37 +000011364 if (attribute_flag[2] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011365 geometry.width=argument_list[2].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011366 if (attribute_flag[3] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011367 geometry.height=argument_list[3].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011368 if (attribute_flag[4] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011369 geometry.x=argument_list[4].integer_reference;
11370 if (attribute_flag[5] != 0)
11371 geometry.y=argument_list[5].integer_reference;
11372 if (attribute_flag[6] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011373 image->gravity=(GravityType) argument_list[6].integer_reference;
dirk169d1642015-06-27 19:51:08 +000011374 SetGeometry(image,&offset_geometry);
cristyf3a724a2015-06-25 13:02:53 +000011375 if (attribute_flag[7] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011376 flags=ParseGravityGeometry(image,argument_list[7].string_reference,
11377 &offset_geometry,exception);
11378 offset.x=offset_geometry.x;
11379 offset.y=offset_geometry.y;
cristyf3a724a2015-06-25 13:02:53 +000011380 if (attribute_flag[8] != 0)
11381 offset.x=argument_list[8].integer_reference;
11382 if (attribute_flag[9] != 0)
11383 offset.y=argument_list[9].integer_reference;
cristycd6d5182015-06-23 17:22:15 +000011384 (void) CopyImagePixels(image,source_image,&geometry,&offset,
11385 exception);
cristy0b94b392015-06-22 18:56:37 +000011386 break;
11387 }
Cristy5488c982016-02-13 14:07:50 -050011388 case 144: /* Color */
11389 {
11390 PixelInfo
11391 color;
11392
Cristyf20e3562016-02-14 09:08:15 -050011393 (void) QueryColorCompliance("none",AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011394 if (attribute_flag[0] != 0)
Cristyf20e3562016-02-14 09:08:15 -050011395 (void) QueryColorCompliance(argument_list[0].string_reference,
11396 AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011397 (void) SetImageColor(image,&color,exception);
11398 break;
11399 }
Cristy2d830ed2016-02-21 10:54:16 -050011400 case 145: /* WaveletDenoise */
11401 {
Cristyc1759412016-02-27 12:17:58 -050011402 if (attribute_flag[0] != 0)
Cristyee21f7f2016-02-27 15:56:49 -050011403 {
11404 flags=ParseGeometry(argument_list[0].string_reference,
11405 &geometry_info);
11406 if ((flags & PercentValue) != 0)
Cristy23446632016-02-29 09:36:34 -050011407 {
11408 geometry_info.rho=QuantumRange*geometry_info.rho/100.0;
11409 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
11410 }
Cristyee21f7f2016-02-27 15:56:49 -050011411 if ((flags & SigmaValue) == 0)
11412 geometry_info.sigma=0.0;
11413 }
Cristyc1759412016-02-27 12:17:58 -050011414 if (attribute_flag[1] != 0)
11415 geometry_info.rho=argument_list[1].real_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011416 if (attribute_flag[2] != 0)
Cristyc1759412016-02-27 12:17:58 -050011417 geometry_info.sigma=argument_list[2].real_reference;
11418 if (attribute_flag[3] != 0)
11419 channel=(ChannelType) argument_list[3].integer_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011420 channel_mask=SetImageChannelMask(image,channel);
Cristyc1759412016-02-27 12:17:58 -050011421 image=WaveletDenoiseImage(image,geometry_info.rho,geometry_info.sigma,
11422 exception);
Cristy2d830ed2016-02-21 10:54:16 -050011423 if (image != (Image *) NULL)
11424 (void) SetImageChannelMask(image,channel_mask);
11425 break;
11426 }
Cristy99a57162016-12-05 11:47:57 -050011427 case 146: /* Colorspace */
11428 {
11429 ColorspaceType
11430 colorspace;
11431
11432 colorspace=sRGBColorspace;
11433 if (attribute_flag[0] != 0)
11434 colorspace=(ColorspaceType) argument_list[0].integer_reference;
11435 (void) TransformImageColorspace(image,colorspace,exception);
11436 break;
11437 }
Cristy53353872017-07-02 12:24:24 -040011438 case 147: /* AutoThreshold */
11439 {
11440 AutoThresholdMethod
11441 method;
11442
11443 method=UndefinedThresholdMethod;
11444 if (attribute_flag[0] != 0)
Cristyb63e7752017-07-02 13:22:01 -040011445 method=(AutoThresholdMethod) argument_list[0].integer_reference;
Cristy53353872017-07-02 12:24:24 -040011446 (void) AutoThresholdImage(image,method,exception);
11447 break;
11448 }
Cristy532b3382018-08-05 17:56:56 -040011449 case 148: /* RangeThreshold */
11450 {
11451 if (attribute_flag[0] != 0)
11452 {
11453 flags=ParseGeometry(argument_list[0].string_reference,
11454 &geometry_info);
11455 if ((flags & SigmaValue) == 0)
11456 geometry_info.sigma=geometry_info.rho;
11457 if ((flags & XiValue) == 0)
11458 geometry_info.xi=geometry_info.sigma;
11459 if ((flags & PsiValue) == 0)
11460 geometry_info.psi=geometry_info.xi;
11461 }
11462 if (attribute_flag[1] != 0)
11463 geometry_info.rho=argument_list[1].real_reference;
11464 if (attribute_flag[2] != 0)
11465 geometry_info.sigma=argument_list[2].real_reference;
11466 if (attribute_flag[3] != 0)
11467 geometry_info.xi=argument_list[3].real_reference;
11468 if (attribute_flag[4] != 0)
11469 geometry_info.psi=argument_list[4].real_reference;
11470 if (attribute_flag[5] != 0)
11471 channel=(ChannelType) argument_list[5].integer_reference;
11472 channel_mask=SetImageChannelMask(image,channel);
Cristy9b220db2018-08-05 18:02:28 -040011473 (void) RangeThresholdImage(image,geometry_info.rho,
11474 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
Cristy532b3382018-08-05 17:56:56 -040011475 if (image != (Image *) NULL)
11476 (void) SetImageChannelMask(image,channel_mask);
11477 break;
11478 }
Cristy9f252542018-11-21 19:13:46 -050011479 case 149: /* CLAHE */
11480 {
11481 if (attribute_flag[0] != 0)
Cristy768e9002019-01-08 07:35:16 -050011482 {
11483 flags=ParseGeometry(argument_list[0].string_reference,
11484 &geometry_info);
11485 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
11486 &geometry,exception);
11487 }
Cristy9f252542018-11-21 19:13:46 -050011488 if (attribute_flag[1] != 0)
Cristy30263282018-12-11 16:40:25 -050011489 geometry.width=argument_list[1].integer_reference;
Cristy9f252542018-11-21 19:13:46 -050011490 if (attribute_flag[2] != 0)
Cristy30263282018-12-11 16:40:25 -050011491 geometry.height=argument_list[2].integer_reference;
Cristy9f252542018-11-21 19:13:46 -050011492 if (attribute_flag[3] != 0)
Cristy768e9002019-01-08 07:35:16 -050011493 geometry.x=argument_list[3].integer_reference;
Cristy9f252542018-11-21 19:13:46 -050011494 if (attribute_flag[4] != 0)
Cristy768e9002019-01-08 07:35:16 -050011495 geometry_info.psi=argument_list[4].real_reference;
Cristyd9b98812018-12-16 09:30:05 -050011496 (void) CLAHEImage(image,geometry.width,geometry.height,geometry.x,
Cristy768e9002019-01-08 07:35:16 -050011497 geometry_info.psi,exception);
Cristy9f252542018-11-21 19:13:46 -050011498 break;
11499 }
cristy4a3ce0a2013-08-03 20:06:59 +000011500 }
11501 if (next != (Image *) NULL)
11502 (void) CatchImageException(next);
Cristy7e567962018-02-03 12:42:20 -050011503 if ((region_info.width*region_info.height) != 0)
11504 (void) SetImageRegionMask(image,WritePixelMask,
11505 (const RectangleInfo *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011506 if (image != (Image *) NULL)
11507 {
11508 number_images++;
11509 if (next && (next != image))
11510 {
11511 image->next=next->next;
11512 if (image->next != (Image *) NULL)
11513 image->next->previous=image;
11514 DeleteImageFromRegistry(*pv,next);
11515 }
11516 sv_setiv(*pv,PTR2IV(image));
11517 next=image;
11518 }
11519 if (*pv)
11520 pv++;
11521 }
11522
11523 PerlException:
11524 if (reference_vector)
11525 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11526 InheritPerlException(exception,perl_exception);
11527 exception=DestroyExceptionInfo(exception);
11528 sv_setiv(perl_exception,(IV) number_images);
11529 SvPOK_on(perl_exception);
11530 ST(0)=sv_2mortal(perl_exception);
11531 XSRETURN(1);
11532 }
11533
11534#
11535###############################################################################
11536# #
11537# #
11538# #
11539# M o n t a g e #
11540# #
11541# #
11542# #
11543###############################################################################
11544#
11545#
11546void
11547Montage(ref,...)
11548 Image::Magick ref=NO_INIT
11549 ALIAS:
11550 MontageImage = 1
11551 montage = 2
11552 montageimage = 3
11553 PPCODE:
11554 {
11555 AV
11556 *av;
11557
11558 char
11559 *attribute;
11560
11561 ExceptionInfo
11562 *exception;
11563
11564 HV
11565 *hv;
11566
11567 Image
11568 *image,
11569 *next;
11570
11571 PixelInfo
11572 transparent_color;
11573
11574 MontageInfo
11575 *montage_info;
11576
11577 register ssize_t
11578 i;
11579
11580 ssize_t
11581 sp;
11582
11583 struct PackageInfo
11584 *info;
11585
11586 SV
11587 *av_reference,
11588 *perl_exception,
11589 *reference,
11590 *rv,
11591 *sv;
11592
11593 PERL_UNUSED_VAR(ref);
11594 PERL_UNUSED_VAR(ix);
11595 exception=AcquireExceptionInfo();
11596 perl_exception=newSVpv("",0);
11597 sv=NULL;
11598 attribute=NULL;
11599 if (sv_isobject(ST(0)) == 0)
11600 {
11601 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11602 PackageName);
11603 goto PerlException;
11604 }
11605 reference=SvRV(ST(0));
11606 hv=SvSTASH(reference);
11607 av=newAV();
11608 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11609 SvREFCNT_dec(av);
11610 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11611 if (image == (Image *) NULL)
11612 {
11613 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11614 PackageName);
11615 goto PerlException;
11616 }
11617 /*
11618 Get options.
11619 */
11620 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11621 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11622 (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11623 exception);
11624 for (i=2; i < items; i+=2)
11625 {
11626 attribute=(char *) SvPV(ST(i-1),na);
11627 switch (*attribute)
11628 {
11629 case 'B':
11630 case 'b':
11631 {
11632 if (LocaleCompare(attribute,"background") == 0)
11633 {
11634 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11635 &montage_info->background_color,exception);
11636 for (next=image; next; next=next->next)
11637 next->background_color=montage_info->background_color;
11638 break;
11639 }
11640 if (LocaleCompare(attribute,"border") == 0)
11641 {
11642 montage_info->border_width=SvIV(ST(i));
11643 break;
11644 }
11645 if (LocaleCompare(attribute,"bordercolor") == 0)
11646 {
11647 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11648 &montage_info->border_color,exception);
11649 for (next=image; next; next=next->next)
11650 next->border_color=montage_info->border_color;
11651 break;
11652 }
11653 if (LocaleCompare(attribute,"borderwidth") == 0)
11654 {
11655 montage_info->border_width=SvIV(ST(i));
11656 break;
11657 }
11658 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11659 attribute);
11660 break;
11661 }
11662 case 'C':
11663 case 'c':
11664 {
11665 if (LocaleCompare(attribute,"compose") == 0)
11666 {
11667 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11668 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11669 if (sp < 0)
11670 {
11671 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11672 SvPV(ST(i),na));
11673 break;
11674 }
11675 for (next=image; next; next=next->next)
11676 next->compose=(CompositeOperator) sp;
11677 break;
11678 }
11679 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11680 attribute);
11681 break;
11682 }
11683 case 'F':
11684 case 'f':
11685 {
11686 if (LocaleCompare(attribute,"fill") == 0)
11687 {
11688 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11689 &montage_info->fill,exception);
11690 break;
11691 }
11692 if (LocaleCompare(attribute,"font") == 0)
11693 {
11694 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11695 break;
11696 }
11697 if (LocaleCompare(attribute,"frame") == 0)
11698 {
11699 char
11700 *p;
11701
11702 p=SvPV(ST(i),na);
11703 if (IsGeometry(p) == MagickFalse)
11704 {
11705 ThrowPerlException(exception,OptionError,"MissingGeometry",
11706 p);
11707 break;
11708 }
11709 (void) CloneString(&montage_info->frame,p);
11710 if (*p == '\0')
11711 montage_info->frame=(char *) NULL;
11712 break;
11713 }
11714 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11715 attribute);
11716 break;
11717 }
11718 case 'G':
11719 case 'g':
11720 {
11721 if (LocaleCompare(attribute,"geometry") == 0)
11722 {
11723 char
11724 *p;
11725
11726 p=SvPV(ST(i),na);
11727 if (IsGeometry(p) == MagickFalse)
11728 {
11729 ThrowPerlException(exception,OptionError,"MissingGeometry",
11730 p);
11731 break;
11732 }
11733 (void) CloneString(&montage_info->geometry,p);
11734 if (*p == '\0')
11735 montage_info->geometry=(char *) NULL;
11736 break;
11737 }
11738 if (LocaleCompare(attribute,"gravity") == 0)
11739 {
11740 ssize_t
11741 in;
11742
11743 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11744 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11745 if (in < 0)
11746 {
11747 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11748 SvPV(ST(i),na));
11749 return;
11750 }
11751 montage_info->gravity=(GravityType) in;
11752 for (next=image; next; next=next->next)
11753 next->gravity=(GravityType) in;
11754 break;
11755 }
11756 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11757 attribute);
11758 break;
11759 }
11760 case 'L':
11761 case 'l':
11762 {
11763 if (LocaleCompare(attribute,"label") == 0)
11764 {
11765 for (next=image; next; next=next->next)
Cristy935a4052017-03-31 17:45:37 -040011766 (void) SetImageProperty(next,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +000011767 info ? info->image_info : (ImageInfo *) NULL,next,
Cristy935a4052017-03-31 17:45:37 -040011768 SvPV(ST(i),na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011769 break;
11770 }
11771 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11772 attribute);
11773 break;
11774 }
11775 case 'M':
11776 case 'm':
11777 {
11778 if (LocaleCompare(attribute,"mattecolor") == 0)
11779 {
11780 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
Cristy8645e042016-02-03 16:35:29 -050011781 &montage_info->alpha_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011782 for (next=image; next; next=next->next)
Cristy8645e042016-02-03 16:35:29 -050011783 next->alpha_color=montage_info->alpha_color;
cristy4a3ce0a2013-08-03 20:06:59 +000011784 break;
11785 }
11786 if (LocaleCompare(attribute,"mode") == 0)
11787 {
11788 ssize_t
11789 in;
11790
11791 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11792 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11793 switch (in)
11794 {
11795 default:
11796 {
11797 ThrowPerlException(exception,OptionError,
11798 "UnrecognizedModeType",SvPV(ST(i),na));
11799 break;
11800 }
11801 case FrameMode:
11802 {
11803 (void) CloneString(&montage_info->frame,"15x15+3+3");
11804 montage_info->shadow=MagickTrue;
11805 break;
11806 }
11807 case UnframeMode:
11808 {
11809 montage_info->frame=(char *) NULL;
11810 montage_info->shadow=MagickFalse;
11811 montage_info->border_width=0;
11812 break;
11813 }
11814 case ConcatenateMode:
11815 {
11816 montage_info->frame=(char *) NULL;
11817 montage_info->shadow=MagickFalse;
11818 (void) CloneString(&montage_info->geometry,"+0+0");
11819 montage_info->border_width=0;
11820 }
11821 }
11822 break;
11823 }
11824 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11825 attribute);
11826 break;
11827 }
11828 case 'P':
11829 case 'p':
11830 {
11831 if (LocaleCompare(attribute,"pointsize") == 0)
11832 {
11833 montage_info->pointsize=SvIV(ST(i));
11834 break;
11835 }
11836 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11837 attribute);
11838 break;
11839 }
11840 case 'S':
11841 case 's':
11842 {
11843 if (LocaleCompare(attribute,"shadow") == 0)
11844 {
11845 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11846 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11847 if (sp < 0)
11848 {
11849 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11850 SvPV(ST(i),na));
11851 break;
11852 }
11853 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11854 break;
11855 }
11856 if (LocaleCompare(attribute,"stroke") == 0)
11857 {
11858 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11859 &montage_info->stroke,exception);
11860 break;
11861 }
11862 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11863 attribute);
11864 break;
11865 }
11866 case 'T':
11867 case 't':
11868 {
11869 if (LocaleCompare(attribute,"texture") == 0)
11870 {
11871 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11872 break;
11873 }
11874 if (LocaleCompare(attribute,"tile") == 0)
11875 {
11876 char *p=SvPV(ST(i),na);
11877 if (IsGeometry(p) == MagickFalse)
11878 {
11879 ThrowPerlException(exception,OptionError,"MissingGeometry",
11880 p);
11881 break;
11882 }
11883 (void) CloneString(&montage_info->tile,p);
11884 if (*p == '\0')
11885 montage_info->tile=(char *) NULL;
11886 break;
11887 }
11888 if (LocaleCompare(attribute,"title") == 0)
11889 {
11890 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11891 break;
11892 }
11893 if (LocaleCompare(attribute,"transparent") == 0)
11894 {
11895 PixelInfo
11896 transparent_color;
11897
11898 QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11899 &transparent_color,exception);
11900 for (next=image; next; next=next->next)
11901 (void) TransparentPaintImage(next,&transparent_color,
11902 TransparentAlpha,MagickFalse,exception);
11903 break;
11904 }
11905 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11906 attribute);
11907 break;
11908 }
11909 default:
11910 {
11911 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11912 attribute);
11913 break;
11914 }
11915 }
11916 }
11917 image=MontageImageList(info->image_info,montage_info,image,exception);
11918 montage_info=DestroyMontageInfo(montage_info);
11919 if (image == (Image *) NULL)
11920 goto PerlException;
11921 if (transparent_color.alpha != TransparentAlpha)
11922 for (next=image; next; next=next->next)
11923 (void) TransparentPaintImage(next,&transparent_color,
11924 TransparentAlpha,MagickFalse,exception);
11925 for ( ; image; image=image->next)
11926 {
11927 AddImageToRegistry(sv,image);
11928 rv=newRV(sv);
11929 av_push(av,sv_bless(rv,hv));
11930 SvREFCNT_dec(sv);
11931 }
11932 exception=DestroyExceptionInfo(exception);
11933 ST(0)=av_reference;
11934 SvREFCNT_dec(perl_exception);
11935 XSRETURN(1);
11936
11937 PerlException:
11938 InheritPerlException(exception,perl_exception);
11939 exception=DestroyExceptionInfo(exception);
11940 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
11941 SvPOK_on(perl_exception);
11942 ST(0)=sv_2mortal(perl_exception);
11943 XSRETURN(1);
11944 }
11945
11946#
11947###############################################################################
11948# #
11949# #
11950# #
11951# M o r p h #
11952# #
11953# #
11954# #
11955###############################################################################
11956#
11957#
11958void
11959Morph(ref,...)
11960 Image::Magick ref=NO_INIT
11961 ALIAS:
11962 MorphImage = 1
11963 morph = 2
11964 morphimage = 3
11965 PPCODE:
11966 {
11967 AV
11968 *av;
11969
11970 char
11971 *attribute;
11972
11973 ExceptionInfo
11974 *exception;
11975
11976 HV
11977 *hv;
11978
11979 Image
11980 *image;
11981
11982 register ssize_t
11983 i;
11984
11985 ssize_t
11986 number_frames;
11987
11988 struct PackageInfo
11989 *info;
11990
11991 SV
11992 *av_reference,
11993 *perl_exception,
11994 *reference,
11995 *rv,
11996 *sv;
11997
11998 PERL_UNUSED_VAR(ref);
11999 PERL_UNUSED_VAR(ix);
12000 exception=AcquireExceptionInfo();
12001 perl_exception=newSVpv("",0);
12002 sv=NULL;
12003 av=NULL;
12004 attribute=NULL;
12005 if (sv_isobject(ST(0)) == 0)
12006 {
12007 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12008 PackageName);
12009 goto PerlException;
12010 }
12011 reference=SvRV(ST(0));
12012 hv=SvSTASH(reference);
12013 av=newAV();
12014 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12015 SvREFCNT_dec(av);
12016 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12017 if (image == (Image *) NULL)
12018 {
12019 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12020 PackageName);
12021 goto PerlException;
12022 }
12023 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12024 /*
12025 Get attribute.
12026 */
12027 number_frames=30;
12028 for (i=2; i < items; i+=2)
12029 {
12030 attribute=(char *) SvPV(ST(i-1),na);
12031 switch (*attribute)
12032 {
12033 case 'F':
12034 case 'f':
12035 {
12036 if (LocaleCompare(attribute,"frames") == 0)
12037 {
12038 number_frames=SvIV(ST(i));
12039 break;
12040 }
12041 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12042 attribute);
12043 break;
12044 }
12045 default:
12046 {
12047 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12048 attribute);
12049 break;
12050 }
12051 }
12052 }
12053 image=MorphImages(image,number_frames,exception);
12054 if (image == (Image *) NULL)
12055 goto PerlException;
12056 for ( ; image; image=image->next)
12057 {
12058 AddImageToRegistry(sv,image);
12059 rv=newRV(sv);
12060 av_push(av,sv_bless(rv,hv));
12061 SvREFCNT_dec(sv);
12062 }
12063 exception=DestroyExceptionInfo(exception);
12064 ST(0)=av_reference;
12065 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12066 XSRETURN(1);
12067
12068 PerlException:
12069 InheritPerlException(exception,perl_exception);
12070 exception=DestroyExceptionInfo(exception);
12071 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12072 SvPOK_on(perl_exception);
12073 ST(0)=sv_2mortal(perl_exception);
12074 XSRETURN(1);
12075 }
12076
12077#
12078###############################################################################
12079# #
12080# #
12081# #
12082# M o s a i c #
12083# #
12084# #
12085# #
12086###############################################################################
12087#
12088#
12089void
12090Mosaic(ref)
12091 Image::Magick ref=NO_INIT
12092 ALIAS:
12093 MosaicImage = 1
12094 mosaic = 2
12095 mosaicimage = 3
12096 PPCODE:
12097 {
12098 AV
12099 *av;
12100
12101 ExceptionInfo
12102 *exception;
12103
12104 HV
12105 *hv;
12106
12107 Image
12108 *image;
12109
12110 struct PackageInfo
12111 *info;
12112
12113 SV
12114 *perl_exception,
12115 *reference,
12116 *rv,
12117 *sv;
12118
12119 PERL_UNUSED_VAR(ref);
12120 PERL_UNUSED_VAR(ix);
12121 exception=AcquireExceptionInfo();
12122 perl_exception=newSVpv("",0);
12123 sv=NULL;
12124 if (sv_isobject(ST(0)) == 0)
12125 {
12126 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12127 PackageName);
12128 goto PerlException;
12129 }
12130 reference=SvRV(ST(0));
12131 hv=SvSTASH(reference);
12132 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12133 if (image == (Image *) NULL)
12134 {
12135 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12136 PackageName);
12137 goto PerlException;
12138 }
12139 image=MergeImageLayers(image,MosaicLayer,exception);
12140 /*
12141 Create blessed Perl array for the returned image.
12142 */
12143 av=newAV();
12144 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12145 SvREFCNT_dec(av);
12146 AddImageToRegistry(sv,image);
12147 rv=newRV(sv);
12148 av_push(av,sv_bless(rv,hv));
12149 SvREFCNT_dec(sv);
cristy4a3ce0a2013-08-03 20:06:59 +000012150 (void) CopyMagickString(info->image_info->filename,image->filename,
cristy151b66d2015-04-15 10:50:31 +000012151 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012152 SetImageInfo(info->image_info,0,exception);
12153 exception=DestroyExceptionInfo(exception);
12154 SvREFCNT_dec(perl_exception);
12155 XSRETURN(1);
12156
12157 PerlException:
12158 InheritPerlException(exception,perl_exception);
12159 exception=DestroyExceptionInfo(exception);
12160 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12161 SvPOK_on(perl_exception); /* return messages in string context */
12162 ST(0)=sv_2mortal(perl_exception);
12163 XSRETURN(1);
12164 }
12165
12166#
12167###############################################################################
12168# #
12169# #
12170# #
12171# P i n g #
12172# #
12173# #
12174# #
12175###############################################################################
12176#
12177#
12178void
12179Ping(ref,...)
12180 Image::Magick ref=NO_INIT
12181 ALIAS:
12182 PingImage = 1
12183 ping = 2
12184 pingimage = 3
12185 PPCODE:
12186 {
12187 AV
12188 *av;
12189
12190 char
12191 **keep,
12192 **list;
12193
12194 ExceptionInfo
12195 *exception;
12196
12197 Image
12198 *image,
12199 *next;
12200
12201 int
12202 n;
12203
12204 MagickBooleanType
12205 status;
12206
12207 register char
12208 **p;
12209
12210 register ssize_t
12211 i;
12212
12213 ssize_t
12214 ac;
12215
12216 STRLEN
12217 *length;
12218
12219 struct PackageInfo
12220 *info,
12221 *package_info;
12222
12223 SV
12224 *perl_exception,
12225 *reference;
12226
12227 size_t
12228 count;
12229
12230 PERL_UNUSED_VAR(ref);
12231 PERL_UNUSED_VAR(ix);
12232 exception=AcquireExceptionInfo();
12233 perl_exception=newSVpv("",0);
12234 package_info=(struct PackageInfo *) NULL;
12235 ac=(items < 2) ? 1 : items-1;
12236 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12237 keep=list;
12238 length=(STRLEN *) NULL;
12239 if (list == (char **) NULL)
12240 {
12241 ThrowPerlException(exception,ResourceLimitError,
12242 "MemoryAllocationFailed",PackageName);
12243 goto PerlException;
12244 }
12245 keep=list;
12246 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12247 if (length == (STRLEN *) NULL)
12248 {
12249 ThrowPerlException(exception,ResourceLimitError,
12250 "MemoryAllocationFailed",PackageName);
12251 goto PerlException;
12252 }
12253 if (sv_isobject(ST(0)) == 0)
12254 {
12255 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12256 PackageName);
12257 goto PerlException;
12258 }
12259 reference=SvRV(ST(0));
12260 if (SvTYPE(reference) != SVt_PVAV)
12261 {
12262 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12263 PackageName);
12264 goto PerlException;
12265 }
12266 av=(AV *) reference;
12267 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12268 exception);
12269 package_info=ClonePackageInfo(info,exception);
12270 n=1;
12271 if (items <= 1)
12272 *list=(char *) (*package_info->image_info->filename ?
12273 package_info->image_info->filename : "XC:black");
12274 else
12275 for (n=0, i=0; i < ac; i++)
12276 {
12277 list[n]=(char *) SvPV(ST(i+1),length[n]);
12278 if ((items >= 3) && strEQcase(list[n],"blob"))
12279 {
12280 void
12281 *blob;
12282
12283 i++;
12284 blob=(void *) (SvPV(ST(i+1),length[n]));
12285 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12286 }
12287 if ((items >= 3) && strEQcase(list[n],"filename"))
12288 continue;
12289 if ((items >= 3) && strEQcase(list[n],"file"))
12290 {
12291 FILE
12292 *file;
12293
12294 PerlIO
12295 *io_info;
12296
12297 i++;
12298 io_info=IoIFP(sv_2io(ST(i+1)));
12299 if (io_info == (PerlIO *) NULL)
12300 {
12301 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12302 PackageName);
12303 continue;
12304 }
12305 file=PerlIO_findFILE(io_info);
12306 if (file == (FILE *) NULL)
12307 {
12308 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12309 PackageName);
12310 continue;
12311 }
12312 SetImageInfoFile(package_info->image_info,file);
12313 }
12314 if ((items >= 3) && strEQcase(list[n],"magick"))
12315 continue;
12316 n++;
12317 }
12318 list[n]=(char *) NULL;
12319 keep=list;
12320 status=ExpandFilenames(&n,&list);
12321 if (status == MagickFalse)
12322 {
12323 ThrowPerlException(exception,ResourceLimitError,
12324 "MemoryAllocationFailed",PackageName);
12325 goto PerlException;
12326 }
12327 count=0;
12328 for (i=0; i < n; i++)
12329 {
12330 (void) CopyMagickString(package_info->image_info->filename,list[i],
cristy151b66d2015-04-15 10:50:31 +000012331 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012332 image=PingImage(package_info->image_info,exception);
12333 if (image == (Image *) NULL)
12334 break;
12335 if ((package_info->image_info->file != (FILE *) NULL) ||
12336 (package_info->image_info->blob != (void *) NULL))
12337 DisassociateImageStream(image);
12338 count+=GetImageListLength(image);
12339 EXTEND(sp,4*count);
12340 for (next=image; next; next=next->next)
12341 {
12342 PUSHs(sv_2mortal(newSViv(next->columns)));
12343 PUSHs(sv_2mortal(newSViv(next->rows)));
12344 PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
12345 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
12346 }
12347 image=DestroyImageList(image);
12348 }
12349 /*
12350 Free resources.
12351 */
12352 for (i=0; i < n; i++)
12353 if (list[i] != (char *) NULL)
12354 for (p=keep; list[i] != *p++; )
12355 if (*p == NULL)
12356 {
12357 list[i]=(char *) RelinquishMagickMemory(list[i]);
12358 break;
12359 }
12360
12361 PerlException:
12362 if (package_info != (struct PackageInfo *) NULL)
12363 DestroyPackageInfo(package_info);
12364 if (list && (list != keep))
12365 list=(char **) RelinquishMagickMemory(list);
12366 if (keep)
12367 keep=(char **) RelinquishMagickMemory(keep);
12368 if (length)
12369 length=(STRLEN *) RelinquishMagickMemory(length);
12370 InheritPerlException(exception,perl_exception);
12371 exception=DestroyExceptionInfo(exception);
12372 SvREFCNT_dec(perl_exception); /* throw away all errors */
12373 }
12374
12375#
12376###############################################################################
12377# #
12378# #
12379# #
12380# P r e v i e w #
12381# #
12382# #
12383# #
12384###############################################################################
12385#
12386#
12387void
12388Preview(ref,...)
12389 Image::Magick ref=NO_INIT
12390 ALIAS:
12391 PreviewImage = 1
12392 preview = 2
12393 previewimage = 3
12394 PPCODE:
12395 {
12396 AV
12397 *av;
12398
12399 ExceptionInfo
12400 *exception;
12401
12402 HV
12403 *hv;
12404
12405 Image
12406 *image,
12407 *preview_image;
12408
12409 PreviewType
12410 preview_type;
12411
12412 struct PackageInfo
12413 *info;
12414
12415 SV
12416 *av_reference,
12417 *perl_exception,
12418 *reference,
12419 *rv,
12420 *sv;
12421
12422 PERL_UNUSED_VAR(ref);
12423 PERL_UNUSED_VAR(ix);
12424 exception=AcquireExceptionInfo();
12425 perl_exception=newSVpv("",0);
12426 sv=NULL;
12427 av=NULL;
12428 if (sv_isobject(ST(0)) == 0)
12429 {
12430 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12431 PackageName);
12432 goto PerlException;
12433 }
12434 reference=SvRV(ST(0));
12435 hv=SvSTASH(reference);
12436 av=newAV();
12437 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12438 SvREFCNT_dec(av);
12439 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12440 if (image == (Image *) NULL)
12441 {
12442 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12443 PackageName);
12444 goto PerlException;
12445 }
12446 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12447 preview_type=GammaPreview;
12448 if (items > 1)
12449 preview_type=(PreviewType)
12450 ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12451 for ( ; image; image=image->next)
12452 {
12453 preview_image=PreviewImage(image,preview_type,exception);
12454 if (preview_image == (Image *) NULL)
12455 goto PerlException;
12456 AddImageToRegistry(sv,preview_image);
12457 rv=newRV(sv);
12458 av_push(av,sv_bless(rv,hv));
12459 SvREFCNT_dec(sv);
12460 }
12461 exception=DestroyExceptionInfo(exception);
12462 ST(0)=av_reference;
12463 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12464 XSRETURN(1);
12465
12466 PerlException:
12467 InheritPerlException(exception,perl_exception);
12468 exception=DestroyExceptionInfo(exception);
12469 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12470 SvPOK_on(perl_exception);
12471 ST(0)=sv_2mortal(perl_exception);
12472 XSRETURN(1);
12473 }
12474
12475#
12476###############################################################################
12477# #
12478# #
12479# #
12480# Q u e r y C o l o r #
12481# #
12482# #
12483# #
12484###############################################################################
12485#
12486#
12487void
12488QueryColor(ref,...)
12489 Image::Magick ref=NO_INIT
12490 ALIAS:
12491 querycolor = 1
12492 PPCODE:
12493 {
12494 char
12495 *name;
12496
12497 ExceptionInfo
12498 *exception;
12499
12500 PixelInfo
12501 color;
12502
12503 register ssize_t
12504 i;
12505
12506 SV
12507 *perl_exception;
12508
12509 PERL_UNUSED_VAR(ref);
12510 PERL_UNUSED_VAR(ix);
12511 exception=AcquireExceptionInfo();
12512 perl_exception=newSVpv("",0);
12513 if (items == 1)
12514 {
12515 const ColorInfo
12516 **colorlist;
12517
12518 size_t
12519 colors;
12520
12521 colorlist=GetColorInfoList("*",&colors,exception);
12522 EXTEND(sp,colors);
12523 for (i=0; i < (ssize_t) colors; i++)
12524 {
12525 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12526 }
12527 colorlist=(const ColorInfo **)
12528 RelinquishMagickMemory((ColorInfo **) colorlist);
12529 goto PerlException;
12530 }
12531 EXTEND(sp,5*items);
12532 for (i=1; i < items; i++)
12533 {
12534 name=(char *) SvPV(ST(i),na);
12535 if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12536 {
12537 PUSHs(&sv_undef);
12538 continue;
12539 }
12540 PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12541 PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12542 PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12543 if (color.colorspace == CMYKColorspace)
12544 PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
cristy17f11b02014-12-20 19:37:04 +000012545 if (color.alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000012546 PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12547 }
12548
12549 PerlException:
12550 InheritPerlException(exception,perl_exception);
12551 exception=DestroyExceptionInfo(exception);
12552 SvREFCNT_dec(perl_exception);
12553 }
12554
12555#
12556###############################################################################
12557# #
12558# #
12559# #
12560# Q u e r y C o l o r N a m e #
12561# #
12562# #
12563# #
12564###############################################################################
12565#
12566#
12567void
12568QueryColorname(ref,...)
12569 Image::Magick ref=NO_INIT
12570 ALIAS:
12571 querycolorname = 1
12572 PPCODE:
12573 {
12574 AV
12575 *av;
12576
12577 char
cristy151b66d2015-04-15 10:50:31 +000012578 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012579
12580 ExceptionInfo
12581 *exception;
12582
12583 Image
12584 *image;
12585
12586 PixelInfo
12587 target_color;
12588
12589 register ssize_t
12590 i;
12591
12592 struct PackageInfo
12593 *info;
12594
12595 SV
12596 *perl_exception,
12597 *reference; /* reference is the SV* of ref=SvIV(reference) */
12598
12599 PERL_UNUSED_VAR(ref);
12600 PERL_UNUSED_VAR(ix);
12601 exception=AcquireExceptionInfo();
12602 perl_exception=newSVpv("",0);
12603 reference=SvRV(ST(0));
12604 av=(AV *) reference;
12605 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12606 exception);
12607 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12608 if (image == (Image *) NULL)
12609 {
12610 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12611 PackageName);
12612 goto PerlException;
12613 }
12614 EXTEND(sp,items);
12615 for (i=1; i < items; i++)
12616 {
12617 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12618 exception);
12619 (void) QueryColorname(image,&target_color,SVGCompliance,message,
12620 exception);
12621 PUSHs(sv_2mortal(newSVpv(message,0)));
12622 }
12623
12624 PerlException:
12625 InheritPerlException(exception,perl_exception);
12626 exception=DestroyExceptionInfo(exception);
12627 SvREFCNT_dec(perl_exception);
12628 }
12629
12630#
12631###############################################################################
12632# #
12633# #
12634# #
12635# Q u e r y F o n t #
12636# #
12637# #
12638# #
12639###############################################################################
12640#
12641#
12642void
12643QueryFont(ref,...)
12644 Image::Magick ref=NO_INIT
12645 ALIAS:
12646 queryfont = 1
12647 PPCODE:
12648 {
12649 char
12650 *name,
cristy151b66d2015-04-15 10:50:31 +000012651 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012652
12653 ExceptionInfo
12654 *exception;
12655
12656 register ssize_t
12657 i;
12658
12659 SV
12660 *perl_exception;
12661
12662 volatile const TypeInfo
12663 *type_info;
12664
12665 PERL_UNUSED_VAR(ref);
12666 PERL_UNUSED_VAR(ix);
12667 exception=AcquireExceptionInfo();
12668 perl_exception=newSVpv("",0);
12669 if (items == 1)
12670 {
12671 const TypeInfo
12672 **typelist;
12673
12674 size_t
12675 types;
12676
12677 typelist=GetTypeInfoList("*",&types,exception);
12678 EXTEND(sp,types);
12679 for (i=0; i < (ssize_t) types; i++)
12680 {
12681 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12682 }
12683 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12684 typelist);
12685 goto PerlException;
12686 }
12687 EXTEND(sp,10*items);
12688 for (i=1; i < items; i++)
12689 {
12690 name=(char *) SvPV(ST(i),na);
12691 type_info=GetTypeInfo(name,exception);
12692 if (type_info == (TypeInfo *) NULL)
12693 {
12694 PUSHs(&sv_undef);
12695 continue;
12696 }
12697 if (type_info->name == (char *) NULL)
12698 PUSHs(&sv_undef);
12699 else
12700 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12701 if (type_info->description == (char *) NULL)
12702 PUSHs(&sv_undef);
12703 else
12704 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12705 if (type_info->family == (char *) NULL)
12706 PUSHs(&sv_undef);
12707 else
12708 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12709 if (type_info->style == UndefinedStyle)
12710 PUSHs(&sv_undef);
12711 else
12712 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12713 type_info->style),0)));
12714 if (type_info->stretch == UndefinedStretch)
12715 PUSHs(&sv_undef);
12716 else
12717 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12718 type_info->stretch),0)));
cristy151b66d2015-04-15 10:50:31 +000012719 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +000012720 type_info->weight);
12721 PUSHs(sv_2mortal(newSVpv(message,0)));
12722 if (type_info->encoding == (char *) NULL)
12723 PUSHs(&sv_undef);
12724 else
12725 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12726 if (type_info->foundry == (char *) NULL)
12727 PUSHs(&sv_undef);
12728 else
12729 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12730 if (type_info->format == (char *) NULL)
12731 PUSHs(&sv_undef);
12732 else
12733 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12734 if (type_info->metrics == (char *) NULL)
12735 PUSHs(&sv_undef);
12736 else
12737 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12738 if (type_info->glyphs == (char *) NULL)
12739 PUSHs(&sv_undef);
12740 else
12741 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12742 }
12743
12744 PerlException:
12745 InheritPerlException(exception,perl_exception);
12746 exception=DestroyExceptionInfo(exception);
12747 SvREFCNT_dec(perl_exception);
12748 }
12749
12750#
12751###############################################################################
12752# #
12753# #
12754# #
12755# Q u e r y F o n t M e t r i c s #
12756# #
12757# #
12758# #
12759###############################################################################
12760#
12761#
12762void
12763QueryFontMetrics(ref,...)
12764 Image::Magick ref=NO_INIT
12765 ALIAS:
12766 queryfontmetrics = 1
12767 PPCODE:
12768 {
12769 AffineMatrix
12770 affine,
12771 current;
12772
12773 AV
12774 *av;
12775
12776 char
12777 *attribute;
12778
12779 double
12780 x,
12781 y;
12782
12783 DrawInfo
12784 *draw_info;
12785
12786 ExceptionInfo
12787 *exception;
12788
12789 GeometryInfo
12790 geometry_info;
12791
12792 Image
12793 *image;
12794
12795 MagickBooleanType
12796 status;
12797
12798 MagickStatusType
12799 flags;
12800
12801 register ssize_t
12802 i;
12803
12804 ssize_t
12805 type;
12806
12807 struct PackageInfo
12808 *info,
12809 *package_info;
12810
12811 SV
12812 *perl_exception,
12813 *reference; /* reference is the SV* of ref=SvIV(reference) */
12814
12815 TypeMetric
12816 metrics;
12817
12818 PERL_UNUSED_VAR(ref);
12819 PERL_UNUSED_VAR(ix);
12820 exception=AcquireExceptionInfo();
12821 package_info=(struct PackageInfo *) NULL;
12822 perl_exception=newSVpv("",0);
12823 reference=SvRV(ST(0));
12824 av=(AV *) reference;
12825 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12826 exception);
12827 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12828 if (image == (Image *) NULL)
12829 {
12830 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12831 PackageName);
12832 goto PerlException;
12833 }
12834 package_info=ClonePackageInfo(info,exception);
12835 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12836 CloneString(&draw_info->text,"");
12837 current=draw_info->affine;
12838 GetAffineMatrix(&affine);
12839 x=0.0;
12840 y=0.0;
12841 EXTEND(sp,7*items);
12842 for (i=2; i < items; i+=2)
12843 {
12844 attribute=(char *) SvPV(ST(i-1),na);
12845 switch (*attribute)
12846 {
12847 case 'A':
12848 case 'a':
12849 {
12850 if (LocaleCompare(attribute,"antialias") == 0)
12851 {
12852 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12853 SvPV(ST(i),na));
12854 if (type < 0)
12855 {
12856 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12857 SvPV(ST(i),na));
12858 break;
12859 }
12860 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12861 break;
12862 }
12863 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12864 attribute);
12865 break;
12866 }
12867 case 'd':
12868 case 'D':
12869 {
12870 if (LocaleCompare(attribute,"density") == 0)
12871 {
12872 CloneString(&draw_info->density,SvPV(ST(i),na));
12873 break;
12874 }
12875 if (LocaleCompare(attribute,"direction") == 0)
12876 {
12877 draw_info->direction=(DirectionType) ParseCommandOption(
12878 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12879 break;
12880 }
12881 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12882 attribute);
12883 break;
12884 }
12885 case 'e':
12886 case 'E':
12887 {
12888 if (LocaleCompare(attribute,"encoding") == 0)
12889 {
12890 CloneString(&draw_info->encoding,SvPV(ST(i),na));
12891 break;
12892 }
12893 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12894 attribute);
12895 break;
12896 }
12897 case 'f':
12898 case 'F':
12899 {
12900 if (LocaleCompare(attribute,"family") == 0)
12901 {
12902 CloneString(&draw_info->family,SvPV(ST(i),na));
12903 break;
12904 }
12905 if (LocaleCompare(attribute,"fill") == 0)
12906 {
12907 if (info)
12908 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12909 &draw_info->fill,exception);
12910 break;
12911 }
12912 if (LocaleCompare(attribute,"font") == 0)
12913 {
12914 CloneString(&draw_info->font,SvPV(ST(i),na));
12915 break;
12916 }
12917 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12918 attribute);
12919 break;
12920 }
12921 case 'g':
12922 case 'G':
12923 {
12924 if (LocaleCompare(attribute,"geometry") == 0)
12925 {
12926 CloneString(&draw_info->geometry,SvPV(ST(i),na));
12927 break;
12928 }
12929 if (LocaleCompare(attribute,"gravity") == 0)
12930 {
12931 draw_info->gravity=(GravityType) ParseCommandOption(
12932 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12933 break;
12934 }
12935 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12936 attribute);
12937 break;
12938 }
12939 case 'i':
12940 case 'I':
12941 {
12942 if (LocaleCompare(attribute,"interline-spacing") == 0)
12943 {
12944 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12945 draw_info->interline_spacing=geometry_info.rho;
12946 break;
12947 }
12948 if (LocaleCompare(attribute,"interword-spacing") == 0)
12949 {
12950 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12951 draw_info->interword_spacing=geometry_info.rho;
12952 break;
12953 }
12954 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12955 attribute);
12956 break;
12957 }
12958 case 'k':
12959 case 'K':
12960 {
12961 if (LocaleCompare(attribute,"kerning") == 0)
12962 {
12963 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12964 draw_info->kerning=geometry_info.rho;
12965 break;
12966 }
12967 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12968 attribute);
12969 break;
12970 }
12971 case 'p':
12972 case 'P':
12973 {
12974 if (LocaleCompare(attribute,"pointsize") == 0)
12975 {
12976 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12977 draw_info->pointsize=geometry_info.rho;
12978 break;
12979 }
12980 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12981 attribute);
12982 break;
12983 }
12984 case 'r':
12985 case 'R':
12986 {
12987 if (LocaleCompare(attribute,"rotate") == 0)
12988 {
12989 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
12990 affine.rx=geometry_info.rho;
12991 affine.ry=geometry_info.sigma;
12992 if ((flags & SigmaValue) == 0)
12993 affine.ry=affine.rx;
12994 break;
12995 }
12996 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12997 attribute);
12998 break;
12999 }
13000 case 's':
13001 case 'S':
13002 {
13003 if (LocaleCompare(attribute,"scale") == 0)
13004 {
13005 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13006 affine.sx=geometry_info.rho;
13007 affine.sy=geometry_info.sigma;
13008 if ((flags & SigmaValue) == 0)
13009 affine.sy=affine.sx;
13010 break;
13011 }
13012 if (LocaleCompare(attribute,"skew") == 0)
13013 {
13014 double
13015 x_angle,
13016 y_angle;
13017
13018 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13019 x_angle=geometry_info.rho;
13020 y_angle=geometry_info.sigma;
13021 if ((flags & SigmaValue) == 0)
13022 y_angle=x_angle;
13023 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13024 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13025 break;
13026 }
13027 if (LocaleCompare(attribute,"stroke") == 0)
13028 {
13029 if (info)
13030 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13031 &draw_info->stroke,exception);
13032 break;
13033 }
13034 if (LocaleCompare(attribute,"style") == 0)
13035 {
13036 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13037 SvPV(ST(i),na));
13038 if (type < 0)
13039 {
13040 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13041 SvPV(ST(i),na));
13042 break;
13043 }
13044 draw_info->style=(StyleType) type;
13045 break;
13046 }
13047 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13048 attribute);
13049 break;
13050 }
13051 case 't':
13052 case 'T':
13053 {
13054 if (LocaleCompare(attribute,"text") == 0)
13055 {
13056 CloneString(&draw_info->text,SvPV(ST(i),na));
13057 break;
13058 }
13059 if (LocaleCompare(attribute,"translate") == 0)
13060 {
13061 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13062 affine.tx=geometry_info.rho;
13063 affine.ty=geometry_info.sigma;
13064 if ((flags & SigmaValue) == 0)
13065 affine.ty=affine.tx;
13066 break;
13067 }
13068 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13069 attribute);
13070 break;
13071 }
13072 case 'w':
13073 case 'W':
13074 {
13075 if (LocaleCompare(attribute,"weight") == 0)
13076 {
13077 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13078 draw_info->weight=(size_t) geometry_info.rho;
13079 break;
13080 }
13081 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13082 attribute);
13083 break;
13084 }
13085 case 'x':
13086 case 'X':
13087 {
13088 if (LocaleCompare(attribute,"x") == 0)
13089 {
13090 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13091 x=geometry_info.rho;
13092 break;
13093 }
13094 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13095 attribute);
13096 break;
13097 }
13098 case 'y':
13099 case 'Y':
13100 {
13101 if (LocaleCompare(attribute,"y") == 0)
13102 {
13103 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13104 y=geometry_info.rho;
13105 break;
13106 }
13107 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13108 attribute);
13109 break;
13110 }
13111 default:
13112 {
13113 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13114 attribute);
13115 break;
13116 }
13117 }
13118 }
13119 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13120 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13121 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13122 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13123 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13124 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13125 if (draw_info->geometry == (char *) NULL)
13126 {
13127 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013128 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -050013129 "%.20g,%.20g",x,y);
cristy4a3ce0a2013-08-03 20:06:59 +000013130 }
13131 status=GetTypeMetrics(image,draw_info,&metrics,exception);
13132 (void) CatchImageException(image);
13133 if (status == MagickFalse)
13134 PUSHs(&sv_undef);
13135 else
13136 {
13137 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13138 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13139 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13140 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13141 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13142 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13143 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13144 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13145 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13146 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13147 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13148 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13149 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13150 }
13151 draw_info=DestroyDrawInfo(draw_info);
13152
13153 PerlException:
13154 if (package_info != (struct PackageInfo *) NULL)
13155 DestroyPackageInfo(package_info);
13156 InheritPerlException(exception,perl_exception);
13157 exception=DestroyExceptionInfo(exception);
13158 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13159 }
13160
13161#
13162###############################################################################
13163# #
13164# #
13165# #
13166# 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 #
13167# #
13168# #
13169# #
13170###############################################################################
13171#
13172#
13173void
13174QueryMultilineFontMetrics(ref,...)
13175 Image::Magick ref=NO_INIT
13176 ALIAS:
13177 querymultilinefontmetrics = 1
13178 PPCODE:
13179 {
13180 AffineMatrix
13181 affine,
13182 current;
13183
13184 AV
13185 *av;
13186
13187 char
13188 *attribute;
13189
13190 double
13191 x,
13192 y;
13193
13194 DrawInfo
13195 *draw_info;
13196
13197 ExceptionInfo
13198 *exception;
13199
13200 GeometryInfo
13201 geometry_info;
13202
13203 Image
13204 *image;
13205
13206 MagickBooleanType
13207 status;
13208
13209 MagickStatusType
13210 flags;
13211
13212 register ssize_t
13213 i;
13214
13215 ssize_t
13216 type;
13217
13218 struct PackageInfo
13219 *info,
13220 *package_info;
13221
13222 SV
13223 *perl_exception,
13224 *reference; /* reference is the SV* of ref=SvIV(reference) */
13225
13226 TypeMetric
13227 metrics;
13228
13229 PERL_UNUSED_VAR(ref);
13230 PERL_UNUSED_VAR(ix);
13231 exception=AcquireExceptionInfo();
13232 package_info=(struct PackageInfo *) NULL;
13233 perl_exception=newSVpv("",0);
13234 reference=SvRV(ST(0));
13235 av=(AV *) reference;
13236 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13237 exception);
13238 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13239 if (image == (Image *) NULL)
13240 {
13241 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13242 PackageName);
13243 goto PerlException;
13244 }
13245 package_info=ClonePackageInfo(info,exception);
13246 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
13247 CloneString(&draw_info->text,"");
13248 current=draw_info->affine;
13249 GetAffineMatrix(&affine);
13250 x=0.0;
13251 y=0.0;
13252 EXTEND(sp,7*items);
13253 for (i=2; i < items; i+=2)
13254 {
13255 attribute=(char *) SvPV(ST(i-1),na);
13256 switch (*attribute)
13257 {
13258 case 'A':
13259 case 'a':
13260 {
13261 if (LocaleCompare(attribute,"antialias") == 0)
13262 {
13263 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13264 SvPV(ST(i),na));
13265 if (type < 0)
13266 {
13267 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13268 SvPV(ST(i),na));
13269 break;
13270 }
13271 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
13272 break;
13273 }
13274 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13275 attribute);
13276 break;
13277 }
13278 case 'd':
13279 case 'D':
13280 {
13281 if (LocaleCompare(attribute,"density") == 0)
13282 {
13283 CloneString(&draw_info->density,SvPV(ST(i),na));
13284 break;
13285 }
13286 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13287 attribute);
13288 break;
13289 }
13290 case 'e':
13291 case 'E':
13292 {
13293 if (LocaleCompare(attribute,"encoding") == 0)
13294 {
13295 CloneString(&draw_info->encoding,SvPV(ST(i),na));
13296 break;
13297 }
13298 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13299 attribute);
13300 break;
13301 }
13302 case 'f':
13303 case 'F':
13304 {
13305 if (LocaleCompare(attribute,"family") == 0)
13306 {
13307 CloneString(&draw_info->family,SvPV(ST(i),na));
13308 break;
13309 }
13310 if (LocaleCompare(attribute,"fill") == 0)
13311 {
13312 if (info)
13313 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13314 &draw_info->fill,exception);
13315 break;
13316 }
13317 if (LocaleCompare(attribute,"font") == 0)
13318 {
13319 CloneString(&draw_info->font,SvPV(ST(i),na));
13320 break;
13321 }
13322 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13323 attribute);
13324 break;
13325 }
13326 case 'g':
13327 case 'G':
13328 {
13329 if (LocaleCompare(attribute,"geometry") == 0)
13330 {
13331 CloneString(&draw_info->geometry,SvPV(ST(i),na));
13332 break;
13333 }
13334 if (LocaleCompare(attribute,"gravity") == 0)
13335 {
13336 draw_info->gravity=(GravityType) ParseCommandOption(
13337 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13338 break;
13339 }
13340 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13341 attribute);
13342 break;
13343 }
13344 case 'p':
13345 case 'P':
13346 {
13347 if (LocaleCompare(attribute,"pointsize") == 0)
13348 {
13349 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13350 draw_info->pointsize=geometry_info.rho;
13351 break;
13352 }
13353 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13354 attribute);
13355 break;
13356 }
13357 case 'r':
13358 case 'R':
13359 {
13360 if (LocaleCompare(attribute,"rotate") == 0)
13361 {
13362 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13363 affine.rx=geometry_info.rho;
13364 affine.ry=geometry_info.sigma;
13365 if ((flags & SigmaValue) == 0)
13366 affine.ry=affine.rx;
13367 break;
13368 }
13369 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13370 attribute);
13371 break;
13372 }
13373 case 's':
13374 case 'S':
13375 {
13376 if (LocaleCompare(attribute,"scale") == 0)
13377 {
13378 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13379 affine.sx=geometry_info.rho;
13380 affine.sy=geometry_info.sigma;
13381 if ((flags & SigmaValue) == 0)
13382 affine.sy=affine.sx;
13383 break;
13384 }
13385 if (LocaleCompare(attribute,"skew") == 0)
13386 {
13387 double
13388 x_angle,
13389 y_angle;
13390
13391 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13392 x_angle=geometry_info.rho;
13393 y_angle=geometry_info.sigma;
13394 if ((flags & SigmaValue) == 0)
13395 y_angle=x_angle;
13396 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13397 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13398 break;
13399 }
13400 if (LocaleCompare(attribute,"stroke") == 0)
13401 {
13402 if (info)
13403 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13404 &draw_info->stroke,exception);
13405 break;
13406 }
13407 if (LocaleCompare(attribute,"style") == 0)
13408 {
13409 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13410 SvPV(ST(i),na));
13411 if (type < 0)
13412 {
13413 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13414 SvPV(ST(i),na));
13415 break;
13416 }
13417 draw_info->style=(StyleType) type;
13418 break;
13419 }
13420 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13421 attribute);
13422 break;
13423 }
13424 case 't':
13425 case 'T':
13426 {
13427 if (LocaleCompare(attribute,"text") == 0)
13428 {
13429 CloneString(&draw_info->text,SvPV(ST(i),na));
13430 break;
13431 }
13432 if (LocaleCompare(attribute,"translate") == 0)
13433 {
13434 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13435 affine.tx=geometry_info.rho;
13436 affine.ty=geometry_info.sigma;
13437 if ((flags & SigmaValue) == 0)
13438 affine.ty=affine.tx;
13439 break;
13440 }
13441 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13442 attribute);
13443 break;
13444 }
13445 case 'w':
13446 case 'W':
13447 {
13448 if (LocaleCompare(attribute,"weight") == 0)
13449 {
13450 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13451 draw_info->weight=(size_t) geometry_info.rho;
13452 break;
13453 }
13454 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13455 attribute);
13456 break;
13457 }
13458 case 'x':
13459 case 'X':
13460 {
13461 if (LocaleCompare(attribute,"x") == 0)
13462 {
13463 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13464 x=geometry_info.rho;
13465 break;
13466 }
13467 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13468 attribute);
13469 break;
13470 }
13471 case 'y':
13472 case 'Y':
13473 {
13474 if (LocaleCompare(attribute,"y") == 0)
13475 {
13476 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13477 y=geometry_info.rho;
13478 break;
13479 }
13480 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13481 attribute);
13482 break;
13483 }
13484 default:
13485 {
13486 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13487 attribute);
13488 break;
13489 }
13490 }
13491 }
13492 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13493 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13494 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13495 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13496 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13497 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13498 if (draw_info->geometry == (char *) NULL)
13499 {
13500 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013501 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -050013502 "%.20g,%.20g",x,y);
cristy4a3ce0a2013-08-03 20:06:59 +000013503 }
13504 status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13505 (void) CatchException(exception);
13506 if (status == MagickFalse)
13507 PUSHs(&sv_undef);
13508 else
13509 {
13510 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13511 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13512 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13513 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13514 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13515 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13516 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13517 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13518 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13519 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13520 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13521 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13522 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13523 }
13524 draw_info=DestroyDrawInfo(draw_info);
13525
13526 PerlException:
13527 if (package_info != (struct PackageInfo *) NULL)
13528 DestroyPackageInfo(package_info);
13529 InheritPerlException(exception,perl_exception);
13530 exception=DestroyExceptionInfo(exception);
13531 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13532 }
13533
13534#
13535###############################################################################
13536# #
13537# #
13538# #
13539# Q u e r y F o r m a t #
13540# #
13541# #
13542# #
13543###############################################################################
13544#
13545#
13546void
13547QueryFormat(ref,...)
13548 Image::Magick ref=NO_INIT
13549 ALIAS:
13550 queryformat = 1
13551 PPCODE:
13552 {
13553 char
13554 *name;
13555
13556 ExceptionInfo
13557 *exception;
13558
13559 register ssize_t
13560 i;
13561
13562 SV
13563 *perl_exception;
13564
13565 volatile const MagickInfo
13566 *magick_info;
13567
13568 PERL_UNUSED_VAR(ref);
13569 PERL_UNUSED_VAR(ix);
13570 exception=AcquireExceptionInfo();
13571 perl_exception=newSVpv("",0);
13572 if (items == 1)
13573 {
13574 char
cristy151b66d2015-04-15 10:50:31 +000013575 format[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013576
13577 const MagickInfo
13578 **format_list;
13579
13580 size_t
13581 types;
13582
13583 format_list=GetMagickInfoList("*",&types,exception);
13584 EXTEND(sp,types);
13585 for (i=0; i < (ssize_t) types; i++)
13586 {
cristy151b66d2015-04-15 10:50:31 +000013587 (void) CopyMagickString(format,format_list[i]->name,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000013588 LocaleLower(format);
13589 PUSHs(sv_2mortal(newSVpv(format,0)));
13590 }
13591 format_list=(const MagickInfo **)
13592 RelinquishMagickMemory((MagickInfo *) format_list);
13593 goto PerlException;
13594 }
13595 EXTEND(sp,8*items);
13596 for (i=1; i < items; i++)
13597 {
13598 name=(char *) SvPV(ST(i),na);
13599 magick_info=GetMagickInfo(name,exception);
13600 if (magick_info == (const MagickInfo *) NULL)
13601 {
13602 PUSHs(&sv_undef);
13603 continue;
13604 }
cristy4a3ce0a2013-08-03 20:06:59 +000013605 if (magick_info->description == (char *) NULL)
13606 PUSHs(&sv_undef);
13607 else
13608 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
13609 if (magick_info->module == (char *) NULL)
13610 PUSHs(&sv_undef);
13611 else
13612 PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
13613 }
13614
13615 PerlException:
13616 InheritPerlException(exception,perl_exception);
13617 exception=DestroyExceptionInfo(exception);
13618 SvREFCNT_dec(perl_exception);
13619 }
13620
13621#
13622###############################################################################
13623# #
13624# #
13625# #
13626# Q u e r y O p t i o n #
13627# #
13628# #
13629# #
13630###############################################################################
13631#
13632#
13633void
13634QueryOption(ref,...)
13635 Image::Magick ref=NO_INIT
13636 ALIAS:
13637 queryoption = 1
13638 PPCODE:
13639 {
13640 char
13641 **options;
13642
13643 ExceptionInfo
13644 *exception;
13645
13646 register ssize_t
13647 i;
13648
13649 ssize_t
13650 j,
13651 option;
13652
13653 SV
13654 *perl_exception;
13655
13656 PERL_UNUSED_VAR(ref);
13657 PERL_UNUSED_VAR(ix);
13658 exception=AcquireExceptionInfo();
13659 perl_exception=newSVpv("",0);
13660 EXTEND(sp,8*items);
13661 for (i=1; i < items; i++)
13662 {
13663 option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13664 SvPV(ST(i),na));
13665 options=GetCommandOptions((CommandOption) option);
13666 if (options == (char **) NULL)
13667 PUSHs(&sv_undef);
13668 else
13669 {
13670 for (j=0; options[j] != (char *) NULL; j++)
13671 PUSHs(sv_2mortal(newSVpv(options[j],0)));
13672 options=DestroyStringList(options);
13673 }
13674 }
13675
13676 InheritPerlException(exception,perl_exception);
13677 exception=DestroyExceptionInfo(exception);
13678 SvREFCNT_dec(perl_exception);
13679 }
13680
13681#
13682###############################################################################
13683# #
13684# #
13685# #
13686# R e a d #
13687# #
13688# #
13689# #
13690###############################################################################
13691#
13692#
13693void
13694Read(ref,...)
13695 Image::Magick ref=NO_INIT
13696 ALIAS:
13697 ReadImage = 1
13698 read = 2
13699 readimage = 3
13700 PPCODE:
13701 {
13702 AV
13703 *av;
13704
13705 char
13706 **keep,
13707 **list;
13708
13709 ExceptionInfo
13710 *exception;
13711
13712 HV
13713 *hv;
13714
13715 Image
13716 *image;
13717
13718 int
13719 n;
13720
13721 MagickBooleanType
13722 status;
13723
13724 register char
13725 **p;
13726
13727 register ssize_t
13728 i;
13729
13730 ssize_t
13731 ac,
13732 number_images;
13733
13734 STRLEN
13735 *length;
13736
13737 struct PackageInfo
13738 *info,
13739 *package_info;
13740
13741 SV
13742 *perl_exception, /* Perl variable for storing messages */
13743 *reference,
13744 *rv,
13745 *sv;
13746
13747 PERL_UNUSED_VAR(ref);
13748 PERL_UNUSED_VAR(ix);
13749 exception=AcquireExceptionInfo();
13750 perl_exception=newSVpv("",0);
13751 sv=NULL;
13752 package_info=(struct PackageInfo *) NULL;
13753 number_images=0;
13754 ac=(items < 2) ? 1 : items-1;
13755 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13756 keep=list;
13757 length=(STRLEN *) NULL;
13758 if (list == (char **) NULL)
13759 {
13760 ThrowPerlException(exception,ResourceLimitError,
13761 "MemoryAllocationFailed",PackageName);
13762 goto PerlException;
13763 }
13764 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13765 if (length == (STRLEN *) NULL)
13766 {
13767 ThrowPerlException(exception,ResourceLimitError,
13768 "MemoryAllocationFailed",PackageName);
13769 goto PerlException;
13770 }
13771 if (sv_isobject(ST(0)) == 0)
13772 {
13773 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13774 PackageName);
13775 goto PerlException;
13776 }
13777 reference=SvRV(ST(0));
13778 hv=SvSTASH(reference);
13779 if (SvTYPE(reference) != SVt_PVAV)
13780 {
13781 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13782 PackageName);
13783 goto PerlException;
13784 }
13785 av=(AV *) reference;
13786 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13787 exception);
13788 package_info=ClonePackageInfo(info,exception);
13789 n=1;
13790 if (items <= 1)
13791 *list=(char *) (*package_info->image_info->filename ?
13792 package_info->image_info->filename : "XC:black");
13793 else
13794 for (n=0, i=0; i < ac; i++)
13795 {
13796 list[n]=(char *) SvPV(ST(i+1),length[n]);
13797 if ((items >= 3) && strEQcase(list[n],"blob"))
13798 {
13799 void
13800 *blob;
13801
13802 i++;
13803 blob=(void *) (SvPV(ST(i+1),length[n]));
13804 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13805 }
13806 if ((items >= 3) && strEQcase(list[n],"filename"))
13807 continue;
13808 if ((items >= 3) && strEQcase(list[n],"file"))
13809 {
13810 FILE
13811 *file;
13812
13813 PerlIO
13814 *io_info;
13815
13816 i++;
13817 io_info=IoIFP(sv_2io(ST(i+1)));
13818 if (io_info == (PerlIO *) NULL)
13819 {
13820 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13821 PackageName);
13822 continue;
13823 }
13824 file=PerlIO_findFILE(io_info);
13825 if (file == (FILE *) NULL)
13826 {
13827 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13828 PackageName);
13829 continue;
13830 }
13831 SetImageInfoFile(package_info->image_info,file);
13832 }
13833 if ((items >= 3) && strEQcase(list[n],"magick"))
13834 continue;
13835 n++;
13836 }
13837 list[n]=(char *) NULL;
13838 keep=list;
13839 status=ExpandFilenames(&n,&list);
13840 if (status == MagickFalse)
13841 {
13842 ThrowPerlException(exception,ResourceLimitError,
13843 "MemoryAllocationFailed",PackageName);
13844 goto PerlException;
13845 }
13846 number_images=0;
13847 for (i=0; i < n; i++)
13848 {
13849 if ((package_info->image_info->file == (FILE *) NULL) &&
13850 (package_info->image_info->blob == (void *) NULL))
13851 image=ReadImages(package_info->image_info,list[i],exception);
13852 else
13853 {
13854 image=ReadImages(package_info->image_info,
13855 package_info->image_info->filename,exception);
13856 if (image != (Image *) NULL)
13857 DisassociateImageStream(image);
13858 }
13859 if (image == (Image *) NULL)
13860 break;
13861 for ( ; image; image=image->next)
13862 {
13863 AddImageToRegistry(sv,image);
13864 rv=newRV(sv);
13865 av_push(av,sv_bless(rv,hv));
13866 SvREFCNT_dec(sv);
13867 number_images++;
13868 }
13869 }
13870 /*
13871 Free resources.
13872 */
13873 for (i=0; i < n; i++)
13874 if (list[i] != (char *) NULL)
13875 for (p=keep; list[i] != *p++; )
13876 if (*p == (char *) NULL)
13877 {
13878 list[i]=(char *) RelinquishMagickMemory(list[i]);
13879 break;
13880 }
13881
13882 PerlException:
13883 if (package_info != (struct PackageInfo *) NULL)
13884 DestroyPackageInfo(package_info);
13885 if (list && (list != keep))
13886 list=(char **) RelinquishMagickMemory(list);
13887 if (keep)
13888 keep=(char **) RelinquishMagickMemory(keep);
13889 if (length)
13890 length=(STRLEN *) RelinquishMagickMemory(length);
13891 InheritPerlException(exception,perl_exception);
13892 exception=DestroyExceptionInfo(exception);
13893 sv_setiv(perl_exception,(IV) number_images);
13894 SvPOK_on(perl_exception);
13895 ST(0)=sv_2mortal(perl_exception);
13896 XSRETURN(1);
13897 }
13898
13899#
13900###############################################################################
13901# #
13902# #
13903# #
13904# R e m o t e #
13905# #
13906# #
13907# #
13908###############################################################################
13909#
13910#
13911void
13912Remote(ref,...)
13913 Image::Magick ref=NO_INIT
13914 ALIAS:
13915 RemoteCommand = 1
13916 remote = 2
13917 remoteCommand = 3
13918 PPCODE:
13919 {
13920 AV
13921 *av;
13922
13923 ExceptionInfo
13924 *exception;
13925
13926 register ssize_t
13927 i;
13928
13929 SV
13930 *perl_exception,
13931 *reference;
13932
13933 struct PackageInfo
13934 *info;
13935
13936 PERL_UNUSED_VAR(ref);
13937 PERL_UNUSED_VAR(ix);
13938 exception=AcquireExceptionInfo();
13939 perl_exception=newSVpv("",0);
13940 reference=SvRV(ST(0));
13941 av=(AV *) reference;
13942 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13943 exception);
13944 for (i=1; i < items; i++)
13945 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
13946 SvPV(ST(i),na),exception);
13947 InheritPerlException(exception,perl_exception);
13948 exception=DestroyExceptionInfo(exception);
13949 SvREFCNT_dec(perl_exception); /* throw away all errors */
13950 }
13951
13952#
13953###############################################################################
13954# #
13955# #
13956# #
13957# S e t #
13958# #
13959# #
13960# #
13961###############################################################################
13962#
13963#
13964void
13965Set(ref,...)
13966 Image::Magick ref=NO_INIT
13967 ALIAS:
13968 SetAttributes = 1
13969 SetAttribute = 2
13970 set = 3
13971 setattributes = 4
13972 setattribute = 5
13973 PPCODE:
13974 {
13975 ExceptionInfo
13976 *exception;
13977
13978 Image
13979 *image;
13980
13981 register ssize_t
13982 i;
13983
13984 struct PackageInfo
13985 *info;
13986
13987 SV
13988 *perl_exception,
13989 *reference; /* reference is the SV* of ref=SvIV(reference) */
13990
13991 PERL_UNUSED_VAR(ref);
13992 PERL_UNUSED_VAR(ix);
13993 exception=AcquireExceptionInfo();
13994 perl_exception=newSVpv("",0);
13995 if (sv_isobject(ST(0)) == 0)
13996 {
13997 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13998 PackageName);
13999 goto PerlException;
14000 }
14001 reference=SvRV(ST(0));
14002 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14003 if (items == 2)
14004 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
14005 else
14006 for (i=2; i < items; i+=2)
14007 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
14008
14009 PerlException:
14010 InheritPerlException(exception,perl_exception);
14011 exception=DestroyExceptionInfo(exception);
14012 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
14013 SvPOK_on(perl_exception);
14014 ST(0)=sv_2mortal(perl_exception);
14015 XSRETURN(1);
14016 }
14017
14018#
14019###############################################################################
14020# #
14021# #
14022# #
14023# S e t P i x e l #
14024# #
14025# #
14026# #
14027###############################################################################
14028#
14029#
14030void
14031SetPixel(ref,...)
14032 Image::Magick ref=NO_INIT
14033 ALIAS:
14034 setpixel = 1
14035 setPixel = 2
14036 PPCODE:
14037 {
14038 AV
14039 *av;
14040
14041 char
14042 *attribute;
14043
14044 ChannelType
14045 channel,
14046 channel_mask;
14047
14048 ExceptionInfo
14049 *exception;
14050
14051 Image
14052 *image;
14053
14054 MagickBooleanType
14055 normalize;
14056
14057 RectangleInfo
14058 region;
14059
14060 register ssize_t
14061 i;
14062
14063 register Quantum
14064 *q;
14065
14066 ssize_t
14067 option;
14068
14069 struct PackageInfo
14070 *info;
14071
14072 SV
14073 *perl_exception,
14074 *reference; /* reference is the SV* of ref=SvIV(reference) */
14075
14076 PERL_UNUSED_VAR(ref);
14077 PERL_UNUSED_VAR(ix);
14078 exception=AcquireExceptionInfo();
14079 perl_exception=newSVpv("",0);
14080 reference=SvRV(ST(0));
14081 av=(AV *) reference;
14082 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
14083 exception);
14084 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14085 if (image == (Image *) NULL)
14086 {
14087 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14088 PackageName);
14089 goto PerlException;
14090 }
14091 av=(AV *) NULL;
14092 normalize=MagickTrue;
14093 region.x=0;
14094 region.y=0;
14095 region.width=image->columns;
14096 region.height=1;
14097 if (items == 1)
14098 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
14099 channel=DefaultChannels;
14100 for (i=2; i < items; i+=2)
14101 {
14102 attribute=(char *) SvPV(ST(i-1),na);
14103 switch (*attribute)
14104 {
14105 case 'C':
14106 case 'c':
14107 {
14108 if (LocaleCompare(attribute,"channel") == 0)
14109 {
14110 ssize_t
14111 option;
14112
14113 option=ParseChannelOption(SvPV(ST(i),na));
14114 if (option < 0)
14115 {
14116 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14117 SvPV(ST(i),na));
14118 return;
14119 }
14120 channel=(ChannelType) option;
14121 break;
14122 }
14123 if (LocaleCompare(attribute,"color") == 0)
14124 {
14125 if (SvTYPE(ST(i)) != SVt_RV)
14126 {
14127 char
cristy151b66d2015-04-15 10:50:31 +000014128 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014129
cristy151b66d2015-04-15 10:50:31 +000014130 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000014131 "invalid %.60s value",attribute);
14132 ThrowPerlException(exception,OptionError,message,
14133 SvPV(ST(i),na));
14134 }
14135 av=(AV *) SvRV(ST(i));
14136 break;
14137 }
14138 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14139 attribute);
14140 break;
14141 }
14142 case 'g':
14143 case 'G':
14144 {
14145 if (LocaleCompare(attribute,"geometry") == 0)
14146 {
14147 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
14148 break;
14149 }
14150 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14151 attribute);
14152 break;
14153 }
14154 case 'N':
14155 case 'n':
14156 {
14157 if (LocaleCompare(attribute,"normalize") == 0)
14158 {
14159 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14160 SvPV(ST(i),na));
14161 if (option < 0)
14162 {
14163 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14164 SvPV(ST(i),na));
14165 break;
14166 }
14167 normalize=option != 0 ? MagickTrue : MagickFalse;
14168 break;
14169 }
14170 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14171 attribute);
14172 break;
14173 }
14174 case 'x':
14175 case 'X':
14176 {
14177 if (LocaleCompare(attribute,"x") == 0)
14178 {
14179 region.x=SvIV(ST(i));
14180 break;
14181 }
14182 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14183 attribute);
14184 break;
14185 }
14186 case 'y':
14187 case 'Y':
14188 {
14189 if (LocaleCompare(attribute,"y") == 0)
14190 {
14191 region.y=SvIV(ST(i));
14192 break;
14193 }
14194 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14195 attribute);
14196 break;
14197 }
14198 default:
14199 {
14200 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14201 attribute);
14202 break;
14203 }
14204 }
14205 }
14206 (void) SetImageStorageClass(image,DirectClass,exception);
14207 channel_mask=SetImageChannelMask(image,channel);
14208 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
14209 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14210 (SvTYPE(av) != SVt_PVAV))
14211 PUSHs(&sv_undef);
14212 else
14213 {
14214 double
14215 scale;
14216
14217 register ssize_t
14218 i;
14219
14220 i=0;
14221 scale=1.0;
14222 if (normalize != MagickFalse)
14223 scale=QuantumRange;
14224 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14225 (i <= av_len(av)))
14226 {
14227 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14228 av_fetch(av,i,0)))),q);
14229 i++;
14230 }
14231 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14232 (i <= av_len(av)))
14233 {
14234 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14235 av_fetch(av,i,0)))),q);
14236 i++;
14237 }
14238 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14239 (i <= av_len(av)))
14240 {
14241 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14242 av_fetch(av,i,0)))),q);
14243 i++;
14244 }
14245 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14246 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14247 {
14248 SetPixelBlack(image,ClampToQuantum(scale*
14249 SvNV(*(av_fetch(av,i,0)))),q);
14250 i++;
14251 }
14252 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14253 (i <= av_len(av)))
14254 {
14255 SetPixelAlpha(image,ClampToQuantum(scale*
14256 SvNV(*(av_fetch(av,i,0)))),q);
14257 i++;
14258 }
14259 (void) SyncAuthenticPixels(image,exception);
14260 }
14261 (void) SetImageChannelMask(image,channel_mask);
14262
14263 PerlException:
14264 InheritPerlException(exception,perl_exception);
14265 exception=DestroyExceptionInfo(exception);
14266 SvREFCNT_dec(perl_exception);
14267 }
14268
14269#
14270###############################################################################
14271# #
14272# #
14273# #
Cristybba545b2018-07-04 15:00:12 -040014274# S e t P i x e l s #
14275# #
14276# #
14277# #
14278###############################################################################
14279#
14280#
14281void
14282SetPixels(ref,...)
14283 Image::Magick ref=NO_INIT
14284 ALIAS:
14285 setpixels = 1
14286 setPixels = 2
14287 PPCODE:
14288 {
14289 AV
14290 *av;
14291
14292 char
14293 *attribute;
14294
14295 ChannelType
14296 channel,
14297 channel_mask;
14298
14299 ExceptionInfo
14300 *exception;
14301
14302 Image
14303 *image;
14304
14305 RectangleInfo
14306 region;
14307
14308 register ssize_t
14309 i;
14310
14311 register Quantum
14312 *q;
14313
14314 struct PackageInfo
14315 *info;
14316
14317 SV
14318 *perl_exception,
14319 *reference; /* reference is the SV* of ref=SvIV(reference) */
14320
14321 PERL_UNUSED_VAR(ref);
14322 PERL_UNUSED_VAR(ix);
14323 exception=AcquireExceptionInfo();
14324 perl_exception=newSVpv("",0);
14325 reference=SvRV(ST(0));
14326 av=(AV *) reference;
14327 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
14328 exception);
14329 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14330 if (image == (Image *) NULL)
14331 {
14332 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14333 PackageName);
14334 goto PerlException;
14335 }
14336 av=(AV *) NULL;
14337 region.x=0;
14338 region.y=0;
14339 region.width=image->columns;
14340 region.height=1;
14341 if (items == 1)
14342 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
14343 channel=DefaultChannels;
14344 for (i=2; i < items; i+=2)
14345 {
14346 attribute=(char *) SvPV(ST(i-1),na);
14347 switch (*attribute)
14348 {
14349 case 'C':
14350 case 'c':
14351 {
14352 if (LocaleCompare(attribute,"channel") == 0)
14353 {
14354 ssize_t
14355 option;
14356
14357 option=ParseChannelOption(SvPV(ST(i),na));
14358 if (option < 0)
14359 {
14360 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14361 SvPV(ST(i),na));
14362 return;
14363 }
14364 channel=(ChannelType) option;
14365 break;
14366 }
14367 if (LocaleCompare(attribute,"color") == 0)
14368 {
14369 if (SvTYPE(ST(i)) != SVt_RV)
14370 {
14371 char
14372 message[MagickPathExtent];
14373
14374 (void) FormatLocaleString(message,MagickPathExtent,
14375 "invalid %.60s value",attribute);
14376 ThrowPerlException(exception,OptionError,message,
14377 SvPV(ST(i),na));
14378 }
14379 av=(AV *) SvRV(ST(i));
14380 break;
14381 }
14382 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14383 attribute);
14384 break;
14385 }
14386 case 'g':
14387 case 'G':
14388 {
14389 if (LocaleCompare(attribute,"geometry") == 0)
14390 {
14391 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
14392 break;
14393 }
14394 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14395 attribute);
14396 break;
14397 }
14398 case 'h':
14399 case 'H':
14400 {
14401 if (LocaleCompare(attribute,"height") == 0)
14402 {
14403 region.height=SvIV(ST(i));
14404 break;
14405 }
14406 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14407 attribute);
14408 break;
14409 }
14410 case 'w':
14411 case 'W':
14412 {
14413 if (LocaleCompare(attribute,"width") == 0)
14414 {
14415 region.width=SvIV(ST(i));
14416 break;
14417 }
14418 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14419 attribute);
14420 break;
14421 }
14422 case 'x':
14423 case 'X':
14424 {
14425 if (LocaleCompare(attribute,"x") == 0)
14426 {
14427 region.x=SvIV(ST(i));
14428 break;
14429 }
14430 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14431 attribute);
14432 break;
14433 }
14434 case 'y':
14435 case 'Y':
14436 {
14437 if (LocaleCompare(attribute,"y") == 0)
14438 {
14439 region.y=SvIV(ST(i));
14440 break;
14441 }
14442 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14443 attribute);
14444 break;
14445 }
14446 default:
14447 {
14448 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14449 attribute);
14450 break;
14451 }
14452 }
14453 }
14454 (void) SetImageStorageClass(image,DirectClass,exception);
14455 channel_mask=SetImageChannelMask(image,channel);
14456 q=GetAuthenticPixels(image,region.x,region.y,region.width,region.height,
14457 exception);
14458 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14459 (SvTYPE(av) != SVt_PVAV))
14460 PUSHs(&sv_undef);
14461 else
14462 {
14463 double
14464 scale;
14465
14466 register ssize_t
14467 i,
14468 n,
14469 number_pixels;
14470
14471 i=0;
14472 n=0;
14473 scale=(double) QuantumRange;
14474 number_pixels=region.width*region.height;
14475 while ((n < number_pixels) && (i < av_len(av)))
14476 {
14477 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14478 (i <= av_len(av)))
14479 {
14480 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14481 av_fetch(av,i,0)))),q);
14482 i++;
14483 }
14484 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14485 (i <= av_len(av)))
14486 {
14487 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14488 av_fetch(av,i,0)))),q);
14489 i++;
14490 }
14491 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14492 (i <= av_len(av)))
14493 {
14494 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14495 av_fetch(av,i,0)))),q);
14496 i++;
14497 }
14498 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14499 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14500 {
14501 SetPixelBlack(image,ClampToQuantum(scale*
14502 SvNV(*(av_fetch(av,i,0)))),q);
14503 i++;
14504 }
14505 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14506 (i <= av_len(av)))
14507 {
14508 SetPixelAlpha(image,ClampToQuantum(scale*
14509 SvNV(*(av_fetch(av,i,0)))),q);
14510 i++;
14511 }
14512 n++;
14513 q+=image->number_channels;
14514 }
14515 (void) SyncAuthenticPixels(image,exception);
14516 }
14517 (void) SetImageChannelMask(image,channel_mask);
14518
14519 PerlException:
14520 InheritPerlException(exception,perl_exception);
14521 exception=DestroyExceptionInfo(exception);
14522 SvREFCNT_dec(perl_exception);
14523 }
14524
14525#
14526###############################################################################
14527# #
14528# #
14529# #
cristy4a3ce0a2013-08-03 20:06:59 +000014530# S m u s h #
14531# #
14532# #
14533# #
14534###############################################################################
14535#
14536#
14537void
14538Smush(ref,...)
14539 Image::Magick ref=NO_INIT
14540 ALIAS:
14541 SmushImage = 1
14542 smush = 2
14543 smushimage = 3
14544 PPCODE:
14545 {
14546 AV
14547 *av;
14548
14549 char
14550 *attribute;
14551
14552 ExceptionInfo
14553 *exception;
14554
14555 HV
14556 *hv;
14557
14558 Image
14559 *image;
14560
14561 register ssize_t
14562 i;
14563
14564 ssize_t
14565 offset,
14566 stack;
14567
14568 struct PackageInfo
14569 *info;
14570
14571 SV
14572 *av_reference,
14573 *perl_exception,
14574 *reference,
14575 *rv,
14576 *sv;
14577
14578 PERL_UNUSED_VAR(ref);
14579 PERL_UNUSED_VAR(ix);
14580 exception=AcquireExceptionInfo();
14581 perl_exception=newSVpv("",0);
14582 sv=NULL;
14583 attribute=NULL;
14584 av=NULL;
14585 if (sv_isobject(ST(0)) == 0)
14586 {
14587 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14588 PackageName);
14589 goto PerlException;
14590 }
14591 reference=SvRV(ST(0));
14592 hv=SvSTASH(reference);
14593 av=newAV();
14594 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14595 SvREFCNT_dec(av);
14596 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14597 if (image == (Image *) NULL)
14598 {
14599 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14600 PackageName);
14601 goto PerlException;
14602 }
14603 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14604 /*
14605 Get options.
14606 */
14607 offset=0;
14608 stack=MagickTrue;
14609 for (i=2; i < items; i+=2)
14610 {
14611 attribute=(char *) SvPV(ST(i-1),na);
14612 switch (*attribute)
14613 {
14614 case 'O':
14615 case 'o':
14616 {
14617 if (LocaleCompare(attribute,"offset") == 0)
14618 {
14619 offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14620 break;
14621 }
14622 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14623 attribute);
14624 break;
14625 }
14626 case 'S':
14627 case 's':
14628 {
14629 if (LocaleCompare(attribute,"stack") == 0)
14630 {
14631 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14632 SvPV(ST(i),na));
14633 if (stack < 0)
14634 {
14635 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14636 SvPV(ST(i),na));
14637 return;
14638 }
14639 break;
14640 }
14641 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14642 attribute);
14643 break;
14644 }
14645 default:
14646 {
14647 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14648 attribute);
14649 break;
14650 }
14651 }
14652 }
14653 image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14654 exception);
14655 if (image == (Image *) NULL)
14656 goto PerlException;
14657 for ( ; image; image=image->next)
14658 {
14659 AddImageToRegistry(sv,image);
14660 rv=newRV(sv);
14661 av_push(av,sv_bless(rv,hv));
14662 SvREFCNT_dec(sv);
14663 }
14664 exception=DestroyExceptionInfo(exception);
14665 ST(0)=av_reference;
14666 SvREFCNT_dec(perl_exception);
14667 XSRETURN(1);
14668
14669 PerlException:
14670 InheritPerlException(exception,perl_exception);
14671 exception=DestroyExceptionInfo(exception);
14672 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14673 SvPOK_on(perl_exception);
14674 ST(0)=sv_2mortal(perl_exception);
14675 XSRETURN(1);
14676 }
14677
14678#
14679###############################################################################
14680# #
14681# #
14682# #
14683# S t a t i s t i c s #
14684# #
14685# #
14686# #
14687###############################################################################
14688#
14689#
14690void
14691Statistics(ref,...)
14692 Image::Magick ref=NO_INIT
14693 ALIAS:
14694 StatisticsImage = 1
14695 statistics = 2
14696 statisticsimage = 3
14697 PPCODE:
14698 {
14699#define ChannelStatistics(channel) \
14700{ \
cristy151b66d2015-04-15 10:50:31 +000014701 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014702 (double) channel_statistics[channel].depth); \
14703 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014704 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014705 channel_statistics[channel].minima/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014706 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014707 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014708 channel_statistics[channel].maxima/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014709 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014710 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014711 channel_statistics[channel].mean/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014712 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014713 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014714 channel_statistics[channel].standard_deviation/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014715 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014716 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014717 channel_statistics[channel].kurtosis); \
14718 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014719 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014720 channel_statistics[channel].skewness); \
14721 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014722 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy275bdd92014-11-08 23:45:03 +000014723 channel_statistics[channel].entropy); \
14724 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy4a3ce0a2013-08-03 20:06:59 +000014725}
14726
14727 AV
14728 *av;
14729
14730 char
cristy151b66d2015-04-15 10:50:31 +000014731 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014732
14733 ChannelStatistics
14734 *channel_statistics;
14735
cristy4a3ce0a2013-08-03 20:06:59 +000014736 ExceptionInfo
14737 *exception;
14738
14739 Image
14740 *image;
14741
14742 ssize_t
14743 count;
14744
14745 struct PackageInfo
14746 *info;
14747
14748 SV
14749 *perl_exception,
14750 *reference;
14751
14752 PERL_UNUSED_VAR(ref);
14753 PERL_UNUSED_VAR(ix);
14754 exception=AcquireExceptionInfo();
14755 perl_exception=newSVpv("",0);
14756 av=NULL;
14757 if (sv_isobject(ST(0)) == 0)
14758 {
14759 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14760 PackageName);
14761 goto PerlException;
14762 }
14763 reference=SvRV(ST(0));
14764 av=newAV();
14765 SvREFCNT_dec(av);
14766 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14767 if (image == (Image *) NULL)
14768 {
14769 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14770 PackageName);
14771 goto PerlException;
14772 }
cristy4a3ce0a2013-08-03 20:06:59 +000014773 count=0;
14774 for ( ; image; image=image->next)
14775 {
Cristyb1710fe2017-02-11 13:51:48 -050014776 register size_t
14777 i;
14778
cristy4a3ce0a2013-08-03 20:06:59 +000014779 channel_statistics=GetImageStatistics(image,exception);
14780 if (channel_statistics == (ChannelStatistics *) NULL)
14781 continue;
14782 count++;
Cristyb1710fe2017-02-11 13:51:48 -050014783 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
14784 {
14785 PixelChannel channel=GetPixelChannelChannel(image,i);
14786 PixelTrait traits=GetPixelChannelTraits(image,channel);
Cristy5a854dc2017-02-11 15:43:46 -050014787 if (traits == UndefinedPixelTrait)
Cristyb1710fe2017-02-11 13:51:48 -050014788 continue;
Cristy5a854dc2017-02-11 15:43:46 -050014789 EXTEND(sp,8*(i+1)*count);
Cristyb1710fe2017-02-11 13:51:48 -050014790 ChannelStatistics(channel);
14791 }
Cristy25813902017-02-11 15:47:52 -050014792 EXTEND(sp,8*(i+1)*count);
14793 ChannelStatistics(CompositePixelChannel);
cristy4a3ce0a2013-08-03 20:06:59 +000014794 channel_statistics=(ChannelStatistics *)
14795 RelinquishMagickMemory(channel_statistics);
14796 }
14797
14798 PerlException:
14799 InheritPerlException(exception,perl_exception);
14800 exception=DestroyExceptionInfo(exception);
14801 SvREFCNT_dec(perl_exception);
14802 }
14803
14804#
14805###############################################################################
14806# #
14807# #
14808# #
14809# S y n c A u t h e n t i c P i x e l s #
14810# #
14811# #
14812# #
14813###############################################################################
14814#
14815#
14816void
14817SyncAuthenticPixels(ref,...)
14818 Image::Magick ref = NO_INIT
14819 ALIAS:
14820 Syncauthenticpixels = 1
14821 SyncImagePixels = 2
14822 syncimagepixels = 3
14823 CODE:
14824 {
14825 ExceptionInfo
14826 *exception;
14827
14828 Image
14829 *image;
14830
14831 MagickBooleanType
14832 status;
14833
14834 struct PackageInfo
14835 *info;
14836
14837 SV
14838 *perl_exception,
14839 *reference;
14840
14841 PERL_UNUSED_VAR(ref);
14842 PERL_UNUSED_VAR(ix);
14843 exception=AcquireExceptionInfo();
14844 perl_exception=newSVpv("",0);
14845 if (sv_isobject(ST(0)) == 0)
14846 {
14847 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14848 PackageName);
14849 goto PerlException;
14850 }
14851
14852 reference=SvRV(ST(0));
14853 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14854 if (image == (Image *) NULL)
14855 {
14856 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14857 PackageName);
14858 goto PerlException;
14859 }
14860
14861 status=SyncAuthenticPixels(image,exception);
14862 if (status != MagickFalse)
14863 return;
14864
14865 PerlException:
14866 InheritPerlException(exception,perl_exception);
14867 exception=DestroyExceptionInfo(exception);
14868 SvREFCNT_dec(perl_exception); /* throw away all errors */
14869 }
14870
14871#
14872###############################################################################
14873# #
14874# #
14875# #
cristy4a3ce0a2013-08-03 20:06:59 +000014876# W r i t e #
14877# #
14878# #
14879# #
14880###############################################################################
14881#
14882#
14883void
14884Write(ref,...)
14885 Image::Magick ref=NO_INIT
14886 ALIAS:
14887 WriteImage = 1
14888 write = 2
14889 writeimage = 3
14890 PPCODE:
14891 {
14892 char
cristy151b66d2015-04-15 10:50:31 +000014893 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014894
14895 ExceptionInfo
14896 *exception;
14897
14898 Image
14899 *image,
14900 *next;
14901
14902 register ssize_t
14903 i;
14904
14905 ssize_t
14906 number_images,
14907 scene;
14908
14909 struct PackageInfo
14910 *info,
14911 *package_info;
14912
14913 SV
14914 *perl_exception,
14915 *reference;
14916
14917 PERL_UNUSED_VAR(ref);
14918 PERL_UNUSED_VAR(ix);
14919 exception=AcquireExceptionInfo();
14920 perl_exception=newSVpv("",0);
14921 number_images=0;
14922 package_info=(struct PackageInfo *) NULL;
14923 if (sv_isobject(ST(0)) == 0)
14924 {
14925 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14926 PackageName);
14927 goto PerlException;
14928 }
14929 reference=SvRV(ST(0));
14930 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14931 if (image == (Image *) NULL)
14932 {
14933 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14934 PackageName);
14935 goto PerlException;
14936 }
Cristyb4ee45c2017-09-27 17:58:55 -040014937 scene=0;
14938 for (next=image; next; next=next->next)
14939 next->scene=scene++;
cristy4a3ce0a2013-08-03 20:06:59 +000014940 package_info=ClonePackageInfo(info,exception);
14941 if (items == 2)
14942 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
14943 else
14944 if (items > 2)
14945 for (i=2; i < items; i+=2)
14946 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
14947 exception);
14948 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +000014949 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000014950 for (next=image; next; next=next->next)
cristy151b66d2015-04-15 10:50:31 +000014951 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy68bd79a2015-02-25 12:23:36 +000014952 *package_info->image_info->magick='\0';
cristy4a3ce0a2013-08-03 20:06:59 +000014953 SetImageInfo(package_info->image_info,(unsigned int)
14954 GetImageListLength(image),exception);
14955 for (next=image; next; next=next->next)
14956 {
14957 (void) WriteImage(package_info->image_info,next,exception);
14958 number_images++;
14959 if (package_info->image_info->adjoin)
14960 break;
14961 }
14962
14963 PerlException:
14964 if (package_info != (struct PackageInfo *) NULL)
14965 DestroyPackageInfo(package_info);
14966 InheritPerlException(exception,perl_exception);
14967 exception=DestroyExceptionInfo(exception);
14968 sv_setiv(perl_exception,(IV) number_images);
14969 SvPOK_on(perl_exception);
14970 ST(0)=sv_2mortal(perl_exception);
14971 XSRETURN(1);
14972 }