blob: f5e72324b1b1426456a8f2bb6c15aa896ccbfb3b [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% %
Cristyf775a5c2019-11-26 14:27:47 -050026% Copyright 1999-2020 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
Cristy3d1de822019-02-15 18:06:30 -050078#define MaxArguments 34
cristy4a3ce0a2013-08-03 20:06:59 +000079#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},
Cristy3d1de822019-02-15 18:06:30 -0500291 {"direction", MagickDirectionOptions},
292 {"decorate", MagickDecorateOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000293 { "ColorFloodfill", { {"geometry", StringReference},
294 {"x", IntegerReference}, {"y", IntegerReference},
295 {"fill", StringReference}, {"bordercolor", StringReference},
296 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
297 { "Composite", { {"image", ImageReference},
298 {"compose", MagickComposeOptions}, {"geometry", StringReference},
299 {"x", IntegerReference}, {"y", IntegerReference},
300 {"gravity", MagickGravityOptions}, {"opacity", StringReference},
301 {"tile", MagickBooleanOptions}, {"rotate", RealReference},
302 {"color", StringReference}, {"mask", ImageReference},
303 {"channel", MagickChannelOptions},
304 {"interpolate", MagickInterpolateOptions}, {"args", StringReference},
Cristy74e39292018-07-08 13:13:20 -0400305 {"blend", StringReference}, {"clip-to-self", MagickBooleanOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000306 { "Contrast", { {"sharpen", MagickBooleanOptions} } },
307 { "CycleColormap", { {"display", IntegerReference} } },
308 { "Draw", { {"primitive", MagickPrimitiveOptions},
309 {"points", StringReference}, {"method", MagickMethodOptions},
310 {"stroke", StringReference}, {"fill", StringReference},
311 {"strokewidth", RealReference}, {"font", StringReference},
312 {"bordercolor", StringReference}, {"x", RealReference},
313 {"y", RealReference}, {"translate", StringReference},
314 {"scale", StringReference}, {"rotate", RealReference},
315 {"skewX", RealReference}, {"skewY", RealReference},
316 {"tile", ImageReference}, {"pointsize", RealReference},
317 {"antialias", MagickBooleanOptions}, {"density", StringReference},
318 {"linewidth", RealReference}, {"affine", ArrayReference},
319 {"stroke-dashoffset", RealReference},
320 {"stroke-dasharray", ArrayReference},
321 {"interpolate", MagickInterpolateOptions},
322 {"origin", StringReference}, {"text", StringReference},
323 {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
324 {"vector-graphics", StringReference}, {"kerning", RealReference},
325 {"interline-spacing", RealReference},
326 {"interword-spacing", RealReference},
327 {"direction", MagickDirectionOptions} } },
328 { "Equalize", { {"channel", MagickChannelOptions} } },
329 { "Gamma", { {"gamma", StringReference}, {"channel", MagickChannelOptions},
330 {"red", RealReference}, {"green", RealReference},
331 {"blue", RealReference} } },
332 { "Map", { {"image", ImageReference},
333 {"dither-method", MagickDitherOptions} } },
334 { "MatteFloodfill", { {"geometry", StringReference},
335 {"x", IntegerReference}, {"y", IntegerReference},
336 {"opacity", StringReference}, {"bordercolor", StringReference},
337 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
338 { "Modulate", { {"factor", StringReference}, {"hue", RealReference},
339 {"saturation", RealReference}, {"whiteness", RealReference},
340 {"brightness", RealReference}, {"lightness", RealReference},
341 {"blackness", RealReference} } },
342 { "Negate", { {"gray", MagickBooleanOptions},
343 {"channel", MagickChannelOptions} } },
344 { "Normalize", { {"channel", MagickChannelOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500345 { "NumberColors", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000346 { "Opaque", { {"color", StringReference}, {"fill", StringReference},
347 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
348 {"invert", MagickBooleanOptions} } },
349 { "Quantize", { {"colors", IntegerReference},
350 {"treedepth", IntegerReference}, {"colorspace", MagickColorspaceOptions},
351 {"dither", MagickDitherOptions}, {"measure", MagickBooleanOptions},
352 {"global", MagickBooleanOptions}, {"transparent-color", StringReference},
353 {"dither-method", MagickDitherOptions} } },
354 { "Raise", { {"geometry", StringReference}, {"width", IntegerReference},
355 {"height", IntegerReference}, {"raise", MagickBooleanOptions} } },
356 { "Segment", { {"geometry", StringReference},
357 {"cluster-threshold", RealReference},
358 {"smoothing-threshold", RealReference},
359 {"colorspace", MagickColorspaceOptions},
360 {"verbose", MagickBooleanOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500361 { "Signature", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000362 { "Solarize", { {"geometry", StringReference},
363 {"threshold", StringReference} } },
Cristy8cb2e452018-01-14 14:46:31 -0500364 { "Sync", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000365 { "Texture", { {"texture", ImageReference} } },
366 { "Evaluate", { {"value", RealReference},
367 {"operator", MagickEvaluateOptions},
368 {"channel", MagickChannelOptions} } },
369 { "Transparent", { {"color", StringReference}, {"opacity", StringReference},
370 {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
371 { "Threshold", { {"threshold", StringReference},
372 {"channel", MagickChannelOptions} } },
373 { "Charcoal", { {"geometry", StringReference}, {"radius", RealReference},
374 {"sigma", RealReference} } },
375 { "Trim", { {"fuzz", StringReference} } },
376 { "Wave", { {"geometry", StringReference}, {"amplitude", RealReference},
377 {"wavelength", RealReference},
378 {"interpolate", MagickInterpolateOptions} } },
379 { "Separate", { {"channel", MagickChannelOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500380 { "Condense", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000381 { "Stereo", { {"image", ImageReference}, {"x", IntegerReference},
382 {"y", IntegerReference} } },
383 { "Stegano", { {"image", ImageReference}, {"offset", IntegerReference} } },
Cristy8cb2e452018-01-14 14:46:31 -0500384 { "Deconstruct", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000385 { "GaussianBlur", { {"geometry", StringReference},
386 {"radius", RealReference}, {"sigma", RealReference},
387 {"channel", MagickChannelOptions} } },
388 { "Convolve", { {"coefficients", ArrayReference},
389 {"channel", MagickChannelOptions}, {"bias", StringReference},
390 {"kernel", StringReference} } },
391 { "Profile", { {"name", StringReference}, {"profile", StringReference},
392 { "rendering-intent", MagickIntentOptions},
393 { "black-point-compensation", MagickBooleanOptions} } },
394 { "UnsharpMask", { {"geometry", StringReference},
395 {"radius", RealReference}, {"sigma", RealReference},
396 {"gain", RealReference}, {"threshold", RealReference},
397 {"channel", MagickChannelOptions} } },
398 { "MotionBlur", { {"geometry", StringReference},
399 {"radius", RealReference}, {"sigma", RealReference},
400 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
401 { "OrderedDither", { {"threshold", StringReference},
402 {"channel", MagickChannelOptions} } },
403 { "Shave", { {"geometry", StringReference}, {"width", IntegerReference},
404 {"height", IntegerReference} } },
405 { "Level", { {"levels", StringReference}, {"black-point", RealReference},
406 {"white-point", RealReference}, {"gamma", RealReference},
407 {"channel", MagickChannelOptions}, {"level", StringReference} } },
408 { "Clip", { {"id", StringReference}, {"inside", MagickBooleanOptions} } },
409 { "AffineTransform", { {"affine", ArrayReference},
410 {"translate", StringReference}, {"scale", StringReference},
411 {"rotate", RealReference}, {"skewX", RealReference},
412 {"skewY", RealReference}, {"interpolate", MagickInterpolateOptions},
413 {"background", StringReference} } },
414 { "Difference", { {"image", ImageReference}, {"fuzz", StringReference} } },
415 { "AdaptiveThreshold", { {"geometry", StringReference},
Cristy9f252542018-11-21 19:13:46 -0500416 {"width", IntegerReference}, {"height", IntegerReference},
417 {"bias", RealReference} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000418 { "Resample", { {"density", StringReference}, {"x", RealReference},
419 {"y", RealReference}, {"filter", MagickFilterOptions},
420 {"support", RealReference } } },
421 { "Describe", { {"file", FileReference} } },
422 { "BlackThreshold", { {"threshold", StringReference},
423 {"channel", MagickChannelOptions} } },
424 { "WhiteThreshold", { {"threshold", StringReference},
425 {"channel", MagickChannelOptions} } },
cristy60c73c02014-03-25 12:09:58 +0000426 { "RotationalBlur", { {"geometry", StringReference},
427 {"angle", RealReference}, {"channel", MagickChannelOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000428 { "Thumbnail", { {"geometry", StringReference}, {"width", IntegerReference},
429 {"height", IntegerReference} } },
Cristy8cb2e452018-01-14 14:46:31 -0500430 { "Strip", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000431 { "Tint", { {"fill", StringReference}, {"blend", StringReference} } },
432 { "Channel", { {"channel", MagickChannelOptions} } },
433 { "Splice", { {"geometry", StringReference}, {"width", IntegerReference},
434 {"height", IntegerReference}, {"x", IntegerReference},
435 {"y", IntegerReference}, {"fuzz", StringReference},
436 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
437 { "Posterize", { {"levels", IntegerReference},
438 {"dither", MagickBooleanOptions} } },
439 { "Shadow", { {"geometry", StringReference}, {"alpha", RealReference},
440 {"sigma", RealReference}, {"x", IntegerReference},
441 {"y", IntegerReference} } },
442 { "Identify", { {"file", FileReference}, {"features", StringReference},
Cristy8b3ffe62020-02-17 12:36:53 -0500443 {"moments", MagickBooleanOptions}, {"unique", MagickBooleanOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000444 { "SepiaTone", { {"threshold", RealReference} } },
445 { "SigmoidalContrast", { {"geometry", StringReference},
446 {"contrast", RealReference}, {"mid-point", RealReference},
447 {"channel", MagickChannelOptions}, {"sharpen", MagickBooleanOptions} } },
448 { "Extent", { {"geometry", StringReference}, {"width", IntegerReference},
449 {"height", IntegerReference}, {"x", IntegerReference},
450 {"y", IntegerReference}, {"fuzz", StringReference},
451 {"background", StringReference}, {"gravity", MagickGravityOptions} } },
452 { "Vignette", { {"geometry", StringReference}, {"radius", RealReference},
453 {"sigma", RealReference}, {"x", IntegerReference},
454 {"y", IntegerReference}, {"background", StringReference} } },
455 { "ContrastStretch", { {"levels", StringReference},
456 {"black-point", RealReference},{"white-point", RealReference},
457 {"channel", MagickChannelOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500458 { "Sans0", { { (const char *) NULL, NullReference } } },
459 { "Sans1", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000460 { "AdaptiveSharpen", { {"geometry", StringReference},
461 {"radius", RealReference}, {"sigma", RealReference},
462 {"bias", RealReference}, {"channel", MagickChannelOptions} } },
Cristy8cb2e452018-01-14 14:46:31 -0500463 { "Transpose", { { (const char *) NULL, NullReference } } },
464 { "Transverse", { { (const char *) NULL, NullReference } } },
465 { "AutoOrient", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000466 { "AdaptiveBlur", { {"geometry", StringReference},
467 {"radius", RealReference}, {"sigma", RealReference},
468 {"channel", MagickChannelOptions} } },
469 { "Sketch", { {"geometry", StringReference},
470 {"radius", RealReference}, {"sigma", RealReference},
471 {"angle", RealReference} } },
Cristy8cb2e452018-01-14 14:46:31 -0500472 { "UniqueColors", { { (const char *) NULL, NullReference } } },
cristy4a3ce0a2013-08-03 20:06:59 +0000473 { "AdaptiveResize", { {"geometry", StringReference},
474 {"width", IntegerReference}, {"height", IntegerReference},
475 {"filter", MagickFilterOptions}, {"support", StringReference },
476 {"blur", RealReference } } },
477 { "ClipMask", { {"mask", ImageReference} } },
478 { "LinearStretch", { {"levels", StringReference},
479 {"black-point", RealReference},{"white-point", RealReference} } },
480 { "ColorMatrix", { {"matrix", ArrayReference} } },
481 { "Mask", { {"mask", ImageReference} } },
482 { "Polaroid", { {"caption", StringReference}, {"angle", RealReference},
483 {"font", StringReference}, {"stroke", StringReference},
484 {"fill", StringReference}, {"strokewidth", RealReference},
485 {"pointsize", RealReference}, {"gravity", MagickGravityOptions},
486 {"background", StringReference},
487 {"interpolate", MagickInterpolateOptions} } },
488 { "FloodfillPaint", { {"geometry", StringReference},
489 {"x", IntegerReference}, {"y", IntegerReference},
490 {"fill", StringReference}, {"bordercolor", StringReference},
491 {"fuzz", StringReference}, {"channel", MagickChannelOptions},
492 {"invert", MagickBooleanOptions} } },
493 { "Distort", { {"points", ArrayReference}, {"method", MagickDistortOptions},
494 {"virtual-pixel", MagickVirtualPixelOptions},
495 {"best-fit", MagickBooleanOptions} } },
496 { "Clut", { {"image", ImageReference},
497 {"interpolate", MagickInterpolateOptions},
498 {"channel", MagickChannelOptions} } },
499 { "LiquidRescale", { {"geometry", StringReference},
500 {"width", IntegerReference}, {"height", IntegerReference},
501 {"delta-x", RealReference}, {"rigidity", RealReference } } },
502 { "Encipher", { {"passphrase", StringReference} } },
503 { "Decipher", { {"passphrase", StringReference} } },
504 { "Deskew", { {"geometry", StringReference},
505 {"threshold", StringReference} } },
506 { "Remap", { {"image", ImageReference},
507 {"dither-method", MagickDitherOptions} } },
508 { "SparseColor", { {"points", ArrayReference},
509 {"method", MagickSparseColorOptions},
510 {"virtual-pixel", MagickVirtualPixelOptions},
511 {"channel", MagickChannelOptions} } },
512 { "Function", { {"parameters", ArrayReference},
513 {"function", MagickFunctionOptions},
514 {"virtual-pixel", MagickVirtualPixelOptions} } },
515 { "SelectiveBlur", { {"geometry", StringReference},
516 {"radius", RealReference}, {"sigma", RealReference},
517 {"threshold", RealReference}, {"channel", MagickChannelOptions} } },
518 { "HaldClut", { {"image", ImageReference},
519 {"channel", MagickChannelOptions} } },
520 { "BlueShift", { {"factor", StringReference} } },
521 { "ForwardFourierTransform", { {"magnitude", MagickBooleanOptions} } },
522 { "InverseFourierTransform", { {"magnitude", MagickBooleanOptions} } },
523 { "ColorDecisionList", {
524 {"color-correction-collection", StringReference} } },
525 { "AutoGamma", { {"channel", MagickChannelOptions} } },
526 { "AutoLevel", { {"channel", MagickChannelOptions} } },
527 { "LevelColors", { {"invert", MagickBooleanOptions},
528 {"black-point", StringReference}, {"white-point", StringReference},
529 {"channel", MagickChannelOptions}, {"invert", MagickBooleanOptions} } },
530 { "Clamp", { {"channel", MagickChannelOptions} } },
531 { "BrightnessContrast", { {"levels", StringReference},
532 {"brightness", RealReference},{"contrast", RealReference},
533 {"channel", MagickChannelOptions} } },
534 { "Morphology", { {"kernel", StringReference},
535 {"channel", MagickChannelOptions}, {"method", MagickMorphologyOptions},
536 {"iterations", IntegerReference} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000537 { "Mode", { {"geometry", StringReference},
538 {"width", IntegerReference},{"height", IntegerReference},
539 {"channel", MagickChannelOptions} } },
540 { "Statistic", { {"geometry", StringReference},
541 {"width", IntegerReference},{"height", IntegerReference},
542 {"channel", MagickChannelOptions}, {"type", MagickStatisticOptions} } },
543 { "Perceptible", { {"epsilon", RealReference},
544 {"channel", MagickChannelOptions} } },
545 { "Poly", { {"terms", ArrayReference},
546 {"channel", MagickChannelOptions} } },
547 { "Grayscale", { {"method", MagickNoiseOptions} } },
cristy4ceadb82014-03-29 15:30:43 +0000548 { "CannyEdge", { {"geometry", StringReference},
549 {"radius", RealReference}, {"sigma", RealReference},
cristycfe7bf02014-04-04 15:31:52 +0000550 {"lower-percent", RealReference}, {"upper-percent", RealReference} } },
cristy2fc10e52014-04-26 14:13:53 +0000551 { "HoughLine", { {"geometry", StringReference},
cristy4e215022014-04-19 18:02:35 +0000552 {"width", IntegerReference}, {"height", IntegerReference},
553 {"threshold", IntegerReference} } },
cristy2fc10e52014-04-26 14:13:53 +0000554 { "MeanShift", { {"geometry", StringReference},
555 {"width", IntegerReference}, {"height", IntegerReference},
cristy1309fc32014-04-26 18:48:37 +0000556 {"distance", RealReference} } },
cristy3b207f82014-09-27 14:21:20 +0000557 { "Kuwahara", { {"geometry", StringReference}, {"radius", RealReference},
558 {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
Cristy2ca0e9a2016-01-01 08:36:14 -0500559 { "ConnectedComponents", { {"connectivity", IntegerReference} } },
cristyf3a724a2015-06-25 13:02:53 +0000560 { "CopyPixels", { {"image", ImageReference}, {"geometry", StringReference},
561 {"width", IntegerReference}, {"height", IntegerReference},
562 {"x", IntegerReference}, {"y", IntegerReference},
Cristy532b3382018-08-05 17:56:56 -0400563 {"gravity", MagickGravityOptions}, {"offset", StringReference},
cristyf3a724a2015-06-25 13:02:53 +0000564 {"dx", IntegerReference}, {"dy", IntegerReference} } },
Cristy5488c982016-02-13 14:07:50 -0500565 { "Color", { {"color", StringReference} } },
Cristyc1759412016-02-27 12:17:58 -0500566 { "WaveletDenoise", { {"geometry", StringReference},
567 {"threshold", RealReference}, {"softness", RealReference},
Cristy2d830ed2016-02-21 10:54:16 -0500568 {"channel", MagickChannelOptions} } },
Cristy99a57162016-12-05 11:47:57 -0500569 { "Colorspace", { {"colorspace", MagickColorspaceOptions} } },
Cristy53353872017-07-02 12:24:24 -0400570 { "AutoThreshold", { {"method", MagickAutoThresholdOptions} } },
Cristy532b3382018-08-05 17:56:56 -0400571 { "RangeThreshold", { {"geometry", StringReference},
Cristy72f24752018-08-14 20:17:26 -0400572 {"low-black", RealReference}, {"low-white", RealReference},
573 {"high-white", RealReference}, {"high-black", RealReference},
Cristy532b3382018-08-05 17:56:56 -0400574 {"channel", MagickChannelOptions} } },
Cristy30263282018-12-11 16:40:25 -0500575 { "CLAHE", { {"geometry", StringReference}, {"width", IntegerReference},
576 {"height", IntegerReference}, {"number-bins", IntegerReference},
Cristy768e9002019-01-08 07:35:16 -0500577 {"clip-limit", RealReference} } },
Cristyb4ab5192019-12-19 06:53:46 -0500578 { "Kmeans", { {"geometry", StringReference}, {"colors", IntegerReference},
Cristy1fce5c52019-12-31 09:51:14 -0500579 {"iterations", IntegerReference}, {"tolerance", RealReference} } },
Cristyca5ba782020-02-22 08:17:19 -0500580 { "ColorThreshold", { {"start-color", StringReference},
581 {"stop-color", StringReference}, {"channel", MagickChannelOptions} } },
cristy4a3ce0a2013-08-03 20:06:59 +0000582 };
583
584static SplayTreeInfo
585 *magick_registry = (SplayTreeInfo *) NULL;
586
587/*
588 Forward declarations.
589*/
590static Image
591 *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
592
593static ssize_t
594 strEQcase(const char *,const char *);
595
596/*
597%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
598% %
599% %
600% %
601% C l o n e P a c k a g e I n f o %
602% %
603% %
604% %
605%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
606%
607% ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
608% a new one.
609%
610% The format of the ClonePackageInfo routine is:
611%
612% struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
613% exception)
614%
615% A description of each parameter follows:
616%
617% o info: a structure of type info.
618%
619% o exception: Return any errors or warnings in this structure.
620%
621*/
622static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
623 ExceptionInfo *exception)
624{
625 struct PackageInfo
626 *clone_info;
627
628 clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
629 if (clone_info == (struct PackageInfo *) NULL)
630 {
631 ThrowPerlException(exception,ResourceLimitError,
632 "UnableToClonePackageInfo",PackageName);
633 return((struct PackageInfo *) NULL);
634 }
635 if (info == (struct PackageInfo *) NULL)
636 {
637 clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
638 return(clone_info);
639 }
640 *clone_info=(*info);
641 clone_info->image_info=CloneImageInfo(info->image_info);
642 return(clone_info);
643}
644
645/*
646%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
647% %
648% %
649% %
650% c o n s t a n t %
651% %
652% %
653% %
654%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
655%
656% constant() returns a double value for the specified name.
657%
658% The format of the constant routine is:
659%
660% double constant(char *name,ssize_t sans)
661%
662% A description of each parameter follows:
663%
664% o value: Method constant returns a double value for the specified name.
665%
666% o name: The name of the constant.
667%
668% o sans: This integer value is not used.
669%
670*/
671static double constant(char *name,ssize_t sans)
672{
673 (void) sans;
674 errno=0;
675 switch (*name)
676 {
677 case 'B':
678 {
679 if (strEQ(name,"BlobError"))
680 return(BlobError);
681 if (strEQ(name,"BlobWarning"))
682 return(BlobWarning);
683 break;
684 }
685 case 'C':
686 {
687 if (strEQ(name,"CacheError"))
688 return(CacheError);
689 if (strEQ(name,"CacheWarning"))
690 return(CacheWarning);
691 if (strEQ(name,"CoderError"))
692 return(CoderError);
693 if (strEQ(name,"CoderWarning"))
694 return(CoderWarning);
695 if (strEQ(name,"ConfigureError"))
696 return(ConfigureError);
697 if (strEQ(name,"ConfigureWarning"))
698 return(ConfigureWarning);
699 if (strEQ(name,"CorruptImageError"))
700 return(CorruptImageError);
701 if (strEQ(name,"CorruptImageWarning"))
702 return(CorruptImageWarning);
703 break;
704 }
705 case 'D':
706 {
707 if (strEQ(name,"DelegateError"))
708 return(DelegateError);
709 if (strEQ(name,"DelegateWarning"))
710 return(DelegateWarning);
711 if (strEQ(name,"DrawError"))
712 return(DrawError);
713 if (strEQ(name,"DrawWarning"))
714 return(DrawWarning);
715 break;
716 }
717 case 'E':
718 {
719 if (strEQ(name,"ErrorException"))
720 return(ErrorException);
721 if (strEQ(name,"ExceptionError"))
722 return(CoderError);
723 if (strEQ(name,"ExceptionWarning"))
724 return(CoderWarning);
725 break;
726 }
727 case 'F':
728 {
729 if (strEQ(name,"FatalErrorException"))
730 return(FatalErrorException);
731 if (strEQ(name,"FileOpenError"))
732 return(FileOpenError);
733 if (strEQ(name,"FileOpenWarning"))
734 return(FileOpenWarning);
735 break;
736 }
737 case 'I':
738 {
739 if (strEQ(name,"ImageError"))
740 return(ImageError);
741 if (strEQ(name,"ImageWarning"))
742 return(ImageWarning);
743 break;
744 }
745 case 'M':
746 {
747 if (strEQ(name,"MaxRGB"))
748 return(QuantumRange);
749 if (strEQ(name,"MissingDelegateError"))
750 return(MissingDelegateError);
751 if (strEQ(name,"MissingDelegateWarning"))
752 return(MissingDelegateWarning);
753 if (strEQ(name,"ModuleError"))
754 return(ModuleError);
755 if (strEQ(name,"ModuleWarning"))
756 return(ModuleWarning);
757 break;
758 }
759 case 'O':
760 {
761 if (strEQ(name,"Opaque"))
762 return(OpaqueAlpha);
763 if (strEQ(name,"OptionError"))
764 return(OptionError);
765 if (strEQ(name,"OptionWarning"))
766 return(OptionWarning);
767 break;
768 }
769 case 'Q':
770 {
771 if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
772 return(MAGICKCORE_QUANTUM_DEPTH);
773 if (strEQ(name,"QuantumDepth"))
774 return(MAGICKCORE_QUANTUM_DEPTH);
775 if (strEQ(name,"QuantumRange"))
776 return(QuantumRange);
777 break;
778 }
779 case 'R':
780 {
781 if (strEQ(name,"ResourceLimitError"))
782 return(ResourceLimitError);
783 if (strEQ(name,"ResourceLimitWarning"))
784 return(ResourceLimitWarning);
785 if (strEQ(name,"RegistryError"))
786 return(RegistryError);
787 if (strEQ(name,"RegistryWarning"))
788 return(RegistryWarning);
789 break;
790 }
791 case 'S':
792 {
793 if (strEQ(name,"StreamError"))
794 return(StreamError);
795 if (strEQ(name,"StreamWarning"))
796 return(StreamWarning);
797 if (strEQ(name,"Success"))
798 return(0);
799 break;
800 }
801 case 'T':
802 {
803 if (strEQ(name,"Transparent"))
804 return(TransparentAlpha);
805 if (strEQ(name,"TypeError"))
806 return(TypeError);
807 if (strEQ(name,"TypeWarning"))
808 return(TypeWarning);
809 break;
810 }
811 case 'W':
812 {
813 if (strEQ(name,"WarningException"))
814 return(WarningException);
815 break;
816 }
817 case 'X':
818 {
819 if (strEQ(name,"XServerError"))
820 return(XServerError);
821 if (strEQ(name,"XServerWarning"))
822 return(XServerWarning);
823 break;
824 }
825 }
826 errno=EINVAL;
827 return(0);
828}
829
830/*
831%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
832% %
833% %
834% %
835% D e s t r o y P a c k a g e I n f o %
836% %
837% %
838% %
839%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
840%
841% Method DestroyPackageInfo frees a previously created info structure.
842%
843% The format of the DestroyPackageInfo routine is:
844%
845% DestroyPackageInfo(struct PackageInfo *info)
846%
847% A description of each parameter follows:
848%
849% o info: a structure of type info.
850%
851*/
852static void DestroyPackageInfo(struct PackageInfo *info)
853{
854 info->image_info=DestroyImageInfo(info->image_info);
855 info=(struct PackageInfo *) RelinquishMagickMemory(info);
856}
857
858/*
859%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
860% %
861% %
862% %
863% G e t L i s t %
864% %
865% %
866% %
867%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
868%
869% Method GetList is recursively called by SetupList to traverse the
870% Image__Magick reference. If building an reference_vector (see SetupList),
871% *current is the current position in *reference_vector and *last is the final
872% entry in *reference_vector.
873%
874% The format of the GetList routine is:
875%
876% GetList(info)
877%
878% A description of each parameter follows:
879%
880% o info: a structure of type info.
881%
882*/
883static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
884 ssize_t *current,ssize_t *last,ExceptionInfo *exception)
885{
886 Image
887 *image;
888
889 if (reference == (SV *) NULL)
890 return(NULL);
891 switch (SvTYPE(reference))
892 {
893 case SVt_PVAV:
894 {
895 AV
896 *av;
897
898 Image
899 *head,
900 *previous;
901
902 register ssize_t
903 i;
904
905 ssize_t
906 n;
907
908 /*
909 Array of images.
910 */
911 previous=(Image *) NULL;
912 head=(Image *) NULL;
913 av=(AV *) reference;
914 n=av_len(av);
915 for (i=0; i <= n; i++)
916 {
917 SV
918 **rv;
919
920 rv=av_fetch(av,i,0);
921 if (rv && *rv && sv_isobject(*rv))
922 {
923 image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
924 exception);
925 if (image == (Image *) NULL)
926 continue;
927 if (image == previous)
928 {
929 image=CloneImage(image,0,0,MagickTrue,exception);
930 if (image == (Image *) NULL)
931 return(NULL);
932 }
933 image->previous=previous;
934 *(previous ? &previous->next : &head)=image;
935 for (previous=image; previous->next; previous=previous->next) ;
936 }
937 }
938 return(head);
939 }
940 case SVt_PVMG:
941 {
942 /*
943 Blessed scalar, one image.
944 */
945 image=INT2PTR(Image *,SvIV(reference));
946 if (image == (Image *) NULL)
947 return(NULL);
948 image->previous=(Image *) NULL;
949 image->next=(Image *) NULL;
950 if (reference_vector)
951 {
952 if (*current == *last)
953 {
954 *last+=256;
955 if (*reference_vector == (SV **) NULL)
956 *reference_vector=(SV **) AcquireQuantumMemory(*last,
957 sizeof(*reference_vector));
958 else
959 *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
960 *last,sizeof(*reference_vector));
961 }
962 if (*reference_vector == (SV **) NULL)
963 {
964 ThrowPerlException(exception,ResourceLimitError,
965 "MemoryAllocationFailed",PackageName);
966 return((Image *) NULL);
967 }
968 (*reference_vector)[*current]=reference;
969 (*reference_vector)[++(*current)]=NULL;
970 }
971 return(image);
972 }
973 default:
974 break;
975 }
976 (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
977 (double) SvTYPE(reference));
978 return((Image *) NULL);
979}
980
981/*
982%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
983% %
984% %
985% %
986% G e t P a c k a g e I n f o %
987% %
988% %
989% %
990%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
991%
992% Method GetPackageInfo looks up or creates an info structure for the given
993% Image__Magick reference. If it does create a new one, the information in
994% package_info is used to initialize it.
995%
996% The format of the GetPackageInfo routine is:
997%
998% struct PackageInfo *GetPackageInfo(void *reference,
999% struct PackageInfo *package_info,ExceptionInfo *exception)
1000%
1001% A description of each parameter follows:
1002%
1003% o info: a structure of type info.
1004%
1005% o exception: Return any errors or warnings in this structure.
1006%
1007*/
1008static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
1009 struct PackageInfo *package_info,ExceptionInfo *exception)
1010{
1011 char
cristy151b66d2015-04-15 10:50:31 +00001012 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00001013
1014 struct PackageInfo
1015 *clone_info;
1016
1017 SV
1018 *sv;
1019
cristy151b66d2015-04-15 10:50:31 +00001020 (void) FormatLocaleString(message,MagickPathExtent,"%s::package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00001021 PackageName,XS_VERSION,reference);
1022 sv=perl_get_sv(message,(TRUE | 0x02));
1023 if (sv == (SV *) NULL)
1024 {
1025 ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
1026 message);
1027 return(package_info);
1028 }
1029 if (SvREFCNT(sv) == 0)
1030 (void) SvREFCNT_inc(sv);
1031 if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
1032 return(clone_info);
1033 clone_info=ClonePackageInfo(package_info,exception);
1034 sv_setiv(sv,PTR2IV(clone_info));
1035 return(clone_info);
1036}
1037
1038/*
1039%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1040% %
1041% %
1042% %
1043% S e t A t t r i b u t e %
1044% %
1045% %
1046% %
1047%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1048%
1049% SetAttribute() sets the attribute to the value in sval. This can change
1050% either or both of image or info.
1051%
1052% The format of the SetAttribute routine is:
1053%
1054% SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
1055% SV *sval,ExceptionInfo *exception)
1056%
1057% A description of each parameter follows:
1058%
1059% o list: a list of strings.
1060%
1061% o string: a character string.
1062%
1063*/
1064
1065static double SiPrefixToDoubleInterval(const char *string,const double interval)
1066{
1067 char
1068 *q;
1069
1070 double
1071 value;
1072
1073 value=InterpretSiPrefixValue(string,&q);
1074 if (*q == '%')
1075 value*=interval/100.0;
1076 return(value);
1077}
1078
1079static inline double StringToDouble(const char *string,char **sentinal)
1080{
1081 return(InterpretLocaleValue(string,sentinal));
1082}
1083
1084static double StringToDoubleInterval(const char *string,const double interval)
1085{
1086 char
1087 *q;
1088
1089 double
1090 value;
1091
1092 value=InterpretLocaleValue(string,&q);
1093 if (*q == '%')
1094 value*=interval/100.0;
1095 return(value);
1096}
1097
1098static inline ssize_t StringToLong(const char *value)
1099{
1100 return(strtol(value,(char **) NULL,10));
1101}
1102
1103static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
1104 const char *attribute,SV *sval,ExceptionInfo *exception)
1105{
1106 GeometryInfo
1107 geometry_info;
1108
1109 long
1110 x,
1111 y;
1112
1113 PixelInfo
1114 pixel;
1115
1116 MagickStatusType
1117 flags;
1118
1119 PixelInfo
1120 *color,
1121 target_color;
1122
1123 ssize_t
1124 sp;
1125
1126 switch (*attribute)
1127 {
1128 case 'A':
1129 case 'a':
1130 {
1131 if (LocaleCompare(attribute,"adjoin") == 0)
1132 {
1133 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1134 SvPV(sval,na)) : SvIV(sval);
1135 if (sp < 0)
1136 {
1137 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1138 SvPV(sval,na));
1139 break;
1140 }
1141 if (info)
1142 info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
1143 break;
1144 }
1145 if (LocaleCompare(attribute,"alpha") == 0)
1146 {
1147 sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
1148 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1149 if (sp < 0)
1150 {
1151 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1152 SvPV(sval,na));
1153 break;
1154 }
1155 for ( ; image; image=image->next)
1156 (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
1157 exception);
1158 break;
1159 }
1160 if (LocaleCompare(attribute,"antialias") == 0)
1161 {
1162 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1163 SvPV(sval,na)) : SvIV(sval);
1164 if (sp < 0)
1165 {
1166 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1167 SvPV(sval,na));
1168 break;
1169 }
1170 if (info)
1171 info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
1172 break;
1173 }
1174 if (LocaleCompare(attribute,"area-limit") == 0)
1175 {
1176 MagickSizeType
1177 limit;
1178
1179 limit=MagickResourceInfinity;
1180 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1181 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1182 100.0);
1183 (void) SetMagickResourceLimit(AreaResource,limit);
1184 break;
1185 }
1186 if (LocaleCompare(attribute,"attenuate") == 0)
1187 {
1188 if (info)
1189 (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
1190 break;
1191 }
1192 if (LocaleCompare(attribute,"authenticate") == 0)
1193 {
1194 if (info)
1195 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1196 break;
1197 }
1198 if (info)
1199 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1200 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001201 {
1202 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstra337c9bc2017-04-03 16:04:21 +02001203 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001204 }
cristy4a3ce0a2013-08-03 20:06:59 +00001205 break;
1206 }
1207 case 'B':
1208 case 'b':
1209 {
1210 if (LocaleCompare(attribute,"background") == 0)
1211 {
1212 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1213 exception);
1214 if (info)
1215 info->image_info->background_color=target_color;
1216 for ( ; image; image=image->next)
1217 image->background_color=target_color;
1218 break;
1219 }
1220 if (LocaleCompare(attribute,"blue-primary") == 0)
1221 {
1222 for ( ; image; image=image->next)
1223 {
1224 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1225 image->chromaticity.blue_primary.x=geometry_info.rho;
1226 image->chromaticity.blue_primary.y=geometry_info.sigma;
1227 if ((flags & SigmaValue) == 0)
1228 image->chromaticity.blue_primary.y=
1229 image->chromaticity.blue_primary.x;
1230 }
1231 break;
1232 }
1233 if (LocaleCompare(attribute,"bordercolor") == 0)
1234 {
1235 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1236 exception);
1237 if (info)
1238 info->image_info->border_color=target_color;
1239 for ( ; image; image=image->next)
1240 image->border_color=target_color;
1241 break;
1242 }
1243 if (info)
1244 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1245 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001246 {
1247 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001248 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001249 }
cristy4a3ce0a2013-08-03 20:06:59 +00001250 break;
1251 }
1252 case 'C':
1253 case 'c':
1254 {
1255 if (LocaleCompare(attribute,"cache-threshold") == 0)
1256 {
1257 (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
1258 SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
1259 (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
1260 (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
1261 break;
1262 }
1263 if (LocaleCompare(attribute,"clip-mask") == 0)
1264 {
1265 Image
1266 *clip_mask;
1267
1268 clip_mask=(Image *) NULL;
1269 if (SvPOK(sval))
1270 clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1271 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001272 SetImageMask(image,ReadPixelMask,clip_mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001273 break;
1274 }
1275 if (LocaleNCompare(attribute,"colormap",8) == 0)
1276 {
1277 for ( ; image; image=image->next)
1278 {
1279 int
1280 items;
1281
1282 long
1283 i;
1284
1285 if (image->storage_class == DirectClass)
1286 continue;
1287 i=0;
1288 items=sscanf(attribute,"%*[^[][%ld",&i);
1289 (void) items;
1290 if (i > (ssize_t) image->colors)
1291 i%=image->colors;
1292 if ((strchr(SvPV(sval,na),',') == 0) ||
1293 (strchr(SvPV(sval,na),')') != 0))
1294 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1295 image->colormap+i,exception);
1296 else
1297 {
1298 color=image->colormap+i;
1299 pixel.red=color->red;
1300 pixel.green=color->green;
1301 pixel.blue=color->blue;
1302 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1303 pixel.red=geometry_info.rho;
1304 pixel.green=geometry_info.sigma;
1305 pixel.blue=geometry_info.xi;
1306 color->red=ClampToQuantum(pixel.red);
1307 color->green=ClampToQuantum(pixel.green);
1308 color->blue=ClampToQuantum(pixel.blue);
1309 }
1310 }
1311 break;
1312 }
1313 if (LocaleCompare(attribute,"colorspace") == 0)
1314 {
1315 sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
1316 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1317 if (sp < 0)
1318 {
1319 ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
1320 SvPV(sval,na));
1321 break;
1322 }
1323 for ( ; image; image=image->next)
Cristy59262d92016-12-05 15:21:50 -05001324 (void) SetImageColorspace(image,(ColorspaceType) sp,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001325 break;
1326 }
1327 if (LocaleCompare(attribute,"comment") == 0)
1328 {
1329 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001330 (void) SetImageProperty(image,"Comment",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00001331 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04001332 SvPV(sval,na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001333 break;
1334 }
1335 if (LocaleCompare(attribute,"compression") == 0)
1336 {
1337 sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
1338 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1339 if (sp < 0)
1340 {
1341 ThrowPerlException(exception,OptionError,
1342 "UnrecognizedImageCompression",SvPV(sval,na));
1343 break;
1344 }
1345 if (info)
1346 info->image_info->compression=(CompressionType) sp;
1347 for ( ; image; image=image->next)
1348 image->compression=(CompressionType) sp;
1349 break;
1350 }
1351 if (info)
1352 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1353 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001354 {
1355 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001356 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001357 }
cristy4a3ce0a2013-08-03 20:06:59 +00001358 break;
1359 }
1360 case 'D':
1361 case 'd':
1362 {
1363 if (LocaleCompare(attribute,"debug") == 0)
1364 {
1365 SetLogEventMask(SvPV(sval,na));
1366 break;
1367 }
1368 if (LocaleCompare(attribute,"delay") == 0)
1369 {
1370 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1371 for ( ; image; image=image->next)
1372 {
1373 image->delay=(size_t) floor(geometry_info.rho+0.5);
1374 if ((flags & SigmaValue) != 0)
1375 image->ticks_per_second=(ssize_t)
1376 floor(geometry_info.sigma+0.5);
1377 }
1378 break;
1379 }
1380 if (LocaleCompare(attribute,"disk-limit") == 0)
1381 {
1382 MagickSizeType
1383 limit;
1384
1385 limit=MagickResourceInfinity;
1386 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1387 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1388 100.0);
1389 (void) SetMagickResourceLimit(DiskResource,limit);
1390 break;
1391 }
1392 if (LocaleCompare(attribute,"density") == 0)
1393 {
1394 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
1395 {
1396 ThrowPerlException(exception,OptionError,"MissingGeometry",
1397 SvPV(sval,na));
1398 break;
1399 }
1400 if (info)
1401 (void) CloneString(&info->image_info->density,SvPV(sval,na));
1402 for ( ; image; image=image->next)
1403 {
1404 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1405 image->resolution.x=geometry_info.rho;
1406 image->resolution.y=geometry_info.sigma;
1407 if ((flags & SigmaValue) == 0)
1408 image->resolution.y=image->resolution.x;
1409 }
1410 break;
1411 }
1412 if (LocaleCompare(attribute,"depth") == 0)
1413 {
1414 if (info)
1415 info->image_info->depth=SvIV(sval);
1416 for ( ; image; image=image->next)
1417 (void) SetImageDepth(image,SvIV(sval),exception);
1418 break;
1419 }
1420 if (LocaleCompare(attribute,"dispose") == 0)
1421 {
1422 sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
1423 SvPV(sval,na)) : SvIV(sval);
1424 if (sp < 0)
1425 {
1426 ThrowPerlException(exception,OptionError,
1427 "UnrecognizedDisposeMethod",SvPV(sval,na));
1428 break;
1429 }
1430 for ( ; image; image=image->next)
1431 image->dispose=(DisposeType) sp;
1432 break;
1433 }
1434 if (LocaleCompare(attribute,"dither") == 0)
1435 {
1436 if (info)
1437 {
1438 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
1439 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1440 if (sp < 0)
1441 {
1442 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1443 SvPV(sval,na));
1444 break;
1445 }
1446 info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
1447 }
1448 break;
1449 }
1450 if (LocaleCompare(attribute,"display") == 0)
1451 {
1452 display:
1453 if (info)
1454 (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
1455 break;
1456 }
1457 if (info)
1458 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1459 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001460 {
1461 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001462 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001463 }
cristy4a3ce0a2013-08-03 20:06:59 +00001464 break;
1465 }
1466 case 'E':
1467 case 'e':
1468 {
1469 if (LocaleCompare(attribute,"endian") == 0)
1470 {
1471 sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
1472 SvPV(sval,na)) : SvIV(sval);
1473 if (sp < 0)
1474 {
1475 ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
1476 SvPV(sval,na));
1477 break;
1478 }
1479 if (info)
1480 info->image_info->endian=(EndianType) sp;
1481 for ( ; image; image=image->next)
1482 image->endian=(EndianType) sp;
1483 break;
1484 }
1485 if (LocaleCompare(attribute,"extract") == 0)
1486 {
1487 /*
1488 Set image extract geometry.
1489 */
1490 (void) CloneString(&info->image_info->extract,SvPV(sval,na));
1491 break;
1492 }
1493 if (info)
1494 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1495 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001496 {
1497 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001498 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001499 }
cristy4a3ce0a2013-08-03 20:06:59 +00001500 break;
1501 }
1502 case 'F':
1503 case 'f':
1504 {
1505 if (LocaleCompare(attribute,"filename") == 0)
1506 {
1507 if (info)
1508 (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001509 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001510 for ( ; image; image=image->next)
1511 (void) CopyMagickString(image->filename,SvPV(sval,na),
cristy151b66d2015-04-15 10:50:31 +00001512 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001513 break;
1514 }
1515 if (LocaleCompare(attribute,"file") == 0)
1516 {
1517 FILE
1518 *file;
1519
1520 PerlIO
1521 *io_info;
1522
1523 if (info == (struct PackageInfo *) NULL)
1524 break;
1525 io_info=IoIFP(sv_2io(sval));
1526 if (io_info == (PerlIO *) NULL)
1527 {
1528 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1529 PackageName);
1530 break;
1531 }
1532 file=PerlIO_findFILE(io_info);
1533 if (file == (FILE *) NULL)
1534 {
1535 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
1536 PackageName);
1537 break;
1538 }
1539 SetImageInfoFile(info->image_info,file);
1540 break;
1541 }
1542 if (LocaleCompare(attribute,"fill") == 0)
1543 {
1544 if (info)
1545 (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
1546 break;
1547 }
1548 if (LocaleCompare(attribute,"font") == 0)
1549 {
1550 if (info)
1551 (void) CloneString(&info->image_info->font,SvPV(sval,na));
1552 break;
1553 }
1554 if (LocaleCompare(attribute,"foreground") == 0)
1555 break;
1556 if (LocaleCompare(attribute,"fuzz") == 0)
1557 {
1558 if (info)
1559 info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1560 QuantumRange+1.0);
1561 for ( ; image; image=image->next)
1562 image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
1563 QuantumRange+1.0);
1564 break;
1565 }
1566 if (info)
1567 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1568 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001569 {
1570 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001571 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001572 }
cristy4a3ce0a2013-08-03 20:06:59 +00001573 break;
1574 }
1575 case 'G':
1576 case 'g':
1577 {
1578 if (LocaleCompare(attribute,"gamma") == 0)
1579 {
1580 for ( ; image; image=image->next)
1581 image->gamma=SvNV(sval);
1582 break;
1583 }
1584 if (LocaleCompare(attribute,"gravity") == 0)
1585 {
1586 sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
1587 SvPV(sval,na)) : SvIV(sval);
1588 if (sp < 0)
1589 {
1590 ThrowPerlException(exception,OptionError,
1591 "UnrecognizedGravityType",SvPV(sval,na));
1592 break;
1593 }
1594 if (info)
1595 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1596 for ( ; image; image=image->next)
1597 image->gravity=(GravityType) sp;
1598 break;
1599 }
1600 if (LocaleCompare(attribute,"green-primary") == 0)
1601 {
1602 for ( ; image; image=image->next)
1603 {
1604 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1605 image->chromaticity.green_primary.x=geometry_info.rho;
1606 image->chromaticity.green_primary.y=geometry_info.sigma;
1607 if ((flags & SigmaValue) == 0)
1608 image->chromaticity.green_primary.y=
1609 image->chromaticity.green_primary.x;
1610 }
1611 break;
1612 }
1613 if (info)
1614 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1615 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001616 {
1617 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001618 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001619 }
cristy4a3ce0a2013-08-03 20:06:59 +00001620 break;
1621 }
1622 case 'I':
1623 case 'i':
1624 {
1625 if (LocaleNCompare(attribute,"index",5) == 0)
1626 {
1627 int
1628 items;
1629
1630 long
1631 index;
1632
1633 register Quantum
1634 *q;
1635
1636 CacheView
1637 *image_view;
1638
1639 for ( ; image; image=image->next)
1640 {
1641 if (image->storage_class != PseudoClass)
1642 continue;
1643 x=0;
1644 y=0;
1645 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1646 (void) items;
1647 image_view=AcquireAuthenticCacheView(image,exception);
1648 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1649 if (q != (Quantum *) NULL)
1650 {
1651 items=sscanf(SvPV(sval,na),"%ld",&index);
1652 if ((index >= 0) && (index < (ssize_t) image->colors))
1653 SetPixelIndex(image,index,q);
1654 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1655 }
1656 image_view=DestroyCacheView(image_view);
1657 }
1658 break;
1659 }
1660 if (LocaleCompare(attribute,"iterations") == 0)
1661 {
1662 iterations:
1663 for ( ; image; image=image->next)
1664 image->iterations=SvIV(sval);
1665 break;
1666 }
1667 if (LocaleCompare(attribute,"interlace") == 0)
1668 {
1669 sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
1670 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1671 if (sp < 0)
1672 {
1673 ThrowPerlException(exception,OptionError,
1674 "UnrecognizedInterlaceType",SvPV(sval,na));
1675 break;
1676 }
1677 if (info)
1678 info->image_info->interlace=(InterlaceType) sp;
1679 for ( ; image; image=image->next)
1680 image->interlace=(InterlaceType) sp;
1681 break;
1682 }
1683 if (info)
1684 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1685 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001686 {
1687 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001688 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001689 }
cristy4a3ce0a2013-08-03 20:06:59 +00001690 break;
1691 }
1692 case 'L':
1693 case 'l':
1694 {
1695 if (LocaleCompare(attribute,"label") == 0)
1696 {
1697 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001698 (void) SetImageProperty(image,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00001699 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04001700 SvPV(sval,na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001701 break;
1702 }
1703 if (LocaleCompare(attribute,"loop") == 0)
1704 goto iterations;
1705 if (info)
1706 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1707 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001708 {
1709 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001710 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001711 }
cristy4a3ce0a2013-08-03 20:06:59 +00001712 break;
1713 }
1714 case 'M':
1715 case 'm':
1716 {
1717 if (LocaleCompare(attribute,"magick") == 0)
1718 {
1719 if (info)
Cristyb5b1f5d2017-03-31 16:42:35 -04001720 (void) FormatLocaleString(info->image_info->filename,
1721 MagickPathExtent,"%s:",SvPV(sval,na));
cristy4a3ce0a2013-08-03 20:06:59 +00001722 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001723 (void) CopyMagickString(image->magick,SvPV(sval,na),
1724 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00001725 break;
1726 }
1727 if (LocaleCompare(attribute,"map-limit") == 0)
1728 {
1729 MagickSizeType
1730 limit;
1731
1732 limit=MagickResourceInfinity;
1733 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1734 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1735 100.0);
1736 (void) SetMagickResourceLimit(MapResource,limit);
1737 break;
1738 }
1739 if (LocaleCompare(attribute,"mask") == 0)
1740 {
1741 Image
1742 *mask;
1743
1744 mask=(Image *) NULL;
1745 if (SvPOK(sval))
1746 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1747 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001748 SetImageMask(image,ReadPixelMask,mask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00001749 break;
1750 }
1751 if (LocaleCompare(attribute,"mattecolor") == 0)
1752 {
1753 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
1754 exception);
1755 if (info)
Cristy8645e042016-02-03 16:35:29 -05001756 info->image_info->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001757 for ( ; image; image=image->next)
Cristy8645e042016-02-03 16:35:29 -05001758 image->alpha_color=target_color;
cristy4a3ce0a2013-08-03 20:06:59 +00001759 break;
1760 }
1761 if (LocaleCompare(attribute,"matte") == 0)
1762 {
1763 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1764 SvPV(sval,na)) : SvIV(sval);
1765 if (sp < 0)
1766 {
1767 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1768 SvPV(sval,na));
1769 break;
1770 }
1771 for ( ; image; image=image->next)
1772 image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
1773 break;
1774 }
1775 if (LocaleCompare(attribute,"memory-limit") == 0)
1776 {
1777 MagickSizeType
1778 limit;
1779
1780 limit=MagickResourceInfinity;
1781 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
1782 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
1783 100.0);
1784 (void) SetMagickResourceLimit(MemoryResource,limit);
1785 break;
1786 }
1787 if (LocaleCompare(attribute,"monochrome") == 0)
1788 {
1789 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
1790 SvPV(sval,na)) : SvIV(sval);
1791 if (sp < 0)
1792 {
1793 ThrowPerlException(exception,OptionError,"UnrecognizedType",
1794 SvPV(sval,na));
1795 break;
1796 }
1797 if (info)
1798 info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
1799 for ( ; image; image=image->next)
1800 (void) SetImageType(image,BilevelType,exception);
1801 break;
1802 }
1803 if (info)
1804 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1805 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001806 {
1807 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001808 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001809 }
cristy4a3ce0a2013-08-03 20:06:59 +00001810 break;
1811 }
1812 case 'O':
1813 case 'o':
1814 {
1815 if (LocaleCompare(attribute,"option") == 0)
1816 {
1817 if (info)
1818 DefineImageOption(info->image_info,SvPV(sval,na));
1819 break;
1820 }
1821 if (LocaleCompare(attribute,"orientation") == 0)
1822 {
1823 sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
1824 MagickFalse,SvPV(sval,na)) : SvIV(sval);
1825 if (sp < 0)
1826 {
1827 ThrowPerlException(exception,OptionError,
1828 "UnrecognizedOrientationType",SvPV(sval,na));
1829 break;
1830 }
1831 if (info)
1832 info->image_info->orientation=(OrientationType) sp;
1833 for ( ; image; image=image->next)
1834 image->orientation=(OrientationType) sp;
1835 break;
1836 }
1837 if (info)
1838 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1839 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001840 {
1841 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001842 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001843 }
cristy4a3ce0a2013-08-03 20:06:59 +00001844 break;
1845 }
1846 case 'P':
1847 case 'p':
1848 {
1849 if (LocaleCompare(attribute,"page") == 0)
1850 {
1851 char
1852 *geometry;
1853
1854 geometry=GetPageGeometry(SvPV(sval,na));
1855 if (info)
1856 (void) CloneString(&info->image_info->page,geometry);
1857 for ( ; image; image=image->next)
1858 (void) ParsePageGeometry(image,geometry,&image->page,exception);
1859 geometry=(char *) RelinquishMagickMemory(geometry);
1860 break;
1861 }
1862 if (LocaleNCompare(attribute,"pixel",5) == 0)
1863 {
1864 int
1865 items;
1866
1867 PixelInfo
1868 pixel;
1869
1870 register Quantum
1871 *q;
1872
1873 CacheView
1874 *image_view;
1875
1876 for ( ; image; image=image->next)
1877 {
1878 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1879 break;
1880 x=0;
1881 y=0;
1882 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
1883 (void) items;
1884 image_view=AcquireVirtualCacheView(image,exception);
1885 q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
1886 if (q != (Quantum *) NULL)
1887 {
1888 if ((strchr(SvPV(sval,na),',') == 0) ||
1889 (strchr(SvPV(sval,na),')') != 0))
1890 QueryColorCompliance(SvPV(sval,na),AllCompliance,
1891 &pixel,exception);
1892 else
1893 {
1894 GetPixelInfo(image,&pixel);
1895 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1896 pixel.red=geometry_info.rho;
1897 if ((flags & SigmaValue) != 0)
1898 pixel.green=geometry_info.sigma;
1899 if ((flags & XiValue) != 0)
1900 pixel.blue=geometry_info.xi;
1901 if ((flags & PsiValue) != 0)
1902 pixel.alpha=geometry_info.psi;
1903 if ((flags & ChiValue) != 0)
1904 pixel.black=geometry_info.chi;
1905 }
1906 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1907 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1908 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1909 if (image->colorspace == CMYKColorspace)
1910 SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1911 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1912 (void) SyncCacheViewAuthenticPixels(image_view,exception);
1913 }
1914 image_view=DestroyCacheView(image_view);
1915 }
1916 break;
1917 }
1918 if (LocaleCompare(attribute,"pointsize") == 0)
1919 {
1920 if (info)
1921 {
1922 (void) ParseGeometry(SvPV(sval,na),&geometry_info);
1923 info->image_info->pointsize=geometry_info.rho;
1924 }
1925 break;
1926 }
Cristy798981a2020-02-17 12:07:15 -05001927 if (LocaleCompare(attribute,"precision") == 0)
1928 {
1929 (void) SetMagickPrecision(SvIV(sval));
1930 break;
1931 }
cristy4a3ce0a2013-08-03 20:06:59 +00001932 if (info)
1933 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1934 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001935 {
1936 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001937 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001938 }
cristy4a3ce0a2013-08-03 20:06:59 +00001939 break;
1940 }
1941 case 'Q':
1942 case 'q':
1943 {
1944 if (LocaleCompare(attribute,"quality") == 0)
1945 {
1946 if (info)
1947 info->image_info->quality=SvIV(sval);
1948 for ( ; image; image=image->next)
1949 image->quality=SvIV(sval);
1950 break;
1951 }
1952 if (info)
1953 SetImageOption(info->image_info,attribute,SvPV(sval,na));
1954 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04001955 {
1956 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02001957 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04001958 }
cristy4a3ce0a2013-08-03 20:06:59 +00001959 break;
1960 }
1961 case 'R':
1962 case 'r':
1963 {
cristyc0fe4752015-07-27 18:02:39 +00001964 if (LocaleCompare(attribute,"read-mask") == 0)
1965 {
1966 Image
1967 *mask;
1968
1969 mask=(Image *) NULL;
1970 if (SvPOK(sval))
1971 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
1972 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00001973 SetImageMask(image,ReadPixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00001974 break;
1975 }
cristy4a3ce0a2013-08-03 20:06:59 +00001976 if (LocaleCompare(attribute,"red-primary") == 0)
1977 {
1978 for ( ; image; image=image->next)
1979 {
1980 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
1981 image->chromaticity.red_primary.x=geometry_info.rho;
1982 image->chromaticity.red_primary.y=geometry_info.sigma;
1983 if ((flags & SigmaValue) == 0)
1984 image->chromaticity.red_primary.y=
1985 image->chromaticity.red_primary.x;
1986 }
1987 break;
1988 }
1989 if (LocaleCompare(attribute,"render") == 0)
1990 {
1991 sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
1992 SvPV(sval,na)) : SvIV(sval);
1993 if (sp < 0)
1994 {
1995 ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
1996 SvPV(sval,na));
1997 break;
1998 }
1999 for ( ; image; image=image->next)
2000 image->rendering_intent=(RenderingIntent) sp;
2001 break;
2002 }
2003 if (LocaleCompare(attribute,"repage") == 0)
2004 {
2005 RectangleInfo
2006 geometry;
2007
2008 for ( ; image; image=image->next)
2009 {
2010 flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
2011 if ((flags & WidthValue) != 0)
2012 {
2013 if ((flags & HeightValue) == 0)
2014 geometry.height=geometry.width;
2015 image->page.width=geometry.width;
2016 image->page.height=geometry.height;
2017 }
2018 if ((flags & AspectValue) != 0)
2019 {
2020 if ((flags & XValue) != 0)
2021 image->page.x+=geometry.x;
2022 if ((flags & YValue) != 0)
2023 image->page.y+=geometry.y;
2024 }
2025 else
2026 {
2027 if ((flags & XValue) != 0)
2028 {
2029 image->page.x=geometry.x;
2030 if (((flags & WidthValue) != 0) && (geometry.x > 0))
2031 image->page.width=image->columns+geometry.x;
2032 }
2033 if ((flags & YValue) != 0)
2034 {
2035 image->page.y=geometry.y;
2036 if (((flags & HeightValue) != 0) && (geometry.y > 0))
2037 image->page.height=image->rows+geometry.y;
2038 }
2039 }
2040 }
2041 break;
2042 }
2043 if (info)
2044 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2045 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002046 {
2047 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002048 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002049 }
cristy4a3ce0a2013-08-03 20:06:59 +00002050 break;
2051 }
2052 case 'S':
2053 case 's':
2054 {
2055 if (LocaleCompare(attribute,"sampling-factor") == 0)
2056 {
2057 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2058 {
2059 ThrowPerlException(exception,OptionError,"MissingGeometry",
2060 SvPV(sval,na));
2061 break;
2062 }
2063 if (info)
2064 (void) CloneString(&info->image_info->sampling_factor,
2065 SvPV(sval,na));
2066 break;
2067 }
2068 if (LocaleCompare(attribute,"scene") == 0)
2069 {
2070 for ( ; image; image=image->next)
2071 image->scene=SvIV(sval);
2072 break;
2073 }
2074 if (LocaleCompare(attribute,"server") == 0)
2075 goto display;
2076 if (LocaleCompare(attribute,"size") == 0)
2077 {
2078 if (info)
2079 {
2080 if (IsGeometry(SvPV(sval,na)) == MagickFalse)
2081 {
2082 ThrowPerlException(exception,OptionError,"MissingGeometry",
2083 SvPV(sval,na));
2084 break;
2085 }
2086 (void) CloneString(&info->image_info->size,SvPV(sval,na));
2087 }
2088 break;
2089 }
2090 if (LocaleCompare(attribute,"stroke") == 0)
2091 {
2092 if (info)
2093 (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
2094 break;
2095 }
2096 if (info)
2097 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2098 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002099 {
2100 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002101 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002102 }
cristy4a3ce0a2013-08-03 20:06:59 +00002103 break;
2104 }
2105 case 'T':
2106 case 't':
2107 {
2108 if (LocaleCompare(attribute,"texture") == 0)
2109 {
2110 if (info)
2111 (void) CloneString(&info->image_info->texture,SvPV(sval,na));
2112 break;
2113 }
2114 if (LocaleCompare(attribute,"thread-limit") == 0)
2115 {
2116 MagickSizeType
2117 limit;
2118
2119 limit=MagickResourceInfinity;
2120 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2121 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2122 100.0);
2123 (void) SetMagickResourceLimit(ThreadResource,limit);
2124 break;
2125 }
2126 if (LocaleCompare(attribute,"tile-offset") == 0)
2127 {
2128 char
2129 *geometry;
2130
2131 geometry=GetPageGeometry(SvPV(sval,na));
2132 if (info)
2133 (void) CloneString(&info->image_info->page,geometry);
2134 for ( ; image; image=image->next)
2135 (void) ParsePageGeometry(image,geometry,&image->tile_offset,
2136 exception);
2137 geometry=(char *) RelinquishMagickMemory(geometry);
2138 break;
2139 }
2140 if (LocaleCompare(attribute,"time-limit") == 0)
2141 {
2142 MagickSizeType
2143 limit;
2144
2145 limit=MagickResourceInfinity;
2146 if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
2147 limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
2148 100.0);
2149 (void) SetMagickResourceLimit(TimeResource,limit);
2150 break;
2151 }
2152 if (LocaleCompare(attribute,"transparent-color") == 0)
2153 {
2154 (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
2155 exception);
2156 if (info)
2157 info->image_info->transparent_color=target_color;
2158 for ( ; image; image=image->next)
2159 image->transparent_color=target_color;
2160 break;
2161 }
2162 if (LocaleCompare(attribute,"type") == 0)
2163 {
2164 sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
2165 SvPV(sval,na)) : SvIV(sval);
2166 if (sp < 0)
2167 {
2168 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2169 SvPV(sval,na));
2170 break;
2171 }
2172 if (info)
2173 info->image_info->type=(ImageType) sp;
2174 for ( ; image; image=image->next)
2175 SetImageType(image,(ImageType) sp,exception);
2176 break;
2177 }
2178 if (info)
2179 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2180 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002181 {
2182 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002183 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002184 }
cristy4a3ce0a2013-08-03 20:06:59 +00002185 break;
2186 }
2187 case 'U':
2188 case 'u':
2189 {
2190 if (LocaleCompare(attribute,"units") == 0)
2191 {
2192 sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
2193 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2194 if (sp < 0)
2195 {
2196 ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
2197 SvPV(sval,na));
2198 break;
2199 }
2200 if (info)
2201 info->image_info->units=(ResolutionType) sp;
2202 for ( ; image; image=image->next)
2203 {
2204 ResolutionType
2205 units;
2206
2207 units=(ResolutionType) sp;
2208 if (image->units != units)
2209 switch (image->units)
2210 {
2211 case UndefinedResolution:
2212 case PixelsPerInchResolution:
2213 {
2214 if (units == PixelsPerCentimeterResolution)
2215 {
2216 image->resolution.x*=2.54;
2217 image->resolution.y*=2.54;
2218 }
2219 break;
2220 }
2221 case PixelsPerCentimeterResolution:
2222 {
2223 if (units == PixelsPerInchResolution)
2224 {
2225 image->resolution.x/=2.54;
2226 image->resolution.y/=2.54;
2227 }
2228 break;
2229 }
2230 }
2231 image->units=units;
2232 }
2233 break;
2234 }
2235 if (info)
2236 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2237 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002238 {
2239 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002240 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002241 }
cristy4a3ce0a2013-08-03 20:06:59 +00002242 break;
2243 }
2244 case 'V':
2245 case 'v':
2246 {
2247 if (LocaleCompare(attribute,"verbose") == 0)
2248 {
2249 sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
2250 SvPV(sval,na)) : SvIV(sval);
2251 if (sp < 0)
2252 {
2253 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2254 SvPV(sval,na));
2255 break;
2256 }
2257 if (info)
2258 info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
2259 break;
2260 }
cristy4a3ce0a2013-08-03 20:06:59 +00002261 if (LocaleCompare(attribute,"virtual-pixel") == 0)
2262 {
2263 sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
2264 MagickFalse,SvPV(sval,na)) : SvIV(sval);
2265 if (sp < 0)
2266 {
2267 ThrowPerlException(exception,OptionError,
2268 "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
2269 break;
2270 }
2271 for ( ; image; image=image->next)
2272 SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
2273 break;
2274 }
2275 if (info)
2276 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2277 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002278 {
2279 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002280 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002281 }
cristy4a3ce0a2013-08-03 20:06:59 +00002282 break;
2283 }
2284 case 'W':
2285 case 'w':
2286 {
2287 if (LocaleCompare(attribute,"white-point") == 0)
2288 {
2289 for ( ; image; image=image->next)
2290 {
2291 flags=ParseGeometry(SvPV(sval,na),&geometry_info);
2292 image->chromaticity.white_point.x=geometry_info.rho;
2293 image->chromaticity.white_point.y=geometry_info.sigma;
2294 if ((flags & SigmaValue) == 0)
2295 image->chromaticity.white_point.y=
2296 image->chromaticity.white_point.x;
2297 }
2298 break;
2299 }
cristyc0fe4752015-07-27 18:02:39 +00002300 if (LocaleCompare(attribute,"write-mask") == 0)
2301 {
2302 Image
2303 *mask;
2304
2305 mask=(Image *) NULL;
2306 if (SvPOK(sval))
2307 mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
2308 for ( ; image; image=image->next)
cristy1f7ffb72015-07-29 11:07:03 +00002309 SetImageMask(image,WritePixelMask,mask,exception);
cristyc0fe4752015-07-27 18:02:39 +00002310 break;
2311 }
cristy4a3ce0a2013-08-03 20:06:59 +00002312 if (info)
2313 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2314 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002315 {
2316 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002317 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002318 }
cristy4a3ce0a2013-08-03 20:06:59 +00002319 break;
2320 }
2321 default:
2322 {
2323 if (info)
2324 SetImageOption(info->image_info,attribute,SvPV(sval,na));
2325 for ( ; image; image=image->next)
Cristy935a4052017-03-31 17:45:37 -04002326 {
2327 (void) SetImageProperty(image,attribute,SvPV(sval,na),exception);
Dirk Lemstraf42b7fc2017-04-03 16:21:09 +02002328 (void) SetImageArtifact(image,attribute,SvPV(sval,na));
Cristy935a4052017-03-31 17:45:37 -04002329 }
cristy4a3ce0a2013-08-03 20:06:59 +00002330 break;
2331 }
2332 }
2333}
2334
2335/*
2336%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2337% %
2338% %
2339% %
2340% S e t u p L i s t %
2341% %
2342% %
2343% %
2344%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2345%
2346% Method SetupList returns the list of all the images linked by their
2347% image->next and image->previous link lists for use with ImageMagick. If
2348% info is non-NULL, an info structure is returned in *info. If
2349% reference_vector is non-NULL,an array of SV* are returned in
2350% *reference_vector. Reference_vector is used when the images are going to be
2351% replaced with new Image*'s.
2352%
2353% The format of the SetupList routine is:
2354%
2355% Image *SetupList(SV *reference,struct PackageInfo **info,
2356% SV ***reference_vector,ExceptionInfo *exception)
2357%
2358% A description of each parameter follows:
2359%
2360% o list: a list of strings.
2361%
2362% o string: a character string.
2363%
2364% o exception: Return any errors or warnings in this structure.
2365%
2366*/
2367static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
2368 SV ***reference_vector,ExceptionInfo *exception)
2369{
2370 Image
2371 *image;
2372
2373 ssize_t
2374 current,
2375 last;
2376
2377 if (reference_vector)
2378 *reference_vector=NULL;
2379 if (info)
2380 *info=NULL;
2381 current=0;
2382 last=0;
2383 image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
2384 if (info && (SvTYPE(reference) == SVt_PVAV))
2385 *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
2386 exception);
2387 return(image);
2388}
2389
2390/*
2391%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2392% %
2393% %
2394% %
2395% s t r E Q c a s e %
2396% %
2397% %
2398% %
2399%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2400%
2401% strEQcase() compares two strings and returns 0 if they are the
2402% same or if the second string runs out first. The comparison is case
2403% insensitive.
2404%
2405% The format of the strEQcase routine is:
2406%
2407% ssize_t strEQcase(const char *p,const char *q)
2408%
2409% A description of each parameter follows:
2410%
2411% o p: a character string.
2412%
2413% o q: a character string.
2414%
2415%
2416*/
2417static ssize_t strEQcase(const char *p,const char *q)
2418{
2419 char
2420 c;
2421
2422 register ssize_t
2423 i;
2424
2425 for (i=0 ; (c=(*q)) != 0; i++)
2426 {
2427 if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
2428 (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
2429 return(0);
2430 p++;
2431 q++;
2432 }
2433 return(((*q == 0) && (*p == 0)) ? i : 0);
2434}
2435
2436/*
2437%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2438% %
2439% %
2440% %
2441% I m a g e : : M a g i c k %
2442% %
2443% %
2444% %
2445%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2446%
2447%
2448*/
2449MODULE = Image::Magick PACKAGE = Image::Magick
2450
2451PROTOTYPES: ENABLE
2452
2453BOOT:
2454 MagickCoreGenesis("PerlMagick",MagickFalse);
2455 SetWarningHandler(NULL);
2456 SetErrorHandler(NULL);
2457 magick_registry=NewSplayTree((int (*)(const void *,const void *))
2458 NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
2459
2460void
2461UNLOAD()
2462 PPCODE:
2463 {
2464 if (magick_registry != (SplayTreeInfo *) NULL)
2465 magick_registry=DestroySplayTree(magick_registry);
2466 MagickCoreTerminus();
2467 }
2468
2469double
2470constant(name,argument)
2471 char *name
2472 ssize_t argument
2473
2474#
2475###############################################################################
2476# #
2477# #
2478# #
2479# A n i m a t e #
2480# #
2481# #
2482# #
2483###############################################################################
2484#
2485#
2486void
2487Animate(ref,...)
2488 Image::Magick ref=NO_INIT
2489 ALIAS:
2490 AnimateImage = 1
2491 animate = 2
2492 animateimage = 3
2493 PPCODE:
2494 {
2495 ExceptionInfo
2496 *exception;
2497
2498 Image
2499 *image;
2500
2501 register ssize_t
2502 i;
2503
2504 struct PackageInfo
2505 *info,
2506 *package_info;
2507
2508 SV
2509 *perl_exception,
2510 *reference;
2511
2512 PERL_UNUSED_VAR(ref);
2513 PERL_UNUSED_VAR(ix);
2514 exception=AcquireExceptionInfo();
2515 perl_exception=newSVpv("",0);
2516 package_info=(struct PackageInfo *) NULL;
2517 if (sv_isobject(ST(0)) == 0)
2518 {
2519 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2520 PackageName);
2521 goto PerlException;
2522 }
2523 reference=SvRV(ST(0));
2524 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2525 if (image == (Image *) NULL)
2526 {
2527 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2528 PackageName);
2529 goto PerlException;
2530 }
2531 package_info=ClonePackageInfo(info,exception);
2532 if (items == 2)
2533 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
2534 else
2535 if (items > 2)
2536 for (i=2; i < items; i+=2)
2537 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
2538 exception);
2539 (void) AnimateImages(package_info->image_info,image,exception);
2540 (void) CatchImageException(image);
2541
2542 PerlException:
2543 if (package_info != (struct PackageInfo *) NULL)
2544 DestroyPackageInfo(package_info);
2545 InheritPerlException(exception,perl_exception);
2546 exception=DestroyExceptionInfo(exception);
2547 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2548 SvPOK_on(perl_exception);
2549 ST(0)=sv_2mortal(perl_exception);
2550 XSRETURN(1);
2551 }
2552
2553#
2554###############################################################################
2555# #
2556# #
2557# #
2558# A p p e n d #
2559# #
2560# #
2561# #
2562###############################################################################
2563#
2564#
2565void
2566Append(ref,...)
2567 Image::Magick ref=NO_INIT
2568 ALIAS:
2569 AppendImage = 1
2570 append = 2
2571 appendimage = 3
2572 PPCODE:
2573 {
2574 AV
2575 *av;
2576
2577 char
2578 *attribute;
2579
2580 ExceptionInfo
2581 *exception;
2582
2583 HV
2584 *hv;
2585
2586 Image
2587 *image;
2588
2589 register ssize_t
2590 i;
2591
2592 ssize_t
2593 stack;
2594
2595 struct PackageInfo
2596 *info;
2597
2598 SV
2599 *av_reference,
2600 *perl_exception,
2601 *reference,
2602 *rv,
2603 *sv;
2604
2605 PERL_UNUSED_VAR(ref);
2606 PERL_UNUSED_VAR(ix);
2607 exception=AcquireExceptionInfo();
2608 perl_exception=newSVpv("",0);
2609 sv=NULL;
2610 attribute=NULL;
2611 av=NULL;
2612 if (sv_isobject(ST(0)) == 0)
2613 {
2614 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2615 PackageName);
2616 goto PerlException;
2617 }
2618 reference=SvRV(ST(0));
2619 hv=SvSTASH(reference);
2620 av=newAV();
2621 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2622 SvREFCNT_dec(av);
2623 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2624 if (image == (Image *) NULL)
2625 {
2626 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2627 PackageName);
2628 goto PerlException;
2629 }
2630 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
2631 /*
2632 Get options.
2633 */
2634 stack=MagickTrue;
2635 for (i=2; i < items; i+=2)
2636 {
2637 attribute=(char *) SvPV(ST(i-1),na);
2638 switch (*attribute)
2639 {
2640 case 'S':
2641 case 's':
2642 {
2643 if (LocaleCompare(attribute,"stack") == 0)
2644 {
2645 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
2646 SvPV(ST(i),na));
2647 if (stack < 0)
2648 {
2649 ThrowPerlException(exception,OptionError,"UnrecognizedType",
2650 SvPV(ST(i),na));
2651 return;
2652 }
2653 break;
2654 }
2655 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2656 attribute);
2657 break;
2658 }
2659 default:
2660 {
2661 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
2662 attribute);
2663 break;
2664 }
2665 }
2666 }
2667 image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
2668 if (image == (Image *) NULL)
2669 goto PerlException;
2670 for ( ; image; image=image->next)
2671 {
2672 AddImageToRegistry(sv,image);
2673 rv=newRV(sv);
2674 av_push(av,sv_bless(rv,hv));
2675 SvREFCNT_dec(sv);
2676 }
2677 exception=DestroyExceptionInfo(exception);
2678 ST(0)=av_reference;
2679 SvREFCNT_dec(perl_exception);
2680 XSRETURN(1);
2681
2682 PerlException:
2683 InheritPerlException(exception,perl_exception);
2684 exception=DestroyExceptionInfo(exception);
2685 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2686 SvPOK_on(perl_exception);
2687 ST(0)=sv_2mortal(perl_exception);
2688 XSRETURN(1);
2689 }
2690
2691#
2692###############################################################################
2693# #
2694# #
2695# #
2696# A v e r a g e #
2697# #
2698# #
2699# #
2700###############################################################################
2701#
2702#
2703void
2704Average(ref)
2705 Image::Magick ref=NO_INIT
2706 ALIAS:
2707 AverageImage = 1
2708 average = 2
2709 averageimage = 3
2710 PPCODE:
2711 {
2712 AV
2713 *av;
2714
2715 char
2716 *p;
2717
2718 ExceptionInfo
2719 *exception;
2720
2721 HV
2722 *hv;
2723
2724 Image
2725 *image;
2726
2727 struct PackageInfo
2728 *info;
2729
2730 SV
2731 *perl_exception,
2732 *reference,
2733 *rv,
2734 *sv;
2735
2736 PERL_UNUSED_VAR(ref);
2737 PERL_UNUSED_VAR(ix);
2738 exception=AcquireExceptionInfo();
2739 perl_exception=newSVpv("",0);
2740 sv=NULL;
2741 if (sv_isobject(ST(0)) == 0)
2742 {
2743 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2744 PackageName);
2745 goto PerlException;
2746 }
2747 reference=SvRV(ST(0));
2748 hv=SvSTASH(reference);
2749 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
2750 if (image == (Image *) NULL)
2751 {
2752 ThrowPerlException(exception,OptionError,"NoImagesDefined",
2753 PackageName);
2754 goto PerlException;
2755 }
2756 image=EvaluateImages(image,MeanEvaluateOperator,exception);
2757 if (image == (Image *) NULL)
2758 goto PerlException;
2759 /*
2760 Create blessed Perl array for the returned image.
2761 */
2762 av=newAV();
2763 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
2764 SvREFCNT_dec(av);
2765 AddImageToRegistry(sv,image);
2766 rv=newRV(sv);
2767 av_push(av,sv_bless(rv,hv));
2768 SvREFCNT_dec(sv);
2769 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00002770 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
2771 "average-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00002772 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
2773 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00002774 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00002775 SetImageInfo(info->image_info,0,exception);
2776 exception=DestroyExceptionInfo(exception);
2777 SvREFCNT_dec(perl_exception);
2778 XSRETURN(1);
2779
2780 PerlException:
2781 InheritPerlException(exception,perl_exception);
2782 exception=DestroyExceptionInfo(exception);
2783 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
2784 SvPOK_on(perl_exception);
2785 ST(0)=sv_2mortal(perl_exception);
2786 XSRETURN(1);
2787 }
2788
2789#
2790###############################################################################
2791# #
2792# #
2793# #
2794# B l o b T o I m a g e #
2795# #
2796# #
2797# #
2798###############################################################################
2799#
2800#
2801void
2802BlobToImage(ref,...)
2803 Image::Magick ref=NO_INIT
2804 ALIAS:
2805 BlobToImage = 1
2806 blobtoimage = 2
2807 blobto = 3
2808 PPCODE:
2809 {
2810 AV
2811 *av;
2812
2813 char
2814 **keep,
2815 **list;
2816
2817 ExceptionInfo
2818 *exception;
2819
2820 HV
2821 *hv;
2822
2823 Image
2824 *image;
2825
2826 register char
2827 **p;
2828
2829 register ssize_t
2830 i;
2831
2832 ssize_t
2833 ac,
2834 n,
2835 number_images;
2836
2837 STRLEN
2838 *length;
2839
2840 struct PackageInfo
2841 *info;
2842
2843 SV
2844 *perl_exception,
2845 *reference,
2846 *rv,
2847 *sv;
2848
2849 PERL_UNUSED_VAR(ref);
2850 PERL_UNUSED_VAR(ix);
2851 exception=AcquireExceptionInfo();
2852 perl_exception=newSVpv("",0);
2853 sv=NULL;
2854 number_images=0;
2855 ac=(items < 2) ? 1 : items-1;
2856 length=(STRLEN *) NULL;
2857 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
2858 if (list == (char **) NULL)
2859 {
2860 ThrowPerlException(exception,ResourceLimitError,
2861 "MemoryAllocationFailed",PackageName);
2862 goto PerlException;
2863 }
2864 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
2865 if (length == (STRLEN *) NULL)
2866 {
2867 ThrowPerlException(exception,ResourceLimitError,
2868 "MemoryAllocationFailed",PackageName);
2869 goto PerlException;
2870 }
2871 if (sv_isobject(ST(0)) == 0)
2872 {
2873 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2874 PackageName);
2875 goto PerlException;
2876 }
2877 reference=SvRV(ST(0));
2878 hv=SvSTASH(reference);
2879 if (SvTYPE(reference) != SVt_PVAV)
2880 {
2881 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
2882 PackageName);
2883 goto PerlException;
2884 }
2885 av=(AV *) reference;
2886 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
2887 exception);
2888 n=1;
2889 if (items <= 1)
2890 {
2891 ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
2892 goto PerlException;
2893 }
2894 for (n=0, i=0; i < ac; i++)
2895 {
2896 list[n]=(char *) (SvPV(ST(i+1),length[n]));
2897 if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
2898 {
2899 list[n]=(char *) (SvPV(ST(i+2),length[n]));
2900 continue;
2901 }
2902 n++;
2903 }
2904 list[n]=(char *) NULL;
2905 keep=list;
2906 for (i=number_images=0; i < n; i++)
2907 {
2908 image=BlobToImage(info->image_info,list[i],length[i],exception);
2909 if (image == (Image *) NULL)
2910 break;
2911 for ( ; image; image=image->next)
2912 {
2913 AddImageToRegistry(sv,image);
2914 rv=newRV(sv);
2915 av_push(av,sv_bless(rv,hv));
2916 SvREFCNT_dec(sv);
2917 number_images++;
2918 }
2919 }
2920 /*
2921 Free resources.
2922 */
2923 for (i=0; i < n; i++)
2924 if (list[i] != (char *) NULL)
2925 for (p=keep; list[i] != *p++; )
2926 if (*p == (char *) NULL)
2927 {
2928 list[i]=(char *) RelinquishMagickMemory(list[i]);
2929 break;
2930 }
2931
2932 PerlException:
2933 if (list)
2934 list=(char **) RelinquishMagickMemory(list);
2935 if (length)
2936 length=(STRLEN *) RelinquishMagickMemory(length);
2937 InheritPerlException(exception,perl_exception);
2938 exception=DestroyExceptionInfo(exception);
2939 sv_setiv(perl_exception,(IV) number_images);
2940 SvPOK_on(perl_exception);
2941 ST(0)=sv_2mortal(perl_exception);
2942 XSRETURN(1);
2943 }
2944
2945#
2946###############################################################################
2947# #
2948# #
2949# #
2950# C h a n n e l F x #
2951# #
2952# #
2953# #
2954###############################################################################
2955#
2956#
2957void
2958ChannelFx(ref,...)
2959 Image::Magick ref=NO_INIT
2960 ALIAS:
2961 ChannelFxImage = 1
2962 channelfx = 2
2963 channelfximage = 3
2964 PPCODE:
2965 {
2966 AV
2967 *av;
2968
2969 char
2970 *attribute,
cristy151b66d2015-04-15 10:50:31 +00002971 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00002972
2973 ChannelType
2974 channel,
2975 channel_mask;
2976
2977 ExceptionInfo
2978 *exception;
2979
2980 HV
2981 *hv;
2982
2983 Image
2984 *image;
2985
2986 register ssize_t
2987 i;
2988
2989 struct PackageInfo
2990 *info;
2991
2992 SV
2993 *av_reference,
2994 *perl_exception,
2995 *reference,
2996 *rv,
2997 *sv;
2998
2999 PERL_UNUSED_VAR(ref);
3000 PERL_UNUSED_VAR(ix);
3001 exception=AcquireExceptionInfo();
3002 perl_exception=newSVpv("",0);
3003 sv=NULL;
3004 attribute=NULL;
3005 av=NULL;
3006 if (sv_isobject(ST(0)) == 0)
3007 {
3008 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3009 PackageName);
3010 goto PerlException;
3011 }
3012 reference=SvRV(ST(0));
3013 hv=SvSTASH(reference);
3014 av=newAV();
3015 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3016 SvREFCNT_dec(av);
3017 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3018 if (image == (Image *) NULL)
3019 {
3020 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3021 PackageName);
3022 goto PerlException;
3023 }
3024 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3025 /*
3026 Get options.
3027 */
3028 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00003029 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003030 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00003031 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003032 else
3033 for (i=2; i < items; i+=2)
3034 {
3035 attribute=(char *) SvPV(ST(i-1),na);
3036 switch (*attribute)
3037 {
3038 case 'C':
3039 case 'c':
3040 {
3041 if (LocaleCompare(attribute,"channel") == 0)
3042 {
3043 ssize_t
3044 option;
3045
3046 option=ParseChannelOption(SvPV(ST(i),na));
3047 if (option < 0)
3048 {
3049 ThrowPerlException(exception,OptionError,
3050 "UnrecognizedType",SvPV(ST(i),na));
3051 return;
3052 }
3053 channel=(ChannelType) option;
3054 break;
3055 }
3056 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3057 attribute);
3058 break;
3059 }
3060 case 'E':
3061 case 'e':
3062 {
3063 if (LocaleCompare(attribute,"expression") == 0)
3064 {
3065 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00003066 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00003067 break;
3068 }
3069 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3070 attribute);
3071 break;
3072 }
3073 default:
3074 {
3075 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3076 attribute);
3077 break;
3078 }
3079 }
3080 }
3081 channel_mask=SetImageChannelMask(image,channel);
3082 image=ChannelFxImage(image,expression,exception);
3083 if (image != (Image *) NULL)
3084 (void) SetImageChannelMask(image,channel_mask);
3085 if (image == (Image *) NULL)
3086 goto PerlException;
3087 for ( ; image; image=image->next)
3088 {
3089 AddImageToRegistry(sv,image);
3090 rv=newRV(sv);
3091 av_push(av,sv_bless(rv,hv));
3092 SvREFCNT_dec(sv);
3093 }
3094 exception=DestroyExceptionInfo(exception);
3095 ST(0)=av_reference;
3096 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3097 XSRETURN(1);
3098
3099 PerlException:
3100 InheritPerlException(exception,perl_exception);
3101 exception=DestroyExceptionInfo(exception);
3102 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3103 SvPOK_on(perl_exception);
3104 ST(0)=sv_2mortal(perl_exception);
3105 XSRETURN(1);
3106 }
3107
3108#
3109###############################################################################
3110# #
3111# #
3112# #
3113# C l o n e #
3114# #
3115# #
3116# #
3117###############################################################################
3118#
3119#
3120void
3121Clone(ref)
3122 Image::Magick ref=NO_INIT
3123 ALIAS:
3124 CopyImage = 1
3125 copy = 2
3126 copyimage = 3
3127 CloneImage = 4
3128 clone = 5
3129 cloneimage = 6
3130 Clone = 7
3131 PPCODE:
3132 {
3133 AV
3134 *av;
3135
3136 ExceptionInfo
3137 *exception;
3138
3139 HV
3140 *hv;
3141
3142 Image
3143 *clone,
3144 *image;
3145
3146 struct PackageInfo
3147 *info;
3148
3149 SV
3150 *perl_exception,
3151 *reference,
3152 *rv,
3153 *sv;
3154
3155 PERL_UNUSED_VAR(ref);
3156 PERL_UNUSED_VAR(ix);
3157 exception=AcquireExceptionInfo();
3158 perl_exception=newSVpv("",0);
3159 sv=NULL;
3160 if (sv_isobject(ST(0)) == 0)
3161 {
3162 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3163 PackageName);
3164 goto PerlException;
3165 }
3166 reference=SvRV(ST(0));
3167 hv=SvSTASH(reference);
3168 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3169 if (image == (Image *) NULL)
3170 {
3171 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3172 PackageName);
3173 goto PerlException;
3174 }
3175 /*
3176 Create blessed Perl array for the returned image.
3177 */
3178 av=newAV();
3179 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3180 SvREFCNT_dec(av);
3181 for ( ; image; image=image->next)
3182 {
3183 clone=CloneImage(image,0,0,MagickTrue,exception);
3184 if (clone == (Image *) NULL)
3185 break;
3186 AddImageToRegistry(sv,clone);
3187 rv=newRV(sv);
3188 av_push(av,sv_bless(rv,hv));
3189 SvREFCNT_dec(sv);
3190 }
3191 exception=DestroyExceptionInfo(exception);
3192 SvREFCNT_dec(perl_exception);
3193 XSRETURN(1);
3194
3195 PerlException:
3196 InheritPerlException(exception,perl_exception);
3197 exception=DestroyExceptionInfo(exception);
3198 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3199 SvPOK_on(perl_exception);
3200 ST(0)=sv_2mortal(perl_exception);
3201 XSRETURN(1);
3202 }
3203
3204#
3205###############################################################################
3206# #
3207# #
3208# #
3209# C L O N E #
3210# #
3211# #
3212# #
3213###############################################################################
3214#
3215#
3216void
3217CLONE(ref,...)
3218 SV *ref;
3219 CODE:
3220 {
3221 PERL_UNUSED_VAR(ref);
3222 if (magick_registry != (SplayTreeInfo *) NULL)
3223 {
3224 register Image
3225 *p;
3226
3227 ResetSplayTreeIterator(magick_registry);
3228 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3229 while (p != (Image *) NULL)
3230 {
3231 ReferenceImage(p);
3232 p=(Image *) GetNextKeyInSplayTree(magick_registry);
3233 }
3234 }
3235 }
3236
3237#
3238###############################################################################
3239# #
3240# #
3241# #
3242# C o a l e s c e #
3243# #
3244# #
3245# #
3246###############################################################################
3247#
3248#
3249void
3250Coalesce(ref)
3251 Image::Magick ref=NO_INIT
3252 ALIAS:
3253 CoalesceImage = 1
3254 coalesce = 2
3255 coalesceimage = 3
3256 PPCODE:
3257 {
3258 AV
3259 *av;
3260
3261 ExceptionInfo
3262 *exception;
3263
3264 HV
3265 *hv;
3266
3267 Image
3268 *image;
3269
3270 struct PackageInfo
3271 *info;
3272
3273 SV
3274 *av_reference,
3275 *perl_exception,
3276 *reference,
3277 *rv,
3278 *sv;
3279
3280 PERL_UNUSED_VAR(ref);
3281 PERL_UNUSED_VAR(ix);
3282 exception=AcquireExceptionInfo();
3283 perl_exception=newSVpv("",0);
3284 sv=NULL;
3285 if (sv_isobject(ST(0)) == 0)
3286 {
3287 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3288 PackageName);
3289 goto PerlException;
3290 }
3291 reference=SvRV(ST(0));
3292 hv=SvSTASH(reference);
3293 av=newAV();
3294 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3295 SvREFCNT_dec(av);
3296 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3297 if (image == (Image *) NULL)
3298 {
3299 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3300 PackageName);
3301 goto PerlException;
3302 }
3303 image=CoalesceImages(image,exception);
3304 if (image == (Image *) NULL)
3305 goto PerlException;
3306 for ( ; image; image=image->next)
3307 {
3308 AddImageToRegistry(sv,image);
3309 rv=newRV(sv);
3310 av_push(av,sv_bless(rv,hv));
3311 SvREFCNT_dec(sv);
3312 }
3313 exception=DestroyExceptionInfo(exception);
3314 ST(0)=av_reference;
3315 SvREFCNT_dec(perl_exception);
3316 XSRETURN(1);
3317
3318 PerlException:
3319 InheritPerlException(exception,perl_exception);
3320 exception=DestroyExceptionInfo(exception);
3321 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3322 SvPOK_on(perl_exception);
3323 ST(0)=sv_2mortal(perl_exception);
3324 XSRETURN(1);
3325 }
3326
3327#
3328###############################################################################
3329# #
3330# #
3331# #
3332# C o m p a r e #
3333# #
3334# #
3335# #
3336###############################################################################
3337#
3338#
3339void
3340Compare(ref,...)
3341 Image::Magick ref=NO_INIT
3342 ALIAS:
3343 CompareImages = 1
3344 compare = 2
3345 compareimage = 3
3346 PPCODE:
3347 {
3348 AV
3349 *av;
3350
3351 char
3352 *attribute;
3353
3354 double
3355 distortion;
3356
3357 ExceptionInfo
3358 *exception;
3359
3360 HV
3361 *hv;
3362
3363 Image
3364 *difference_image,
3365 *image,
3366 *reconstruct_image;
3367
3368 MetricType
3369 metric;
3370
3371 register ssize_t
3372 i;
3373
3374 ssize_t
3375 option;
3376
3377 struct PackageInfo
3378 *info;
3379
3380 SV
3381 *av_reference,
3382 *perl_exception,
3383 *reference,
3384 *rv,
3385 *sv;
3386
3387 PERL_UNUSED_VAR(ref);
3388 PERL_UNUSED_VAR(ix);
3389 exception=AcquireExceptionInfo();
3390 perl_exception=newSVpv("",0);
3391 sv=NULL;
3392 av=NULL;
3393 attribute=NULL;
3394 if (sv_isobject(ST(0)) == 0)
3395 {
3396 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3397 PackageName);
3398 goto PerlException;
3399 }
3400 reference=SvRV(ST(0));
3401 hv=SvSTASH(reference);
3402 av=newAV();
3403 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3404 SvREFCNT_dec(av);
3405 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3406 if (image == (Image *) NULL)
3407 {
3408 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3409 PackageName);
3410 goto PerlException;
3411 }
3412 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
3413 /*
3414 Get attribute.
3415 */
3416 reconstruct_image=image;
3417 metric=RootMeanSquaredErrorMetric;
3418 for (i=2; i < items; i+=2)
3419 {
3420 attribute=(char *) SvPV(ST(i-1),na);
3421 switch (*attribute)
3422 {
3423 case 'C':
3424 case 'c':
3425 {
3426 if (LocaleCompare(attribute,"channel") == 0)
3427 {
3428 ssize_t
3429 option;
3430
3431 option=ParseChannelOption(SvPV(ST(i),na));
3432 if (option < 0)
3433 {
3434 ThrowPerlException(exception,OptionError,
3435 "UnrecognizedType",SvPV(ST(i),na));
3436 return;
3437 }
cristybcd59342015-06-07 14:07:19 +00003438 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00003439 break;
3440 }
3441 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3442 attribute);
3443 break;
3444 }
3445 case 'F':
3446 case 'f':
3447 {
3448 if (LocaleCompare(attribute,"fuzz") == 0)
3449 {
3450 image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
3451 break;
3452 }
3453 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3454 attribute);
3455 break;
3456 }
3457 case 'I':
3458 case 'i':
3459 {
3460 if (LocaleCompare(attribute,"image") == 0)
3461 {
3462 reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
3463 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
3464 break;
3465 }
3466 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3467 attribute);
3468 break;
3469 }
3470 case 'M':
3471 case 'm':
3472 {
3473 if (LocaleCompare(attribute,"metric") == 0)
3474 {
3475 option=ParseCommandOption(MagickMetricOptions,MagickFalse,
3476 SvPV(ST(i),na));
3477 if (option < 0)
3478 {
3479 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3480 SvPV(ST(i),na));
3481 break;
3482 }
3483 metric=(MetricType) option;
3484 break;
3485 }
3486 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3487 attribute);
3488 break;
3489 }
3490 default:
3491 {
3492 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3493 attribute);
3494 break;
3495 }
3496 }
3497 }
3498 difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
3499 exception);
3500 if (difference_image != (Image *) NULL)
3501 {
3502 difference_image->error.mean_error_per_pixel=distortion;
3503 AddImageToRegistry(sv,difference_image);
3504 rv=newRV(sv);
3505 av_push(av,sv_bless(rv,hv));
3506 SvREFCNT_dec(sv);
3507 }
3508 exception=DestroyExceptionInfo(exception);
3509 ST(0)=av_reference;
3510 SvREFCNT_dec(perl_exception); /* can't return warning messages */
3511 XSRETURN(1);
3512
3513 PerlException:
3514 InheritPerlException(exception,perl_exception);
3515 exception=DestroyExceptionInfo(exception);
3516 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3517 SvPOK_on(perl_exception);
3518 ST(0)=sv_2mortal(perl_exception);
3519 XSRETURN(1);
3520 }
3521
3522#
3523###############################################################################
3524# #
3525# #
3526# #
cristy15655332013-10-06 00:27:33 +00003527# C o m p l e x I m a g e s #
3528# #
3529# #
3530# #
3531###############################################################################
3532#
3533#
3534void
3535ComplexImages(ref)
3536 Image::Magick ref=NO_INIT
3537 ALIAS:
3538 ComplexImages = 1
3539 compleximages = 2
3540 PPCODE:
3541 {
3542 AV
3543 *av;
3544
3545 char
3546 *attribute,
3547 *p;
3548
cristyfa21e9e2013-10-07 10:37:38 +00003549 ComplexOperator
3550 op;
3551
cristy15655332013-10-06 00:27:33 +00003552 ExceptionInfo
3553 *exception;
3554
3555 HV
3556 *hv;
3557
3558 Image
3559 *image;
3560
cristy15655332013-10-06 00:27:33 +00003561 register ssize_t
3562 i;
3563
3564 struct PackageInfo
3565 *info;
3566
3567 SV
3568 *perl_exception,
3569 *reference,
3570 *rv,
3571 *sv;
3572
3573 PERL_UNUSED_VAR(ref);
3574 PERL_UNUSED_VAR(ix);
3575 exception=AcquireExceptionInfo();
3576 perl_exception=newSVpv("",0);
3577 sv=NULL;
3578 if (sv_isobject(ST(0)) == 0)
3579 {
3580 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3581 PackageName);
3582 goto PerlException;
3583 }
3584 reference=SvRV(ST(0));
3585 hv=SvSTASH(reference);
3586 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3587 if (image == (Image *) NULL)
3588 {
3589 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3590 PackageName);
3591 goto PerlException;
3592 }
cristyfd168722013-10-07 15:59:31 +00003593 op=UndefinedComplexOperator;
cristy15655332013-10-06 00:27:33 +00003594 if (items == 2)
3595 {
3596 ssize_t
3597 in;
3598
3599 in=ParseCommandOption(MagickComplexOptions,MagickFalse,(char *)
3600 SvPV(ST(1),na));
3601 if (in < 0)
3602 {
3603 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3604 SvPV(ST(1),na));
3605 return;
3606 }
cristyfa21e9e2013-10-07 10:37:38 +00003607 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003608 }
3609 else
3610 for (i=2; i < items; i+=2)
3611 {
3612 attribute=(char *) SvPV(ST(i-1),na);
3613 switch (*attribute)
3614 {
3615 case 'O':
3616 case 'o':
3617 {
3618 if (LocaleCompare(attribute,"operator") == 0)
3619 {
3620 ssize_t
3621 in;
3622
3623 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
3624 MagickComplexOptions,MagickFalse,SvPV(ST(i),na));
3625 if (in < 0)
3626 {
3627 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3628 SvPV(ST(i),na));
3629 return;
3630 }
cristyfa21e9e2013-10-07 10:37:38 +00003631 op=(ComplexOperator) in;
cristy15655332013-10-06 00:27:33 +00003632 break;
3633 }
3634 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3635 attribute);
3636 break;
3637 }
3638 default:
3639 {
3640 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3641 attribute);
3642 break;
3643 }
3644 }
3645 }
3646 image=ComplexImages(image,op,exception);
3647 if (image == (Image *) NULL)
3648 goto PerlException;
3649 /*
3650 Create blessed Perl array for the returned image.
3651 */
3652 av=newAV();
3653 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3654 SvREFCNT_dec(av);
3655 AddImageToRegistry(sv,image);
3656 rv=newRV(sv);
3657 av_push(av,sv_bless(rv,hv));
3658 SvREFCNT_dec(sv);
3659 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00003660 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
3661 "complex-%.*s",(int) (MagickPathExtent-9),
cristy15655332013-10-06 00:27:33 +00003662 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
3663 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00003664 MagickPathExtent);
cristy15655332013-10-06 00:27:33 +00003665 SetImageInfo(info->image_info,0,exception);
3666 exception=DestroyExceptionInfo(exception);
3667 SvREFCNT_dec(perl_exception);
3668 XSRETURN(1);
3669
3670 PerlException:
3671 InheritPerlException(exception,perl_exception);
3672 exception=DestroyExceptionInfo(exception);
3673 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3674 SvPOK_on(perl_exception);
3675 ST(0)=sv_2mortal(perl_exception);
3676 XSRETURN(1);
3677 }
3678
3679#
3680###############################################################################
3681# #
3682# #
3683# #
cristy4a3ce0a2013-08-03 20:06:59 +00003684# C o m p a r e L a y e r s #
3685# #
3686# #
3687# #
3688###############################################################################
3689#
3690#
3691void
3692CompareLayers(ref)
3693 Image::Magick ref=NO_INIT
3694 ALIAS:
3695 CompareImagesLayers = 1
3696 comparelayers = 2
3697 compareimagelayers = 3
3698 PPCODE:
3699 {
3700 AV
3701 *av;
3702
3703 char
3704 *attribute;
3705
3706 ExceptionInfo
3707 *exception;
3708
3709 HV
3710 *hv;
3711
3712 Image
3713 *image;
3714
3715 LayerMethod
3716 method;
3717
3718 register ssize_t
3719 i;
3720
3721 ssize_t
3722 option;
3723
3724 struct PackageInfo
3725 *info;
3726
3727 SV
3728 *av_reference,
3729 *perl_exception,
3730 *reference,
3731 *rv,
3732 *sv;
3733
3734 PERL_UNUSED_VAR(ref);
3735 PERL_UNUSED_VAR(ix);
3736 exception=AcquireExceptionInfo();
3737 perl_exception=newSVpv("",0);
3738 sv=NULL;
3739 if (sv_isobject(ST(0)) == 0)
3740 {
3741 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3742 PackageName);
3743 goto PerlException;
3744 }
3745 reference=SvRV(ST(0));
3746 hv=SvSTASH(reference);
3747 av=newAV();
3748 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
3749 SvREFCNT_dec(av);
3750 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3751 if (image == (Image *) NULL)
3752 {
3753 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3754 PackageName);
3755 goto PerlException;
3756 }
3757 method=CompareAnyLayer;
3758 for (i=2; i < items; i+=2)
3759 {
3760 attribute=(char *) SvPV(ST(i-1),na);
3761 switch (*attribute)
3762 {
3763 case 'M':
3764 case 'm':
3765 {
3766 if (LocaleCompare(attribute,"method") == 0)
3767 {
3768 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
3769 SvPV(ST(i),na));
3770 if (option < 0)
3771 {
3772 ThrowPerlException(exception,OptionError,"UnrecognizedType",
3773 SvPV(ST(i),na));
3774 break;
3775 }
3776 method=(LayerMethod) option;
3777 break;
3778 }
3779 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3780 attribute);
3781 break;
3782 }
3783 default:
3784 {
3785 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
3786 attribute);
3787 break;
3788 }
3789 }
3790 }
3791 image=CompareImagesLayers(image,method,exception);
3792 if (image == (Image *) NULL)
3793 goto PerlException;
3794 for ( ; image; image=image->next)
3795 {
3796 AddImageToRegistry(sv,image);
3797 rv=newRV(sv);
3798 av_push(av,sv_bless(rv,hv));
3799 SvREFCNT_dec(sv);
3800 }
3801 exception=DestroyExceptionInfo(exception);
3802 ST(0)=av_reference;
3803 SvREFCNT_dec(perl_exception);
3804 XSRETURN(1);
3805
3806 PerlException:
3807 InheritPerlException(exception,perl_exception);
3808 exception=DestroyExceptionInfo(exception);
3809 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3810 SvPOK_on(perl_exception);
3811 ST(0)=sv_2mortal(perl_exception);
3812 XSRETURN(1);
3813 }
3814
3815#
3816###############################################################################
3817# #
3818# #
3819# #
3820# D e s t r o y #
3821# #
3822# #
3823# #
3824###############################################################################
3825#
3826#
3827void
3828DESTROY(ref)
3829 Image::Magick ref=NO_INIT
3830 PPCODE:
3831 {
3832 SV
3833 *reference;
3834
3835 PERL_UNUSED_VAR(ref);
3836 if (sv_isobject(ST(0)) == 0)
3837 croak("ReferenceIsNotMyType");
3838 reference=SvRV(ST(0));
3839 switch (SvTYPE(reference))
3840 {
3841 case SVt_PVAV:
3842 {
3843 char
cristy151b66d2015-04-15 10:50:31 +00003844 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00003845
3846 const SV
3847 *key;
3848
3849 HV
3850 *hv;
3851
3852 GV
3853 **gvp;
3854
3855 struct PackageInfo
3856 *info;
3857
3858 SV
3859 *sv;
3860
3861 /*
3862 Array (AV *) reference
3863 */
cristy151b66d2015-04-15 10:50:31 +00003864 (void) FormatLocaleString(message,MagickPathExtent,"package%s%p",
cristy4a3ce0a2013-08-03 20:06:59 +00003865 XS_VERSION,reference);
3866 hv=gv_stashpv(PackageName, FALSE);
3867 if (!hv)
3868 break;
3869 gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
3870 if (!gvp)
3871 break;
3872 sv=GvSV(*gvp);
3873 if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
3874 {
3875 info=INT2PTR(struct PackageInfo *,SvIV(sv));
3876 DestroyPackageInfo(info);
3877 }
3878 key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
3879 (void) key;
3880 break;
3881 }
3882 case SVt_PVMG:
3883 {
3884 Image
3885 *image;
3886
3887 /*
3888 Blessed scalar = (Image *) SvIV(reference)
3889 */
3890 image=INT2PTR(Image *,SvIV(reference));
3891 if (image != (Image *) NULL)
3892 DeleteImageFromRegistry(reference,image);
3893 break;
3894 }
3895 default:
3896 break;
3897 }
3898 }
3899
3900#
3901###############################################################################
3902# #
3903# #
3904# #
3905# D i s p l a y #
3906# #
3907# #
3908# #
3909###############################################################################
3910#
3911#
3912void
3913Display(ref,...)
3914 Image::Magick ref=NO_INIT
3915 ALIAS:
3916 DisplayImage = 1
3917 display = 2
3918 displayimage = 3
3919 PPCODE:
3920 {
3921 ExceptionInfo
3922 *exception;
3923
3924 Image
3925 *image;
3926
3927 register ssize_t
3928 i;
3929
3930 struct PackageInfo
3931 *info,
3932 *package_info;
3933
3934 SV
3935 *perl_exception,
3936 *reference;
3937
3938 PERL_UNUSED_VAR(ref);
3939 PERL_UNUSED_VAR(ix);
3940 exception=AcquireExceptionInfo();
3941 perl_exception=newSVpv("",0);
3942 package_info=(struct PackageInfo *) NULL;
3943 if (sv_isobject(ST(0)) == 0)
3944 {
3945 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
3946 PackageName);
3947 goto PerlException;
3948 }
3949 reference=SvRV(ST(0));
3950 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
3951 if (image == (Image *) NULL)
3952 {
3953 ThrowPerlException(exception,OptionError,"NoImagesDefined",
3954 PackageName);
3955 goto PerlException;
3956 }
3957 package_info=ClonePackageInfo(info,exception);
3958 if (items == 2)
3959 SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
3960 else
3961 if (items > 2)
3962 for (i=2; i < items; i+=2)
3963 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
3964 exception);
3965 (void) DisplayImages(package_info->image_info,image,exception);
3966 (void) CatchImageException(image);
3967
3968 PerlException:
3969 if (package_info != (struct PackageInfo *) NULL)
3970 DestroyPackageInfo(package_info);
3971 InheritPerlException(exception,perl_exception);
3972 exception=DestroyExceptionInfo(exception);
3973 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
3974 SvPOK_on(perl_exception);
3975 ST(0)=sv_2mortal(perl_exception);
3976 XSRETURN(1);
3977 }
3978
3979#
3980###############################################################################
3981# #
3982# #
3983# #
3984# E v a l u a t e I m a g e s #
3985# #
3986# #
3987# #
3988###############################################################################
3989#
3990#
3991void
3992EvaluateImages(ref)
3993 Image::Magick ref=NO_INIT
3994 ALIAS:
3995 EvaluateImages = 1
3996 evaluateimages = 2
3997 PPCODE:
3998 {
3999 AV
4000 *av;
4001
4002 char
4003 *attribute,
4004 *p;
4005
4006 ExceptionInfo
4007 *exception;
4008
4009 HV
4010 *hv;
4011
4012 Image
4013 *image;
4014
4015 MagickEvaluateOperator
4016 op;
4017
4018 register ssize_t
4019 i;
4020
4021 struct PackageInfo
4022 *info;
4023
4024 SV
4025 *perl_exception,
4026 *reference,
4027 *rv,
4028 *sv;
4029
4030 PERL_UNUSED_VAR(ref);
4031 PERL_UNUSED_VAR(ix);
4032 exception=AcquireExceptionInfo();
4033 perl_exception=newSVpv("",0);
4034 sv=NULL;
4035 if (sv_isobject(ST(0)) == 0)
4036 {
4037 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4038 PackageName);
4039 goto PerlException;
4040 }
4041 reference=SvRV(ST(0));
4042 hv=SvSTASH(reference);
4043 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4044 if (image == (Image *) NULL)
4045 {
4046 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4047 PackageName);
4048 goto PerlException;
4049 }
4050 op=MeanEvaluateOperator;
4051 if (items == 2)
4052 {
4053 ssize_t
4054 in;
4055
4056 in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
4057 SvPV(ST(1),na));
4058 if (in < 0)
4059 {
4060 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4061 SvPV(ST(1),na));
4062 return;
4063 }
4064 op=(MagickEvaluateOperator) in;
4065 }
4066 else
4067 for (i=2; i < items; i+=2)
4068 {
4069 attribute=(char *) SvPV(ST(i-1),na);
4070 switch (*attribute)
4071 {
4072 case 'O':
4073 case 'o':
4074 {
4075 if (LocaleCompare(attribute,"operator") == 0)
4076 {
4077 ssize_t
4078 in;
4079
4080 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
4081 MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
4082 if (in < 0)
4083 {
4084 ThrowPerlException(exception,OptionError,"UnrecognizedType",
4085 SvPV(ST(i),na));
4086 return;
4087 }
4088 op=(MagickEvaluateOperator) in;
4089 break;
4090 }
4091 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4092 attribute);
4093 break;
4094 }
4095 default:
4096 {
4097 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4098 attribute);
4099 break;
4100 }
4101 }
4102 }
4103 image=EvaluateImages(image,op,exception);
4104 if (image == (Image *) NULL)
4105 goto PerlException;
4106 /*
4107 Create blessed Perl array for the returned image.
4108 */
4109 av=newAV();
4110 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4111 SvREFCNT_dec(av);
4112 AddImageToRegistry(sv,image);
4113 rv=newRV(sv);
4114 av_push(av,sv_bless(rv,hv));
4115 SvREFCNT_dec(sv);
4116 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004117 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4118 "evaluate-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004119 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4120 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004121 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004122 SetImageInfo(info->image_info,0,exception);
4123 exception=DestroyExceptionInfo(exception);
4124 SvREFCNT_dec(perl_exception);
4125 XSRETURN(1);
4126
4127 PerlException:
4128 InheritPerlException(exception,perl_exception);
4129 exception=DestroyExceptionInfo(exception);
4130 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4131 SvPOK_on(perl_exception);
4132 ST(0)=sv_2mortal(perl_exception);
4133 XSRETURN(1);
4134 }
4135
4136#
4137###############################################################################
4138# #
4139# #
4140# #
4141# F e a t u r e s #
4142# #
4143# #
4144# #
4145###############################################################################
4146#
4147#
4148void
4149Features(ref,...)
4150 Image::Magick ref=NO_INIT
4151 ALIAS:
4152 FeaturesImage = 1
4153 features = 2
4154 featuresimage = 3
4155 PPCODE:
4156 {
4157#define ChannelFeatures(channel,direction) \
4158{ \
Cristyb1710fe2017-02-11 13:51:48 -05004159 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004160 channel_features[channel].angular_second_moment[direction]); \
4161 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004162 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004163 channel_features[channel].contrast[direction]); \
4164 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004165 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004166 channel_features[channel].contrast[direction]); \
4167 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004168 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004169 channel_features[channel].variance_sum_of_squares[direction]); \
4170 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004171 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004172 channel_features[channel].inverse_difference_moment[direction]); \
4173 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004174 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004175 channel_features[channel].sum_average[direction]); \
4176 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004177 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004178 channel_features[channel].sum_variance[direction]); \
4179 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004180 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004181 channel_features[channel].sum_entropy[direction]); \
4182 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004183 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004184 channel_features[channel].entropy[direction]); \
4185 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004186 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004187 channel_features[channel].difference_variance[direction]); \
4188 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004189 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004190 channel_features[channel].difference_entropy[direction]); \
4191 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004192 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004193 channel_features[channel].measure_of_correlation_1[direction]); \
4194 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004195 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004196 channel_features[channel].measure_of_correlation_2[direction]); \
4197 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -05004198 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +00004199 channel_features[channel].maximum_correlation_coefficient[direction]); \
4200 PUSHs(sv_2mortal(newSVpv(message,0))); \
4201}
4202
4203 AV
4204 *av;
4205
4206 char
4207 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004208 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004209
4210 ChannelFeatures
4211 *channel_features;
4212
4213 double
4214 distance;
4215
4216 ExceptionInfo
4217 *exception;
4218
4219 Image
4220 *image;
4221
4222 register ssize_t
4223 i;
4224
4225 ssize_t
4226 count;
4227
4228 struct PackageInfo
4229 *info;
4230
4231 SV
4232 *perl_exception,
4233 *reference;
4234
4235 PERL_UNUSED_VAR(ref);
4236 PERL_UNUSED_VAR(ix);
4237 exception=AcquireExceptionInfo();
4238 perl_exception=newSVpv("",0);
4239 av=NULL;
4240 if (sv_isobject(ST(0)) == 0)
4241 {
4242 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4243 PackageName);
4244 goto PerlException;
4245 }
4246 reference=SvRV(ST(0));
4247 av=newAV();
4248 SvREFCNT_dec(av);
4249 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4250 if (image == (Image *) NULL)
4251 {
4252 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4253 PackageName);
4254 goto PerlException;
4255 }
cristy7dbd9262014-07-02 17:53:42 +00004256 distance=1.0;
cristy4a3ce0a2013-08-03 20:06:59 +00004257 for (i=2; i < items; i+=2)
4258 {
4259 attribute=(char *) SvPV(ST(i-1),na);
4260 switch (*attribute)
4261 {
4262 case 'D':
4263 case 'd':
4264 {
4265 if (LocaleCompare(attribute,"distance") == 0)
4266 {
4267 distance=StringToLong((char *) SvPV(ST(1),na));
4268 break;
4269 }
4270 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4271 attribute);
4272 break;
4273 }
4274 default:
4275 {
4276 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4277 attribute);
4278 break;
4279 }
4280 }
4281 }
4282 count=0;
4283 for ( ; image; image=image->next)
4284 {
Cristy5a854dc2017-02-11 15:43:46 -05004285 register ssize_t
4286 j;
4287
cristy4a3ce0a2013-08-03 20:06:59 +00004288 channel_features=GetImageFeatures(image,distance,exception);
4289 if (channel_features == (ChannelFeatures *) NULL)
4290 continue;
4291 count++;
Cristy5a854dc2017-02-11 15:43:46 -05004292 for (j=0; j < 4; j++)
cristy4a3ce0a2013-08-03 20:06:59 +00004293 {
Cristy5a854dc2017-02-11 15:43:46 -05004294 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
4295 {
4296 PixelChannel channel=GetPixelChannelChannel(image,i);
4297 PixelTrait traits=GetPixelChannelTraits(image,channel);
4298 if (traits == UndefinedPixelTrait)
4299 continue;
4300 EXTEND(sp,14*(i+1)*count);
4301 ChannelFeatures(channel,j);
4302 }
cristy4a3ce0a2013-08-03 20:06:59 +00004303 }
4304 channel_features=(ChannelFeatures *)
4305 RelinquishMagickMemory(channel_features);
4306 }
4307
4308 PerlException:
4309 InheritPerlException(exception,perl_exception);
4310 exception=DestroyExceptionInfo(exception);
4311 SvREFCNT_dec(perl_exception);
4312 }
4313
4314#
4315###############################################################################
4316# #
4317# #
4318# #
4319# F l a t t e n #
4320# #
4321# #
4322# #
4323###############################################################################
4324#
4325#
4326void
4327Flatten(ref)
4328 Image::Magick ref=NO_INIT
4329 ALIAS:
4330 FlattenImage = 1
4331 flatten = 2
4332 flattenimage = 3
4333 PPCODE:
4334 {
4335 AV
4336 *av;
4337
4338 char
4339 *attribute,
4340 *p;
4341
4342 ExceptionInfo
4343 *exception;
4344
4345 HV
4346 *hv;
4347
4348 Image
4349 *image;
4350
4351 PixelInfo
4352 background_color;
4353
4354 register ssize_t
4355 i;
4356
4357 struct PackageInfo
4358 *info;
4359
4360 SV
4361 *perl_exception,
4362 *reference,
4363 *rv,
4364 *sv;
4365
4366 PERL_UNUSED_VAR(ref);
4367 PERL_UNUSED_VAR(ix);
4368 exception=AcquireExceptionInfo();
4369 perl_exception=newSVpv("",0);
4370 sv=NULL;
4371 if (sv_isobject(ST(0)) == 0)
4372 {
4373 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4374 PackageName);
4375 goto PerlException;
4376 }
4377 reference=SvRV(ST(0));
4378 hv=SvSTASH(reference);
4379 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4380 if (image == (Image *) NULL)
4381 {
4382 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4383 PackageName);
4384 goto PerlException;
4385 }
4386 background_color=image->background_color;
4387 if (items == 2)
4388 (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
4389 &background_color,exception);
4390 else
4391 for (i=2; i < items; i+=2)
4392 {
4393 attribute=(char *) SvPV(ST(i-1),na);
4394 switch (*attribute)
4395 {
4396 case 'B':
4397 case 'b':
4398 {
4399 if (LocaleCompare(attribute,"background") == 0)
4400 {
4401 (void) QueryColorCompliance((char *) SvPV(ST(1),na),
4402 AllCompliance,&background_color,exception);
4403 break;
4404 }
4405 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4406 attribute);
4407 break;
4408 }
4409 default:
4410 {
4411 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4412 attribute);
4413 break;
4414 }
4415 }
4416 }
4417 image->background_color=background_color;
4418 image=MergeImageLayers(image,FlattenLayer,exception);
4419 if (image == (Image *) NULL)
4420 goto PerlException;
4421 /*
4422 Create blessed Perl array for the returned image.
4423 */
4424 av=newAV();
4425 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4426 SvREFCNT_dec(av);
4427 AddImageToRegistry(sv,image);
4428 rv=newRV(sv);
4429 av_push(av,sv_bless(rv,hv));
4430 SvREFCNT_dec(sv);
4431 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
cristy151b66d2015-04-15 10:50:31 +00004432 (void) FormatLocaleString(info->image_info->filename,MagickPathExtent,
4433 "flatten-%.*s",(int) (MagickPathExtent-9),
cristy4a3ce0a2013-08-03 20:06:59 +00004434 ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
4435 (void) CopyMagickString(image->filename,info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00004436 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004437 SetImageInfo(info->image_info,0,exception);
4438 exception=DestroyExceptionInfo(exception);
4439 SvREFCNT_dec(perl_exception);
4440 XSRETURN(1);
4441
4442 PerlException:
4443 InheritPerlException(exception,perl_exception);
4444 exception=DestroyExceptionInfo(exception);
4445 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4446 SvPOK_on(perl_exception); /* return messages in string context */
4447 ST(0)=sv_2mortal(perl_exception);
4448 XSRETURN(1);
4449 }
4450
4451#
4452###############################################################################
4453# #
4454# #
4455# #
4456# F x #
4457# #
4458# #
4459# #
4460###############################################################################
4461#
4462#
4463void
4464Fx(ref,...)
4465 Image::Magick ref=NO_INIT
4466 ALIAS:
4467 FxImage = 1
4468 fx = 2
4469 fximage = 3
4470 PPCODE:
4471 {
4472 AV
4473 *av;
4474
4475 char
4476 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004477 expression[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004478
4479 ChannelType
4480 channel,
4481 channel_mask;
4482
4483 ExceptionInfo
4484 *exception;
4485
4486 HV
4487 *hv;
4488
4489 Image
4490 *image;
4491
4492 register ssize_t
4493 i;
4494
4495 struct PackageInfo
4496 *info;
4497
4498 SV
4499 *av_reference,
4500 *perl_exception,
4501 *reference,
4502 *rv,
4503 *sv;
4504
4505 PERL_UNUSED_VAR(ref);
4506 PERL_UNUSED_VAR(ix);
4507 exception=AcquireExceptionInfo();
4508 perl_exception=newSVpv("",0);
4509 sv=NULL;
4510 attribute=NULL;
4511 av=NULL;
4512 if (sv_isobject(ST(0)) == 0)
4513 {
4514 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4515 PackageName);
4516 goto PerlException;
4517 }
4518 reference=SvRV(ST(0));
4519 hv=SvSTASH(reference);
4520 av=newAV();
4521 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
4522 SvREFCNT_dec(av);
4523 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4524 if (image == (Image *) NULL)
4525 {
4526 ThrowPerlException(exception,OptionError,"NoImagesDefined",
4527 PackageName);
4528 goto PerlException;
4529 }
4530 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
4531 /*
4532 Get options.
4533 */
4534 channel=DefaultChannels;
cristy151b66d2015-04-15 10:50:31 +00004535 (void) CopyMagickString(expression,"u",MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004536 if (items == 2)
cristy151b66d2015-04-15 10:50:31 +00004537 (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004538 else
4539 for (i=2; i < items; i+=2)
4540 {
4541 attribute=(char *) SvPV(ST(i-1),na);
4542 switch (*attribute)
4543 {
4544 case 'C':
4545 case 'c':
4546 {
4547 if (LocaleCompare(attribute,"channel") == 0)
4548 {
4549 ssize_t
4550 option;
4551
4552 option=ParseChannelOption(SvPV(ST(i),na));
4553 if (option < 0)
4554 {
4555 ThrowPerlException(exception,OptionError,
4556 "UnrecognizedType",SvPV(ST(i),na));
4557 return;
4558 }
4559 channel=(ChannelType) option;
4560 break;
4561 }
4562 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4563 attribute);
4564 break;
4565 }
4566 case 'E':
4567 case 'e':
4568 {
4569 if (LocaleCompare(attribute,"expression") == 0)
4570 {
4571 (void) CopyMagickString(expression,SvPV(ST(i),na),
cristy151b66d2015-04-15 10:50:31 +00004572 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00004573 break;
4574 }
4575 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4576 attribute);
4577 break;
4578 }
4579 default:
4580 {
4581 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4582 attribute);
4583 break;
4584 }
4585 }
4586 }
4587 channel_mask=SetImageChannelMask(image,channel);
4588 image=FxImage(image,expression,exception);
4589 if (image != (Image *) NULL)
4590 (void) SetImageChannelMask(image,channel_mask);
4591 if (image == (Image *) NULL)
4592 goto PerlException;
4593 for ( ; image; image=image->next)
4594 {
4595 AddImageToRegistry(sv,image);
4596 rv=newRV(sv);
4597 av_push(av,sv_bless(rv,hv));
4598 SvREFCNT_dec(sv);
4599 }
4600 exception=DestroyExceptionInfo(exception);
4601 ST(0)=av_reference;
4602 SvREFCNT_dec(perl_exception); /* can't return warning messages */
4603 XSRETURN(1);
4604
4605 PerlException:
4606 InheritPerlException(exception,perl_exception);
4607 exception=DestroyExceptionInfo(exception);
4608 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
4609 SvPOK_on(perl_exception);
4610 ST(0)=sv_2mortal(perl_exception);
4611 XSRETURN(1);
4612 }
4613
4614#
4615###############################################################################
4616# #
4617# #
4618# #
4619# G e t #
4620# #
4621# #
4622# #
4623###############################################################################
4624#
4625#
4626void
4627Get(ref,...)
4628 Image::Magick ref=NO_INIT
4629 ALIAS:
4630 GetAttributes = 1
4631 GetAttribute = 2
4632 get = 3
4633 getattributes = 4
4634 getattribute = 5
4635 PPCODE:
4636 {
4637 char
4638 *attribute,
cristy151b66d2015-04-15 10:50:31 +00004639 color[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004640
4641 const char
4642 *value;
4643
4644 ExceptionInfo
4645 *exception;
4646
4647 Image
4648 *image;
4649
4650 long
4651 j;
4652
4653 register ssize_t
4654 i;
4655
4656 struct PackageInfo
4657 *info;
4658
4659 SV
4660 *perl_exception,
4661 *reference,
4662 *s;
4663
4664 PERL_UNUSED_VAR(ref);
4665 PERL_UNUSED_VAR(ix);
4666 exception=AcquireExceptionInfo();
4667 perl_exception=newSVpv("",0);
4668 if (sv_isobject(ST(0)) == 0)
4669 {
4670 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
4671 PackageName);
4672 XSRETURN_EMPTY;
4673 }
4674 reference=SvRV(ST(0));
4675 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
4676 if (image == (Image *) NULL && !info)
4677 XSRETURN_EMPTY;
4678 EXTEND(sp,items);
4679 for (i=1; i < items; i++)
4680 {
4681 attribute=(char *) SvPV(ST(i),na);
4682 s=NULL;
4683 switch (*attribute)
4684 {
4685 case 'A':
4686 case 'a':
4687 {
4688 if (LocaleCompare(attribute,"adjoin") == 0)
4689 {
4690 if (info)
4691 s=newSViv((ssize_t) info->image_info->adjoin);
4692 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4693 continue;
4694 }
4695 if (LocaleCompare(attribute,"antialias") == 0)
4696 {
4697 if (info)
4698 s=newSViv((ssize_t) info->image_info->antialias);
4699 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4700 continue;
4701 }
4702 if (LocaleCompare(attribute,"area") == 0)
4703 {
4704 s=newSViv(GetMagickResource(AreaResource));
4705 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4706 continue;
4707 }
4708 if (LocaleCompare(attribute,"attenuate") == 0)
4709 {
4710 const char
4711 *value;
4712
4713 value=GetImageProperty(image,attribute,exception);
4714 if (value != (const char *) NULL)
4715 s=newSVpv(value,0);
4716 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4717 continue;
4718 }
4719 if (LocaleCompare(attribute,"authenticate") == 0)
4720 {
4721 if (info)
4722 {
4723 const char
4724 *option;
4725
4726 option=GetImageOption(info->image_info,attribute);
4727 if (option != (const char *) NULL)
4728 s=newSVpv(option,0);
4729 }
4730 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4731 continue;
4732 }
4733 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4734 attribute);
4735 break;
4736 }
4737 case 'B':
4738 case 'b':
4739 {
4740 if (LocaleCompare(attribute,"background") == 0)
4741 {
4742 if (image == (Image *) NULL)
4743 break;
cristy151b66d2015-04-15 10:50:31 +00004744 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004745 "%.20g,%.20g,%.20g,%.20g",(double) image->background_color.red,
4746 (double) image->background_color.green,
4747 (double) image->background_color.blue,
4748 (double) image->background_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004749 s=newSVpv(color,0);
4750 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4751 continue;
4752 }
4753 if (LocaleCompare(attribute,"base-columns") == 0)
4754 {
4755 if (image != (Image *) NULL)
4756 s=newSViv((ssize_t) image->magick_columns);
4757 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4758 continue;
4759 }
4760 if (LocaleCompare(attribute,"base-filename") == 0)
4761 {
4762 if (image != (Image *) NULL)
4763 s=newSVpv(image->magick_filename,0);
4764 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4765 continue;
4766 }
4767 if (LocaleCompare(attribute,"base-height") == 0)
4768 {
4769 if (image != (Image *) NULL)
4770 s=newSViv((ssize_t) image->magick_rows);
4771 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4772 continue;
4773 }
4774 if (LocaleCompare(attribute,"base-rows") == 0)
4775 {
4776 if (image != (Image *) NULL)
4777 s=newSViv((ssize_t) image->magick_rows);
4778 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4779 continue;
4780 }
4781 if (LocaleCompare(attribute,"base-width") == 0)
4782 {
4783 if (image != (Image *) NULL)
4784 s=newSViv((ssize_t) image->magick_columns);
4785 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4786 continue;
4787 }
4788 if (LocaleCompare(attribute,"blue-primary") == 0)
4789 {
4790 if (image == (Image *) NULL)
4791 break;
Cristyb1710fe2017-02-11 13:51:48 -05004792 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00004793 image->chromaticity.blue_primary.x,
4794 image->chromaticity.blue_primary.y);
4795 s=newSVpv(color,0);
4796 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4797 continue;
4798 }
4799 if (LocaleCompare(attribute,"bordercolor") == 0)
4800 {
4801 if (image == (Image *) NULL)
4802 break;
cristy151b66d2015-04-15 10:50:31 +00004803 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004804 "%.20g,%.20g,%.20g,%.20g",(double) image->border_color.red,
4805 (double) image->border_color.green,
4806 (double) image->border_color.blue,
4807 (double) image->border_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004808 s=newSVpv(color,0);
4809 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4810 continue;
4811 }
4812 if (LocaleCompare(attribute,"bounding-box") == 0)
4813 {
4814 char
cristy151b66d2015-04-15 10:50:31 +00004815 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004816
4817 RectangleInfo
4818 page;
4819
4820 if (image == (Image *) NULL)
4821 break;
4822 page=GetImageBoundingBox(image,exception);
cristy151b66d2015-04-15 10:50:31 +00004823 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00004824 "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
4825 page.height,(double) page.x,(double) page.y);
4826 s=newSVpv(geometry,0);
4827 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4828 continue;
4829 }
4830 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4831 attribute);
4832 break;
4833 }
4834 case 'C':
4835 case 'c':
4836 {
4837 if (LocaleCompare(attribute,"class") == 0)
4838 {
4839 if (image == (Image *) NULL)
4840 break;
4841 s=newSViv(image->storage_class);
4842 (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
4843 image->storage_class));
4844 SvIOK_on(s);
4845 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4846 continue;
4847 }
4848 if (LocaleCompare(attribute,"clip-mask") == 0)
4849 {
4850 if (image != (Image *) NULL)
4851 {
4852 Image
4853 *mask_image;
4854
4855 SV
4856 *sv;
4857
4858 sv=NULL;
4859 if (image->read_mask == MagickFalse)
4860 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004861 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004862 if (mask_image != (Image *) NULL)
4863 {
4864 AddImageToRegistry(sv,mask_image);
4865 s=sv_bless(newRV(sv),SvSTASH(reference));
4866 }
4867 }
4868 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4869 continue;
4870 }
4871 if (LocaleCompare(attribute,"clip-path") == 0)
4872 {
4873 if (image != (Image *) NULL)
4874 {
4875 Image
4876 *mask_image;
4877
4878 SV
4879 *sv;
4880
4881 sv=NULL;
4882 if (image->read_mask != MagickFalse)
4883 ClipImage(image,exception);
Cristyda6b91a2016-01-11 16:05:27 -05004884 mask_image=GetImageMask(image,ReadPixelMask,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004885 if (mask_image != (Image *) NULL)
4886 {
4887 AddImageToRegistry(sv,mask_image);
4888 s=sv_bless(newRV(sv),SvSTASH(reference));
4889 }
4890 }
4891 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4892 continue;
4893 }
4894 if (LocaleCompare(attribute,"compression") == 0)
4895 {
4896 j=info ? info->image_info->compression : image ?
4897 image->compression : UndefinedCompression;
4898 if (info)
4899 if (info->image_info->compression == UndefinedCompression)
4900 j=image->compression;
4901 s=newSViv(j);
4902 (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
4903 j));
4904 SvIOK_on(s);
4905 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4906 continue;
4907 }
4908 if (LocaleCompare(attribute,"colorspace") == 0)
4909 {
4910 j=image ? image->colorspace : RGBColorspace;
4911 s=newSViv(j);
4912 (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
4913 j));
4914 SvIOK_on(s);
4915 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4916 continue;
4917 }
4918 if (LocaleCompare(attribute,"colors") == 0)
4919 {
4920 if (image != (Image *) NULL)
4921 s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
4922 exception));
4923 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4924 continue;
4925 }
4926 if (LocaleNCompare(attribute,"colormap",8) == 0)
4927 {
4928 int
4929 items;
4930
4931 if (image == (Image *) NULL || !image->colormap)
4932 break;
4933 j=0;
4934 items=sscanf(attribute,"%*[^[][%ld",&j);
4935 (void) items;
4936 if (j > (ssize_t) image->colors)
4937 j%=image->colors;
cristy151b66d2015-04-15 10:50:31 +00004938 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00004939 "%.20g,%.20g,%.20g,%.20g",(double) image->colormap[j].red,
4940 (double) image->colormap[j].green,
4941 (double) image->colormap[j].blue,
4942 (double) image->colormap[j].alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00004943 s=newSVpv(color,0);
4944 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4945 continue;
4946 }
4947 if (LocaleCompare(attribute,"columns") == 0)
4948 {
4949 if (image != (Image *) NULL)
4950 s=newSViv((ssize_t) image->columns);
4951 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4952 continue;
4953 }
4954 if (LocaleCompare(attribute,"comment") == 0)
4955 {
4956 const char
4957 *value;
4958
Cristy935a4052017-03-31 17:45:37 -04004959 value=GetImageProperty(image,attribute,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00004960 if (value != (const char *) NULL)
4961 s=newSVpv(value,0);
4962 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4963 continue;
4964 }
4965 if (LocaleCompare(attribute,"copyright") == 0)
4966 {
4967 s=newSVpv(GetMagickCopyright(),0);
4968 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4969 continue;
4970 }
4971 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
4972 attribute);
4973 break;
4974 }
4975 case 'D':
4976 case 'd':
4977 {
4978 if (LocaleCompare(attribute,"density") == 0)
4979 {
4980 char
cristy151b66d2015-04-15 10:50:31 +00004981 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00004982
4983 if (image == (Image *) NULL)
4984 break;
Cristyb1710fe2017-02-11 13:51:48 -05004985 (void) FormatLocaleString(geometry,MagickPathExtent,"%.20gx%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00004986 image->resolution.x,image->resolution.y);
4987 s=newSVpv(geometry,0);
4988 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4989 continue;
4990 }
4991 if (LocaleCompare(attribute,"delay") == 0)
4992 {
4993 if (image != (Image *) NULL)
4994 s=newSViv((ssize_t) image->delay);
4995 PUSHs(s ? sv_2mortal(s) : &sv_undef);
4996 continue;
4997 }
4998 if (LocaleCompare(attribute,"depth") == 0)
4999 {
5000 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5001 if (image != (Image *) NULL)
5002 s=newSViv((ssize_t) GetImageDepth(image,exception));
5003 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5004 continue;
5005 }
5006 if (LocaleCompare(attribute,"directory") == 0)
5007 {
5008 if (image && image->directory)
5009 s=newSVpv(image->directory,0);
5010 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5011 continue;
5012 }
5013 if (LocaleCompare(attribute,"dispose") == 0)
5014 {
5015 if (image == (Image *) NULL)
5016 break;
5017
5018 s=newSViv(image->dispose);
5019 (void) sv_setpv(s,
5020 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
5021 SvIOK_on(s);
5022 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5023 continue;
5024 }
5025 if (LocaleCompare(attribute,"disk") == 0)
5026 {
5027 s=newSViv(GetMagickResource(DiskResource));
5028 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5029 continue;
5030 }
5031 if (LocaleCompare(attribute,"dither") == 0)
5032 {
5033 if (info)
5034 s=newSViv((ssize_t) info->image_info->dither);
5035 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5036 continue;
5037 }
5038 if (LocaleCompare(attribute,"display") == 0) /* same as server */
5039 {
5040 if (info && info->image_info->server_name)
5041 s=newSVpv(info->image_info->server_name,0);
5042 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5043 continue;
5044 }
5045 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5046 attribute);
5047 break;
5048 }
5049 case 'E':
5050 case 'e':
5051 {
5052 if (LocaleCompare(attribute,"elapsed-time") == 0)
5053 {
5054 if (image != (Image *) NULL)
5055 s=newSVnv(GetElapsedTime(&image->timer));
5056 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5057 continue;
5058 }
5059 if (LocaleCompare(attribute,"endian") == 0)
5060 {
5061 j=info ? info->image_info->endian : image ? image->endian :
5062 UndefinedEndian;
5063 s=newSViv(j);
5064 (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
5065 SvIOK_on(s);
5066 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5067 continue;
5068 }
5069 if (LocaleCompare(attribute,"error") == 0)
5070 {
5071 if (image != (Image *) NULL)
5072 s=newSVnv(image->error.mean_error_per_pixel);
5073 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5074 continue;
5075 }
5076 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5077 attribute);
5078 break;
5079 }
5080 case 'F':
5081 case 'f':
5082 {
5083 if (LocaleCompare(attribute,"filesize") == 0)
5084 {
5085 if (image != (Image *) NULL)
5086 s=newSViv((ssize_t) GetBlobSize(image));
5087 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5088 continue;
5089 }
5090 if (LocaleCompare(attribute,"filename") == 0)
5091 {
Cristy2273d6a2017-07-14 19:19:55 -04005092 if (info && *info->image_info->filename)
cristy4a3ce0a2013-08-03 20:06:59 +00005093 s=newSVpv(info->image_info->filename,0);
5094 if (image != (Image *) NULL)
5095 s=newSVpv(image->filename,0);
5096 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5097 continue;
5098 }
5099 if (LocaleCompare(attribute,"filter") == 0)
5100 {
5101 s=image ? newSViv(image->filter) : newSViv(0);
5102 (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
5103 image->filter));
5104 SvIOK_on(s);
5105 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5106 continue;
5107 }
5108 if (LocaleCompare(attribute,"font") == 0)
5109 {
5110 if (info && info->image_info->font)
5111 s=newSVpv(info->image_info->font,0);
5112 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5113 continue;
5114 }
5115 if (LocaleCompare(attribute,"foreground") == 0)
5116 continue;
5117 if (LocaleCompare(attribute,"format") == 0)
5118 {
5119 const MagickInfo
5120 *magick_info;
5121
5122 magick_info=(const MagickInfo *) NULL;
5123 if (info && (*info->image_info->magick != '\0'))
5124 magick_info=GetMagickInfo(info->image_info->magick,exception);
5125 if (image != (Image *) NULL)
5126 magick_info=GetMagickInfo(image->magick,exception);
5127 if ((magick_info != (const MagickInfo *) NULL) &&
5128 (*magick_info->description != '\0'))
5129 s=newSVpv((char *) magick_info->description,0);
5130 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5131 continue;
5132 }
5133 if (LocaleCompare(attribute,"fuzz") == 0)
5134 {
5135 if (info)
5136 s=newSVnv(info->image_info->fuzz);
5137 if (image != (Image *) NULL)
5138 s=newSVnv(image->fuzz);
5139 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5140 continue;
5141 }
5142 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5143 attribute);
5144 break;
5145 }
5146 case 'G':
5147 case 'g':
5148 {
5149 if (LocaleCompare(attribute,"gamma") == 0)
5150 {
5151 if (image != (Image *) NULL)
5152 s=newSVnv(image->gamma);
5153 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5154 continue;
5155 }
5156 if (LocaleCompare(attribute,"geometry") == 0)
5157 {
5158 if (image && image->geometry)
5159 s=newSVpv(image->geometry,0);
5160 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5161 continue;
5162 }
5163 if (LocaleCompare(attribute,"gravity") == 0)
5164 {
5165 s=image ? newSViv(image->gravity) : newSViv(0);
5166 (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
5167 image->gravity));
5168 SvIOK_on(s);
5169 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5170 continue;
5171 }
5172 if (LocaleCompare(attribute,"green-primary") == 0)
5173 {
5174 if (image == (Image *) NULL)
5175 break;
Cristyb1710fe2017-02-11 13:51:48 -05005176 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005177 image->chromaticity.green_primary.x,
5178 image->chromaticity.green_primary.y);
5179 s=newSVpv(color,0);
5180 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5181 continue;
5182 }
5183 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5184 attribute);
5185 break;
5186 }
5187 case 'H':
5188 case 'h':
5189 {
5190 if (LocaleCompare(attribute,"height") == 0)
5191 {
5192 if (image != (Image *) NULL)
5193 s=newSViv((ssize_t) image->rows);
5194 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5195 continue;
5196 }
5197 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5198 attribute);
5199 break;
5200 }
5201 case 'I':
5202 case 'i':
5203 {
5204 if (LocaleCompare(attribute,"icc") == 0)
5205 {
5206 if (image != (Image *) NULL)
5207 {
5208 const StringInfo
5209 *profile;
5210
5211 profile=GetImageProfile(image,"icc");
5212 if (profile != (StringInfo *) NULL)
5213 s=newSVpv((const char *) GetStringInfoDatum(profile),
5214 GetStringInfoLength(profile));
5215 }
5216 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5217 continue;
5218 }
5219 if (LocaleCompare(attribute,"icm") == 0)
5220 {
5221 if (image != (Image *) NULL)
5222 {
5223 const StringInfo
5224 *profile;
5225
5226 profile=GetImageProfile(image,"icm");
5227 if (profile != (const StringInfo *) NULL)
5228 s=newSVpv((const char *) GetStringInfoDatum(profile),
5229 GetStringInfoLength(profile));
5230 }
5231 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5232 continue;
5233 }
5234 if (LocaleCompare(attribute,"id") == 0)
5235 {
5236 if (image != (Image *) NULL)
5237 {
5238 char
cristy151b66d2015-04-15 10:50:31 +00005239 key[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005240
5241 MagickBooleanType
5242 status;
5243
5244 static ssize_t
5245 id = 0;
5246
cristy151b66d2015-04-15 10:50:31 +00005247 (void) FormatLocaleString(key,MagickPathExtent,"%.20g\n",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00005248 id);
5249 status=SetImageRegistry(ImageRegistryType,key,image,
5250 exception);
5251 (void) status;
5252 s=newSViv(id++);
5253 }
5254 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5255 continue;
5256 }
5257 if (LocaleNCompare(attribute,"index",5) == 0)
5258 {
5259 char
cristy151b66d2015-04-15 10:50:31 +00005260 name[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005261
5262 int
5263 items;
5264
5265 long
5266 x,
5267 y;
5268
5269 register const Quantum
5270 *p;
5271
5272 CacheView
5273 *image_view;
5274
5275 if (image == (Image *) NULL)
5276 break;
5277 if (image->storage_class != PseudoClass)
5278 break;
5279 x=0;
5280 y=0;
5281 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5282 (void) items;
5283 image_view=AcquireVirtualCacheView(image,exception);
5284 p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
5285 if (p != (const Quantum *) NULL)
5286 {
cristy151b66d2015-04-15 10:50:31 +00005287 (void) FormatLocaleString(name,MagickPathExtent,QuantumFormat,
cristy4a3ce0a2013-08-03 20:06:59 +00005288 GetPixelIndex(image,p));
5289 s=newSVpv(name,0);
5290 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5291 }
5292 image_view=DestroyCacheView(image_view);
5293 continue;
5294 }
5295 if (LocaleCompare(attribute,"iptc") == 0)
5296 {
5297 if (image != (Image *) NULL)
5298 {
5299 const StringInfo
5300 *profile;
5301
5302 profile=GetImageProfile(image,"iptc");
5303 if (profile != (const StringInfo *) NULL)
5304 s=newSVpv((const char *) GetStringInfoDatum(profile),
5305 GetStringInfoLength(profile));
5306 }
5307 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5308 continue;
5309 }
5310 if (LocaleCompare(attribute,"iterations") == 0) /* same as loop */
5311 {
5312 if (image != (Image *) NULL)
5313 s=newSViv((ssize_t) image->iterations);
5314 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5315 continue;
5316 }
5317 if (LocaleCompare(attribute,"interlace") == 0)
5318 {
5319 j=info ? info->image_info->interlace : image ? image->interlace :
5320 UndefinedInterlace;
5321 s=newSViv(j);
5322 (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
5323 j));
5324 SvIOK_on(s);
5325 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5326 continue;
5327 }
5328 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5329 attribute);
5330 break;
5331 }
5332 case 'L':
5333 case 'l':
5334 {
5335 if (LocaleCompare(attribute,"label") == 0)
5336 {
5337 const char
5338 *value;
5339
5340 if (image == (Image *) NULL)
5341 break;
Cristy935a4052017-03-31 17:45:37 -04005342 value=GetImageProperty(image,"Label",exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005343 if (value != (const char *) NULL)
5344 s=newSVpv(value,0);
5345 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5346 continue;
5347 }
5348 if (LocaleCompare(attribute,"loop") == 0) /* same as iterations */
5349 {
5350 if (image != (Image *) NULL)
5351 s=newSViv((ssize_t) image->iterations);
5352 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5353 continue;
5354 }
5355 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5356 attribute);
5357 break;
5358 }
5359 case 'M':
5360 case 'm':
5361 {
5362 if (LocaleCompare(attribute,"magick") == 0)
5363 {
5364 if (info && *info->image_info->magick)
5365 s=newSVpv(info->image_info->magick,0);
5366 if (image != (Image *) NULL)
5367 s=newSVpv(image->magick,0);
5368 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5369 continue;
5370 }
5371 if (LocaleCompare(attribute,"map") == 0)
5372 {
5373 s=newSViv(GetMagickResource(MapResource));
5374 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5375 continue;
5376 }
5377 if (LocaleCompare(attribute,"maximum-error") == 0)
5378 {
5379 if (image != (Image *) NULL)
5380 s=newSVnv(image->error.normalized_maximum_error);
5381 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5382 continue;
5383 }
5384 if (LocaleCompare(attribute,"memory") == 0)
5385 {
5386 s=newSViv(GetMagickResource(MemoryResource));
5387 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5388 continue;
5389 }
5390 if (LocaleCompare(attribute,"mean-error") == 0)
5391 {
5392 if (image != (Image *) NULL)
5393 s=newSVnv(image->error.normalized_mean_error);
5394 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5395 continue;
5396 }
5397 if (LocaleCompare(attribute,"mime") == 0)
5398 {
5399 if (info && *info->image_info->magick)
5400 s=newSVpv(MagickToMime(info->image_info->magick),0);
5401 if (image != (Image *) NULL)
5402 s=newSVpv(MagickToMime(image->magick),0);
5403 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5404 continue;
5405 }
5406 if (LocaleCompare(attribute,"mattecolor") == 0)
5407 {
5408 if (image == (Image *) NULL)
5409 break;
cristy151b66d2015-04-15 10:50:31 +00005410 (void) FormatLocaleString(color,MagickPathExtent,
Cristy8645e042016-02-03 16:35:29 -05005411 "%.20g,%.20g,%.20g,%.20g",(double) image->alpha_color.red,
5412 (double) image->alpha_color.green,
5413 (double) image->alpha_color.blue,
5414 (double) image->alpha_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005415 s=newSVpv(color,0);
5416 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5417 continue;
5418 }
5419 if (LocaleCompare(attribute,"matte") == 0)
5420 {
5421 if (image != (Image *) NULL)
cristy17f11b02014-12-20 19:37:04 +00005422 s=newSViv((ssize_t) image->alpha_trait != UndefinedPixelTrait ?
cristy4a3ce0a2013-08-03 20:06:59 +00005423 1 : 0);
5424 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5425 continue;
5426 }
5427 if (LocaleCompare(attribute,"mime") == 0)
5428 {
5429 const char
5430 *magick;
5431
5432 magick=NULL;
5433 if (info && *info->image_info->magick)
5434 magick=info->image_info->magick;
5435 if (image != (Image *) NULL)
5436 magick=image->magick;
5437 if (magick)
5438 {
5439 char
5440 *mime;
5441
5442 mime=MagickToMime(magick);
5443 s=newSVpv(mime,0);
5444 mime=(char *) RelinquishMagickMemory(mime);
5445 }
5446 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5447 continue;
5448 }
5449 if (LocaleCompare(attribute,"monochrome") == 0)
5450 {
5451 if (image == (Image *) NULL)
5452 continue;
5453 j=info ? info->image_info->monochrome :
cristy932cb072015-04-13 20:06:25 +00005454 SetImageMonochrome(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00005455 s=newSViv(j);
5456 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5457 continue;
5458 }
5459 if (LocaleCompare(attribute,"montage") == 0)
5460 {
5461 if (image && image->montage)
5462 s=newSVpv(image->montage,0);
5463 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5464 continue;
5465 }
5466 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5467 attribute);
5468 break;
5469 }
5470 case 'O':
5471 case 'o':
5472 {
5473 if (LocaleCompare(attribute,"orientation") == 0)
5474 {
5475 j=info ? info->image_info->orientation : image ?
5476 image->orientation : UndefinedOrientation;
5477 s=newSViv(j);
5478 (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
5479 j));
5480 SvIOK_on(s);
5481 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5482 continue;
5483 }
5484 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5485 attribute);
5486 break;
5487 }
5488 case 'P':
5489 case 'p':
5490 {
5491 if (LocaleCompare(attribute,"page") == 0)
5492 {
5493 if (info && info->image_info->page)
5494 s=newSVpv(info->image_info->page,0);
5495 if (image != (Image *) NULL)
5496 {
5497 char
cristy151b66d2015-04-15 10:50:31 +00005498 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005499
cristy151b66d2015-04-15 10:50:31 +00005500 (void) FormatLocaleString(geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00005501 "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
5502 (double) image->page.height,(double) image->page.x,(double)
5503 image->page.y);
5504 s=newSVpv(geometry,0);
5505 }
5506 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5507 continue;
5508 }
5509 if (LocaleCompare(attribute,"page.x") == 0)
5510 {
5511 if (image != (Image *) NULL)
5512 s=newSViv((ssize_t) image->page.x);
5513 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5514 continue;
5515 }
5516 if (LocaleCompare(attribute,"page.y") == 0)
5517 {
5518 if (image != (Image *) NULL)
5519 s=newSViv((ssize_t) image->page.y);
5520 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5521 continue;
5522 }
5523 if (LocaleNCompare(attribute,"pixel",5) == 0)
5524 {
5525 char
cristy151b66d2015-04-15 10:50:31 +00005526 tuple[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00005527
5528 int
5529 items;
5530
5531 long
5532 x,
5533 y;
5534
5535 register const Quantum
5536 *p;
5537
5538 if (image == (Image *) NULL)
5539 break;
5540 x=0;
5541 y=0;
5542 items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
5543 (void) items;
5544 p=GetVirtualPixels(image,x,y,1,1,exception);
5545 if (image->colorspace != CMYKColorspace)
cristy151b66d2015-04-15 10:50:31 +00005546 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005547 QuantumFormat "," QuantumFormat "," QuantumFormat,
5548 GetPixelRed(image,p),GetPixelGreen(image,p),
5549 GetPixelBlue(image,p),GetPixelAlpha(image,p));
5550 else
cristy151b66d2015-04-15 10:50:31 +00005551 (void) FormatLocaleString(tuple,MagickPathExtent,QuantumFormat ","
cristy4a3ce0a2013-08-03 20:06:59 +00005552 QuantumFormat "," QuantumFormat "," QuantumFormat ","
5553 QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
5554 GetPixelBlue(image,p),GetPixelBlack(image,p),
5555 GetPixelAlpha(image,p));
5556 s=newSVpv(tuple,0);
5557 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5558 continue;
5559 }
5560 if (LocaleCompare(attribute,"pointsize") == 0)
5561 {
5562 if (info)
5563 s=newSViv((ssize_t) info->image_info->pointsize);
5564 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5565 continue;
5566 }
Cristy798981a2020-02-17 12:07:15 -05005567 if (LocaleCompare(attribute,"precision") == 0)
5568 {
5569 s=newSViv((ssize_t) GetMagickPrecision());
5570 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5571 continue;
5572 }
cristy4a3ce0a2013-08-03 20:06:59 +00005573 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5574 attribute);
5575 break;
5576 }
5577 case 'Q':
5578 case 'q':
5579 {
5580 if (LocaleCompare(attribute,"quality") == 0)
5581 {
5582 if (info)
5583 s=newSViv((ssize_t) info->image_info->quality);
5584 if (image != (Image *) NULL)
5585 s=newSViv((ssize_t) image->quality);
5586 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5587 continue;
5588 }
5589 if (LocaleCompare(attribute,"quantum") == 0)
5590 {
5591 if (info)
5592 s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
5593 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5594 continue;
5595 }
5596 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5597 attribute);
5598 break;
5599 }
5600 case 'R':
5601 case 'r':
5602 {
5603 if (LocaleCompare(attribute,"rendering-intent") == 0)
5604 {
5605 s=newSViv(image->rendering_intent);
5606 (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
5607 image->rendering_intent));
5608 SvIOK_on(s);
5609 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5610 continue;
5611 }
5612 if (LocaleCompare(attribute,"red-primary") == 0)
5613 {
5614 if (image == (Image *) NULL)
5615 break;
Cristyb1710fe2017-02-11 13:51:48 -05005616 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005617 image->chromaticity.red_primary.x,
5618 image->chromaticity.red_primary.y);
5619 s=newSVpv(color,0);
5620 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5621 continue;
5622 }
5623 if (LocaleCompare(attribute,"rows") == 0)
5624 {
5625 if (image != (Image *) NULL)
5626 s=newSViv((ssize_t) image->rows);
5627 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5628 continue;
5629 }
5630 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5631 attribute);
5632 break;
5633 }
5634 case 'S':
5635 case 's':
5636 {
5637 if (LocaleCompare(attribute,"sampling-factor") == 0)
5638 {
5639 if (info && info->image_info->sampling_factor)
5640 s=newSVpv(info->image_info->sampling_factor,0);
5641 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5642 continue;
5643 }
5644 if (LocaleCompare(attribute,"server") == 0) /* same as display */
5645 {
5646 if (info && info->image_info->server_name)
5647 s=newSVpv(info->image_info->server_name,0);
5648 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5649 continue;
5650 }
5651 if (LocaleCompare(attribute,"size") == 0)
5652 {
5653 if (info && info->image_info->size)
5654 s=newSVpv(info->image_info->size,0);
5655 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5656 continue;
5657 }
5658 if (LocaleCompare(attribute,"scene") == 0)
5659 {
5660 if (image != (Image *) NULL)
5661 s=newSViv((ssize_t) image->scene);
5662 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5663 continue;
5664 }
5665 if (LocaleCompare(attribute,"scenes") == 0)
5666 {
5667 if (image != (Image *) NULL)
5668 s=newSViv((ssize_t) info->image_info->number_scenes);
5669 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5670 continue;
5671 }
5672 if (LocaleCompare(attribute,"signature") == 0)
5673 {
5674 const char
5675 *value;
5676
5677 if (image == (Image *) NULL)
5678 break;
5679 (void) SignatureImage(image,exception);
5680 value=GetImageProperty(image,"Signature",exception);
5681 if (value != (const char *) NULL)
5682 s=newSVpv(value,0);
5683 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5684 continue;
5685 }
5686 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5687 attribute);
5688 break;
5689 }
5690 case 'T':
5691 case 't':
5692 {
5693 if (LocaleCompare(attribute,"taint") == 0)
5694 {
5695 if (image != (Image *) NULL)
5696 s=newSViv((ssize_t) IsTaintImage(image));
5697 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5698 continue;
5699 }
5700 if (LocaleCompare(attribute,"texture") == 0)
5701 {
5702 if (info && info->image_info->texture)
5703 s=newSVpv(info->image_info->texture,0);
5704 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5705 continue;
5706 }
5707 if (LocaleCompare(attribute,"total-ink-density") == 0)
5708 {
5709 s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
5710 if (image != (Image *) NULL)
5711 s=newSVnv(GetImageTotalInkDensity(image,exception));
5712 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5713 continue;
5714 }
5715 if (LocaleCompare(attribute,"transparent-color") == 0)
5716 {
5717 if (image == (Image *) NULL)
5718 break;
cristy151b66d2015-04-15 10:50:31 +00005719 (void) FormatLocaleString(color,MagickPathExtent,
cristyaa659162014-08-26 11:35:47 +00005720 "%.20g,%.20g,%.20g,%.20g",(double) image->transparent_color.red,
5721 (double) image->transparent_color.green,
5722 (double) image->transparent_color.blue,
5723 (double) image->transparent_color.alpha);
cristy4a3ce0a2013-08-03 20:06:59 +00005724 s=newSVpv(color,0);
5725 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5726 continue;
5727 }
5728 if (LocaleCompare(attribute,"type") == 0)
5729 {
5730 if (image == (Image *) NULL)
5731 break;
cristya26f54c2015-07-29 12:26:12 +00005732 j=(ssize_t) GetImageType(image);
cristy4a3ce0a2013-08-03 20:06:59 +00005733 s=newSViv(j);
5734 (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
5735 SvIOK_on(s);
5736 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5737 continue;
5738 }
5739 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5740 attribute);
5741 break;
5742 }
5743 case 'U':
5744 case 'u':
5745 {
5746 if (LocaleCompare(attribute,"units") == 0)
5747 {
5748 j=info ? info->image_info->units : image ? image->units :
5749 UndefinedResolution;
5750 if (info && (info->image_info->units == UndefinedResolution))
5751 if (image)
5752 j=image->units;
5753 if (j == UndefinedResolution)
5754 s=newSVpv("undefined units",0);
5755 else
5756 if (j == PixelsPerInchResolution)
5757 s=newSVpv("pixels / inch",0);
5758 else
5759 s=newSVpv("pixels / centimeter",0);
5760 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5761 continue;
5762 }
5763 if (LocaleCompare(attribute,"user-time") == 0)
5764 {
5765 if (image != (Image *) NULL)
5766 s=newSVnv(GetUserTime(&image->timer));
5767 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5768 continue;
5769 }
5770 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5771 attribute);
5772 break;
5773 }
5774 case 'V':
5775 case 'v':
5776 {
5777 if (LocaleCompare(attribute,"verbose") == 0)
5778 {
5779 if (info)
5780 s=newSViv((ssize_t) info->image_info->verbose);
5781 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5782 continue;
5783 }
5784 if (LocaleCompare(attribute,"version") == 0)
5785 {
5786 s=newSVpv(GetMagickVersion((size_t *) NULL),0);
5787 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5788 continue;
5789 }
cristy4a3ce0a2013-08-03 20:06:59 +00005790 if (LocaleCompare(attribute,"virtual-pixel") == 0)
5791 {
5792 if (image == (Image *) NULL)
5793 break;
5794 j=(ssize_t) GetImageVirtualPixelMethod(image);
5795 s=newSViv(j);
5796 (void) sv_setpv(s,CommandOptionToMnemonic(
5797 MagickVirtualPixelOptions,j));
5798 SvIOK_on(s);
5799 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5800 continue;
5801 }
5802 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5803 attribute);
5804 break;
5805 }
5806 case 'W':
5807 case 'w':
5808 {
5809 if (LocaleCompare(attribute,"white-point") == 0)
5810 {
5811 if (image == (Image *) NULL)
5812 break;
Cristyb1710fe2017-02-11 13:51:48 -05005813 (void) FormatLocaleString(color,MagickPathExtent,"%.20g,%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00005814 image->chromaticity.white_point.x,
5815 image->chromaticity.white_point.y);
5816 s=newSVpv(color,0);
5817 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5818 continue;
5819 }
5820 if (LocaleCompare(attribute,"width") == 0)
5821 {
5822 if (image != (Image *) NULL)
5823 s=newSViv((ssize_t) image->columns);
5824 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5825 continue;
5826 }
5827 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5828 attribute);
5829 break;
5830 }
5831 case 'X':
5832 case 'x':
5833 {
Cristyc1f9f9f2016-01-05 08:19:28 -05005834 if (LocaleCompare(attribute,"xmp") == 0)
5835 {
5836 if (image != (Image *) NULL)
5837 {
5838 const StringInfo
5839 *profile;
5840
5841 profile=GetImageProfile(image,"xmp");
5842 if (profile != (StringInfo *) NULL)
5843 s=newSVpv((const char *) GetStringInfoDatum(profile),
5844 GetStringInfoLength(profile));
5845 }
5846 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5847 continue;
5848 }
cristy4a3ce0a2013-08-03 20:06:59 +00005849 if (LocaleCompare(attribute,"x-resolution") == 0)
5850 {
5851 if (image != (Image *) NULL)
5852 s=newSVnv(image->resolution.x);
5853 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5854 continue;
5855 }
5856 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5857 attribute);
5858 break;
5859 }
5860 case 'Y':
5861 case 'y':
5862 {
5863 if (LocaleCompare(attribute,"y-resolution") == 0)
5864 {
5865 if (image != (Image *) NULL)
5866 s=newSVnv(image->resolution.y);
5867 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5868 continue;
5869 }
5870 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5871 attribute);
5872 break;
5873 }
5874 default:
5875 break;
5876 }
5877 if (image == (Image *) NULL)
5878 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5879 attribute)
5880 else
5881 {
5882 value=GetImageProperty(image,attribute,exception);
5883 if (value != (const char *) NULL)
5884 {
5885 s=newSVpv(value,0);
5886 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5887 }
5888 else
5889 if (*attribute != '%')
5890 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5891 attribute)
5892 else
5893 {
5894 char
5895 *meta;
5896
5897 meta=InterpretImageProperties(info ? info->image_info :
5898 (ImageInfo *) NULL,image,attribute,exception);
5899 s=newSVpv(meta,0);
5900 PUSHs(s ? sv_2mortal(s) : &sv_undef);
5901 meta=(char *) RelinquishMagickMemory(meta);
5902 }
5903 }
5904 }
5905 exception=DestroyExceptionInfo(exception);
5906 SvREFCNT_dec(perl_exception); /* can't return warning messages */
5907 }
5908
5909#
5910###############################################################################
5911# #
5912# #
5913# #
5914# G e t A u t h e n t i c P i x e l s #
5915# #
5916# #
5917# #
5918###############################################################################
5919#
5920#
5921void *
5922GetAuthenticPixels(ref,...)
5923 Image::Magick ref = NO_INIT
5924 ALIAS:
5925 getauthenticpixels = 1
5926 GetImagePixels = 2
5927 getimagepixels = 3
5928 CODE:
5929 {
5930 char
5931 *attribute;
5932
5933 ExceptionInfo
5934 *exception;
5935
5936 Image
5937 *image;
5938
5939 RectangleInfo
5940 region;
5941
5942 ssize_t
5943 i;
5944
5945 struct PackageInfo
5946 *info;
5947
5948 SV
5949 *perl_exception,
5950 *reference;
5951
5952 void
5953 *blob = NULL;
5954
5955 PERL_UNUSED_VAR(ref);
5956 PERL_UNUSED_VAR(ix);
5957 exception=AcquireExceptionInfo();
5958 perl_exception=newSVpv("",0);
5959 if (sv_isobject(ST(0)) == 0)
5960 {
5961 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
5962 PackageName);
5963 goto PerlException;
5964 }
5965 reference=SvRV(ST(0));
5966
5967 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
5968 if (image == (Image *) NULL)
5969 {
5970 ThrowPerlException(exception,OptionError,"NoImagesDefined",
5971 PackageName);
5972 goto PerlException;
5973 }
5974
5975 region.x=0;
5976 region.y=0;
5977 region.width=image->columns;
5978 region.height=1;
5979 if (items == 1)
5980 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
5981 for (i=2; i < items; i+=2)
5982 {
5983 attribute=(char *) SvPV(ST(i-1),na);
5984 switch (*attribute)
5985 {
5986 case 'g':
5987 case 'G':
5988 {
5989 if (LocaleCompare(attribute,"geometry") == 0)
5990 {
5991 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
5992 break;
5993 }
5994 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
5995 attribute);
5996 break;
5997 }
5998 case 'H':
5999 case 'h':
6000 {
6001 if (LocaleCompare(attribute,"height") == 0)
6002 {
6003 region.height=SvIV(ST(i));
6004 continue;
6005 }
6006 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6007 attribute);
6008 break;
6009 }
6010 case 'X':
6011 case 'x':
6012 {
6013 if (LocaleCompare(attribute,"x") == 0)
6014 {
6015 region.x=SvIV(ST(i));
6016 continue;
6017 }
6018 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6019 attribute);
6020 break;
6021 }
6022 case 'Y':
6023 case 'y':
6024 {
6025 if (LocaleCompare(attribute,"y") == 0)
6026 {
6027 region.y=SvIV(ST(i));
6028 continue;
6029 }
6030 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6031 attribute);
6032 break;
6033 }
6034 case 'W':
6035 case 'w':
6036 {
6037 if (LocaleCompare(attribute,"width") == 0)
6038 {
6039 region.width=SvIV(ST(i));
6040 continue;
6041 }
6042 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6043 attribute);
6044 break;
6045 }
6046 }
6047 }
6048 blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
6049 region.height,exception);
6050 if (blob != (void *) NULL)
6051 goto PerlEnd;
6052
6053 PerlException:
6054 InheritPerlException(exception,perl_exception);
6055 exception=DestroyExceptionInfo(exception);
6056 SvREFCNT_dec(perl_exception); /* throw away all errors */
6057
6058 PerlEnd:
6059 RETVAL = blob;
6060 }
6061 OUTPUT:
6062 RETVAL
6063
6064#
6065###############################################################################
6066# #
6067# #
6068# #
6069# G e t V i r t u a l P i x e l s #
6070# #
6071# #
6072# #
6073###############################################################################
6074#
6075#
6076void *
6077GetVirtualPixels(ref,...)
6078 Image::Magick ref = NO_INIT
6079 ALIAS:
6080 getvirtualpixels = 1
6081 AcquireImagePixels = 2
6082 acquireimagepixels = 3
6083 CODE:
6084 {
6085 char
6086 *attribute;
6087
6088 const void
6089 *blob = NULL;
6090
6091 ExceptionInfo
6092 *exception;
6093
6094 Image
6095 *image;
6096
6097 RectangleInfo
6098 region;
6099
6100 ssize_t
6101 i;
6102
6103 struct PackageInfo
6104 *info;
6105
6106 SV
6107 *perl_exception,
6108 *reference;
6109
6110 PERL_UNUSED_VAR(ref);
6111 PERL_UNUSED_VAR(ix);
6112 exception=AcquireExceptionInfo();
6113 perl_exception=newSVpv("",0);
6114 if (sv_isobject(ST(0)) == 0)
6115 {
6116 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6117 PackageName);
6118 goto PerlException;
6119 }
6120 reference=SvRV(ST(0));
6121
6122 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6123 if (image == (Image *) NULL)
6124 {
6125 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6126 PackageName);
6127 goto PerlException;
6128 }
6129
6130 region.x=0;
6131 region.y=0;
6132 region.width=image->columns;
6133 region.height=1;
6134 if (items == 1)
6135 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6136 for (i=2; i < items; i+=2)
6137 {
6138 attribute=(char *) SvPV(ST(i-1),na);
6139 switch (*attribute)
6140 {
6141 case 'g':
6142 case 'G':
6143 {
6144 if (LocaleCompare(attribute,"geometry") == 0)
6145 {
6146 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6147 break;
6148 }
6149 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6150 attribute);
6151 break;
6152 }
6153 case 'H':
6154 case 'h':
6155 {
6156 if (LocaleCompare(attribute,"height") == 0)
6157 {
6158 region.height=SvIV(ST(i));
6159 continue;
6160 }
6161 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6162 attribute);
6163 break;
6164 }
6165 case 'X':
6166 case 'x':
6167 {
6168 if (LocaleCompare(attribute,"x") == 0)
6169 {
6170 region.x=SvIV(ST(i));
6171 continue;
6172 }
6173 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6174 attribute);
6175 break;
6176 }
6177 case 'Y':
6178 case 'y':
6179 {
6180 if (LocaleCompare(attribute,"y") == 0)
6181 {
6182 region.y=SvIV(ST(i));
6183 continue;
6184 }
6185 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6186 attribute);
6187 break;
6188 }
6189 case 'W':
6190 case 'w':
6191 {
6192 if (LocaleCompare(attribute,"width") == 0)
6193 {
6194 region.width=SvIV(ST(i));
6195 continue;
6196 }
6197 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
6198 attribute);
6199 break;
6200 }
6201 }
6202 }
6203 blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
6204 region.height,exception);
6205 if (blob != (void *) NULL)
6206 goto PerlEnd;
6207
6208 PerlException:
6209 InheritPerlException(exception,perl_exception);
6210 exception=DestroyExceptionInfo(exception);
6211 SvREFCNT_dec(perl_exception); /* throw away all errors */
6212
6213 PerlEnd:
6214 RETVAL = (void *) blob;
6215 }
6216 OUTPUT:
6217 RETVAL
6218
6219#
6220###############################################################################
6221# #
6222# #
6223# #
6224# G e t A u t h e n t i c M e t a c o n t e n t #
6225# #
6226# #
6227# #
6228###############################################################################
6229#
6230#
6231void *
6232GetAuthenticMetacontent(ref,...)
6233 Image::Magick ref = NO_INIT
6234 ALIAS:
6235 getauthenticmetacontent = 1
6236 GetMetacontent = 2
6237 getmetacontent = 3
6238 CODE:
6239 {
6240 ExceptionInfo
6241 *exception;
6242
6243 Image
6244 *image;
6245
6246 struct PackageInfo
6247 *info;
6248
6249 SV
6250 *perl_exception,
6251 *reference;
6252
6253 void
6254 *blob = NULL;
6255
6256 PERL_UNUSED_VAR(ref);
6257 PERL_UNUSED_VAR(ix);
6258 exception=AcquireExceptionInfo();
6259 perl_exception=newSVpv("",0);
6260 if (sv_isobject(ST(0)) == 0)
6261 {
6262 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6263 PackageName);
6264 goto PerlException;
6265 }
6266 reference=SvRV(ST(0));
6267
6268 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6269 if (image == (Image *) NULL)
6270 {
6271 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6272 PackageName);
6273 goto PerlException;
6274 }
6275
6276 blob=(void *) GetAuthenticMetacontent(image);
6277 if (blob != (void *) NULL)
6278 goto PerlEnd;
6279
6280 PerlException:
6281 InheritPerlException(exception,perl_exception);
6282 exception=DestroyExceptionInfo(exception);
6283 SvREFCNT_dec(perl_exception); /* throw away all errors */
6284
6285 PerlEnd:
6286 RETVAL = blob;
6287 }
6288 OUTPUT:
6289 RETVAL
6290
6291#
6292###############################################################################
6293# #
6294# #
6295# #
6296# G e t V i r t u a l M e t a c o n t e n t #
6297# #
6298# #
6299# #
6300###############################################################################
6301#
6302#
6303void *
6304GetVirtualMetacontent(ref,...)
6305 Image::Magick ref = NO_INIT
6306 ALIAS:
6307 getvirtualmetacontent = 1
6308 CODE:
6309 {
6310 ExceptionInfo
6311 *exception;
6312
6313 Image
6314 *image;
6315
6316 struct PackageInfo
6317 *info;
6318
6319 SV
6320 *perl_exception,
6321 *reference;
6322
6323 void
6324 *blob = NULL;
6325
6326 PERL_UNUSED_VAR(ref);
6327 PERL_UNUSED_VAR(ix);
6328 exception=AcquireExceptionInfo();
6329 perl_exception=newSVpv("",0);
6330 if (sv_isobject(ST(0)) == 0)
6331 {
6332 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6333 PackageName);
6334 goto PerlException;
6335 }
6336 reference=SvRV(ST(0));
6337
6338 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6339 if (image == (Image *) NULL)
6340 {
6341 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6342 PackageName);
6343 goto PerlException;
6344 }
6345
6346 blob=(void *) GetVirtualMetacontent(image);
6347 if (blob != (void *) NULL)
6348 goto PerlEnd;
6349
6350 PerlException:
6351 InheritPerlException(exception,perl_exception);
6352 exception=DestroyExceptionInfo(exception);
6353 SvREFCNT_dec(perl_exception); /* throw away all errors */
6354
6355 PerlEnd:
6356 RETVAL = blob;
6357 }
6358 OUTPUT:
6359 RETVAL
6360
6361#
6362###############################################################################
6363# #
6364# #
6365# #
6366# H i s t o g r a m #
6367# #
6368# #
6369# #
6370###############################################################################
6371#
6372#
6373void
6374Histogram(ref,...)
6375 Image::Magick ref=NO_INIT
6376 ALIAS:
6377 HistogramImage = 1
6378 histogram = 2
6379 histogramimage = 3
6380 PPCODE:
6381 {
6382 AV
6383 *av;
6384
6385 char
cristy151b66d2015-04-15 10:50:31 +00006386 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006387
6388 PixelInfo
6389 *histogram;
6390
6391 ExceptionInfo
6392 *exception;
6393
6394 Image
6395 *image;
6396
6397 register ssize_t
6398 i;
6399
6400 ssize_t
6401 count;
6402
6403 struct PackageInfo
6404 *info;
6405
6406 SV
6407 *perl_exception,
6408 *reference;
6409
6410 size_t
6411 number_colors;
6412
6413 PERL_UNUSED_VAR(ref);
6414 PERL_UNUSED_VAR(ix);
6415 exception=AcquireExceptionInfo();
6416 perl_exception=newSVpv("",0);
6417 av=NULL;
6418 if (sv_isobject(ST(0)) == 0)
6419 {
6420 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6421 PackageName);
6422 goto PerlException;
6423 }
6424 reference=SvRV(ST(0));
6425 av=newAV();
6426 SvREFCNT_dec(av);
6427 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6428 if (image == (Image *) NULL)
6429 {
6430 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6431 PackageName);
6432 goto PerlException;
6433 }
cristy4a3ce0a2013-08-03 20:06:59 +00006434 count=0;
6435 for ( ; image; image=image->next)
6436 {
6437 histogram=GetImageHistogram(image,&number_colors,exception);
6438 if (histogram == (PixelInfo *) NULL)
6439 continue;
6440 count+=(ssize_t) number_colors;
6441 EXTEND(sp,6*count);
6442 for (i=0; i < (ssize_t) number_colors; i++)
6443 {
cristy151b66d2015-04-15 10:50:31 +00006444 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006445 histogram[i].red);
6446 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006447 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006448 histogram[i].green);
6449 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006450 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006451 histogram[i].blue);
6452 PUSHs(sv_2mortal(newSVpv(message,0)));
6453 if (image->colorspace == CMYKColorspace)
6454 {
cristy151b66d2015-04-15 10:50:31 +00006455 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006456 histogram[i].black);
6457 PUSHs(sv_2mortal(newSVpv(message,0)));
6458 }
cristy151b66d2015-04-15 10:50:31 +00006459 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",
cristy4a3ce0a2013-08-03 20:06:59 +00006460 histogram[i].alpha);
6461 PUSHs(sv_2mortal(newSVpv(message,0)));
cristy151b66d2015-04-15 10:50:31 +00006462 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +00006463 histogram[i].count);
6464 PUSHs(sv_2mortal(newSVpv(message,0)));
6465 }
6466 histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
6467 }
6468
6469 PerlException:
6470 InheritPerlException(exception,perl_exception);
6471 exception=DestroyExceptionInfo(exception);
6472 SvREFCNT_dec(perl_exception);
6473 }
6474
6475#
6476###############################################################################
6477# #
6478# #
6479# #
6480# G e t P i x e l #
6481# #
6482# #
6483# #
6484###############################################################################
6485#
6486#
6487void
6488GetPixel(ref,...)
6489 Image::Magick ref=NO_INIT
6490 ALIAS:
6491 getpixel = 1
6492 getPixel = 2
6493 PPCODE:
6494 {
6495 AV
6496 *av;
6497
6498 char
6499 *attribute;
6500
6501 ExceptionInfo
6502 *exception;
6503
6504 Image
6505 *image;
6506
6507 MagickBooleanType
6508 normalize;
6509
6510 RectangleInfo
6511 region;
6512
6513 register const Quantum
6514 *p;
6515
6516 register ssize_t
6517 i;
6518
6519 ssize_t
6520 option;
6521
6522 struct PackageInfo
6523 *info;
6524
6525 SV
6526 *perl_exception,
6527 *reference; /* reference is the SV* of ref=SvIV(reference) */
6528
6529 PERL_UNUSED_VAR(ref);
6530 PERL_UNUSED_VAR(ix);
6531 exception=AcquireExceptionInfo();
6532 perl_exception=newSVpv("",0);
6533 reference=SvRV(ST(0));
6534 av=(AV *) reference;
6535 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6536 exception);
6537 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6538 if (image == (Image *) NULL)
6539 {
6540 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6541 PackageName);
6542 goto PerlException;
6543 }
6544 normalize=MagickTrue;
6545 region.x=0;
6546 region.y=0;
6547 region.width=image->columns;
6548 region.height=1;
6549 if (items == 1)
6550 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6551 for (i=2; i < items; i+=2)
6552 {
6553 attribute=(char *) SvPV(ST(i-1),na);
6554 switch (*attribute)
6555 {
6556 case 'C':
6557 case 'c':
6558 {
6559 if (LocaleCompare(attribute,"channel") == 0)
6560 {
6561 ssize_t
6562 option;
6563
6564 option=ParseChannelOption(SvPV(ST(i),na));
6565 if (option < 0)
6566 {
6567 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6568 SvPV(ST(i),na));
6569 return;
6570 }
cristybcd59342015-06-07 14:07:19 +00006571 (void) SetPixelChannelMask(image,(ChannelType) option);
cristy4a3ce0a2013-08-03 20:06:59 +00006572 break;
6573 }
6574 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6575 attribute);
6576 break;
6577 }
6578 case 'g':
6579 case 'G':
6580 {
6581 if (LocaleCompare(attribute,"geometry") == 0)
6582 {
6583 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6584 break;
6585 }
6586 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6587 attribute);
6588 break;
6589 }
6590 case 'N':
6591 case 'n':
6592 {
6593 if (LocaleCompare(attribute,"normalize") == 0)
6594 {
6595 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6596 SvPV(ST(i),na));
6597 if (option < 0)
6598 {
6599 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6600 SvPV(ST(i),na));
6601 break;
6602 }
6603 normalize=option != 0 ? MagickTrue : MagickFalse;
6604 break;
6605 }
6606 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6607 attribute);
6608 break;
6609 }
6610 case 'x':
6611 case 'X':
6612 {
6613 if (LocaleCompare(attribute,"x") == 0)
6614 {
6615 region.x=SvIV(ST(i));
6616 break;
6617 }
6618 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6619 attribute);
6620 break;
6621 }
6622 case 'y':
6623 case 'Y':
6624 {
6625 if (LocaleCompare(attribute,"y") == 0)
6626 {
6627 region.y=SvIV(ST(i));
6628 break;
6629 }
6630 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6631 attribute);
6632 break;
6633 }
6634 default:
6635 {
6636 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6637 attribute);
6638 break;
6639 }
6640 }
6641 }
6642 p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
6643 if (p == (const Quantum *) NULL)
6644 PUSHs(&sv_undef);
6645 else
6646 {
6647 double
6648 scale;
6649
6650 scale=1.0;
6651 if (normalize != MagickFalse)
6652 scale=1.0/QuantumRange;
6653 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
6654 PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
6655 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
6656 PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
6657 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
6658 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
6659 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
6660 (image->colorspace == CMYKColorspace))
6661 PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
6662 if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
6663 PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
6664 }
6665
6666 PerlException:
6667 InheritPerlException(exception,perl_exception);
6668 exception=DestroyExceptionInfo(exception);
6669 SvREFCNT_dec(perl_exception);
6670 }
6671
6672#
6673###############################################################################
6674# #
6675# #
6676# #
6677# G e t P i x e l s #
6678# #
6679# #
6680# #
6681###############################################################################
6682#
6683#
6684void
6685GetPixels(ref,...)
6686 Image::Magick ref=NO_INIT
6687 ALIAS:
6688 getpixels = 1
6689 getPixels = 2
6690 PPCODE:
6691 {
6692 AV
6693 *av;
6694
6695 char
6696 *attribute;
6697
6698 const char
6699 *map;
6700
6701 ExceptionInfo
6702 *exception;
6703
6704 Image
6705 *image;
6706
6707 MagickBooleanType
6708 normalize,
6709 status;
6710
6711 RectangleInfo
6712 region;
6713
6714 register ssize_t
6715 i;
6716
6717 ssize_t
6718 option;
6719
6720 struct PackageInfo
6721 *info;
6722
6723 SV
6724 *perl_exception,
6725 *reference; /* reference is the SV* of ref=SvIV(reference) */
6726
6727 PERL_UNUSED_VAR(ref);
6728 PERL_UNUSED_VAR(ix);
6729 exception=AcquireExceptionInfo();
6730 perl_exception=newSVpv("",0);
6731 reference=SvRV(ST(0));
6732 av=(AV *) reference;
6733 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
6734 exception);
6735 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6736 if (image == (Image *) NULL)
6737 {
6738 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6739 PackageName);
6740 goto PerlException;
6741 }
6742 map="RGB";
cristy17f11b02014-12-20 19:37:04 +00006743 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006744 map="RGBA";
6745 if (image->colorspace == CMYKColorspace)
6746 {
6747 map="CMYK";
cristy17f11b02014-12-20 19:37:04 +00006748 if (image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00006749 map="CMYKA";
6750 }
6751 normalize=MagickFalse;
6752 region.x=0;
6753 region.y=0;
6754 region.width=image->columns;
6755 region.height=1;
6756 if (items == 1)
6757 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
6758 for (i=2; i < items; i+=2)
6759 {
6760 attribute=(char *) SvPV(ST(i-1),na);
6761 switch (*attribute)
6762 {
6763 case 'g':
6764 case 'G':
6765 {
6766 if (LocaleCompare(attribute,"geometry") == 0)
6767 {
6768 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
6769 break;
6770 }
6771 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6772 attribute);
6773 break;
6774 }
6775 case 'H':
6776 case 'h':
6777 {
6778 if (LocaleCompare(attribute,"height") == 0)
6779 {
6780 region.height=SvIV(ST(i));
6781 break;
6782 }
6783 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6784 attribute);
6785 break;
6786 }
6787 case 'M':
6788 case 'm':
6789 {
6790 if (LocaleCompare(attribute,"map") == 0)
6791 {
6792 map=SvPV(ST(i),na);
6793 break;
6794 }
6795 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6796 attribute);
6797 break;
6798 }
6799 case 'N':
6800 case 'n':
6801 {
6802 if (LocaleCompare(attribute,"normalize") == 0)
6803 {
6804 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6805 SvPV(ST(i),na));
6806 if (option < 0)
6807 {
6808 ThrowPerlException(exception,OptionError,"UnrecognizedType",
6809 SvPV(ST(i),na));
6810 break;
6811 }
6812 normalize=option != 0 ? MagickTrue : MagickFalse;
6813 break;
6814 }
6815 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6816 attribute);
6817 break;
6818 }
6819 case 'W':
6820 case 'w':
6821 {
6822 if (LocaleCompare(attribute,"width") == 0)
6823 {
6824 region.width=SvIV(ST(i));
6825 break;
6826 }
6827 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6828 attribute);
6829 break;
6830 }
6831 case 'x':
6832 case 'X':
6833 {
6834 if (LocaleCompare(attribute,"x") == 0)
6835 {
6836 region.x=SvIV(ST(i));
6837 break;
6838 }
6839 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6840 attribute);
6841 break;
6842 }
6843 case 'y':
6844 case 'Y':
6845 {
6846 if (LocaleCompare(attribute,"y") == 0)
6847 {
6848 region.y=SvIV(ST(i));
6849 break;
6850 }
6851 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6852 attribute);
6853 break;
6854 }
6855 default:
6856 {
6857 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
6858 attribute);
6859 break;
6860 }
6861 }
6862 }
6863 if (normalize != MagickFalse)
6864 {
6865 float
6866 *pixels;
6867
6868 pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
6869 region.height*sizeof(*pixels));
6870 if (pixels == (float *) NULL)
6871 {
6872 ThrowPerlException(exception,ResourceLimitError,
6873 "MemoryAllocationFailed",PackageName);
6874 goto PerlException;
6875 }
6876 status=ExportImagePixels(image,region.x,region.y,region.width,
6877 region.height,map,FloatPixel,pixels,exception);
6878 if (status == MagickFalse)
6879 PUSHs(&sv_undef);
6880 else
6881 {
6882 EXTEND(sp,strlen(map)*region.width*region.height);
6883 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6884 PUSHs(sv_2mortal(newSVnv(pixels[i])));
6885 }
6886 pixels=(float *) RelinquishMagickMemory(pixels);
6887 }
6888 else
6889 {
6890 Quantum
6891 *pixels;
6892
6893 pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
6894 region.height*sizeof(*pixels));
6895 if (pixels == (Quantum *) NULL)
6896 {
6897 ThrowPerlException(exception,ResourceLimitError,
6898 "MemoryAllocationFailed",PackageName);
6899 goto PerlException;
6900 }
6901 status=ExportImagePixels(image,region.x,region.y,region.width,
6902 region.height,map,QuantumPixel,pixels,exception);
6903 if (status == MagickFalse)
6904 PUSHs(&sv_undef);
6905 else
6906 {
6907 EXTEND(sp,strlen(map)*region.width*region.height);
6908 for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
6909 PUSHs(sv_2mortal(newSViv(pixels[i])));
6910 }
6911 pixels=(Quantum *) RelinquishMagickMemory(pixels);
6912 }
6913
6914 PerlException:
6915 InheritPerlException(exception,perl_exception);
6916 exception=DestroyExceptionInfo(exception);
6917 SvREFCNT_dec(perl_exception);
6918 }
6919
6920#
6921###############################################################################
6922# #
6923# #
6924# #
6925# I m a g e T o B l o b #
6926# #
6927# #
6928# #
6929###############################################################################
6930#
6931#
6932void
6933ImageToBlob(ref,...)
6934 Image::Magick ref=NO_INIT
6935 ALIAS:
6936 ImageToBlob = 1
6937 imagetoblob = 2
6938 toblob = 3
6939 blob = 4
6940 PPCODE:
6941 {
6942 char
cristy151b66d2015-04-15 10:50:31 +00006943 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00006944
6945 ExceptionInfo
6946 *exception;
6947
6948 Image
6949 *image,
6950 *next;
6951
6952 register ssize_t
6953 i;
6954
6955 struct PackageInfo
6956 *info,
6957 *package_info;
6958
6959 size_t
6960 length;
6961
6962 ssize_t
6963 scene;
6964
6965 SV
6966 *perl_exception,
6967 *reference;
6968
6969 void
6970 *blob;
6971
6972 PERL_UNUSED_VAR(ref);
6973 PERL_UNUSED_VAR(ix);
6974 exception=AcquireExceptionInfo();
6975 perl_exception=newSVpv("",0);
6976 package_info=(struct PackageInfo *) NULL;
6977 if (sv_isobject(ST(0)) == 0)
6978 {
6979 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
6980 PackageName);
6981 goto PerlException;
6982 }
6983 reference=SvRV(ST(0));
6984 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
6985 if (image == (Image *) NULL)
6986 {
6987 ThrowPerlException(exception,OptionError,"NoImagesDefined",
6988 PackageName);
6989 goto PerlException;
6990 }
6991 package_info=ClonePackageInfo(info,exception);
6992 for (i=2; i < items; i+=2)
6993 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
6994 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +00006995 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00006996 scene=0;
6997 for (next=image; next; next=next->next)
6998 {
cristy151b66d2015-04-15 10:50:31 +00006999 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +00007000 next->scene=scene++;
7001 }
7002 SetImageInfo(package_info->image_info,(unsigned int)
7003 GetImageListLength(image),exception);
7004 EXTEND(sp,(ssize_t) GetImageListLength(image));
7005 for ( ; image; image=image->next)
7006 {
7007 length=0;
7008 blob=ImagesToBlob(package_info->image_info,image,&length,exception);
7009 if (blob != (char *) NULL)
7010 {
7011 PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
7012 blob=(unsigned char *) RelinquishMagickMemory(blob);
7013 }
7014 if (package_info->image_info->adjoin)
7015 break;
7016 }
7017
7018 PerlException:
7019 if (package_info != (struct PackageInfo *) NULL)
7020 DestroyPackageInfo(package_info);
7021 InheritPerlException(exception,perl_exception);
7022 exception=DestroyExceptionInfo(exception);
7023 SvREFCNT_dec(perl_exception); /* throw away all errors */
7024 }
7025
7026#
7027###############################################################################
7028# #
7029# #
7030# #
7031# L a y e r s #
7032# #
7033# #
7034# #
7035###############################################################################
7036#
7037#
7038void
7039Layers(ref,...)
7040 Image::Magick ref=NO_INIT
7041 ALIAS:
7042 Layers = 1
7043 layers = 2
7044 OptimizeImageLayers = 3
7045 optimizelayers = 4
7046 optimizeimagelayers = 5
7047 PPCODE:
7048 {
7049 AV
7050 *av;
7051
7052 char
7053 *attribute;
7054
7055 CompositeOperator
7056 compose;
7057
7058 ExceptionInfo
7059 *exception;
7060
7061 HV
7062 *hv;
7063
7064 Image
7065 *image,
7066 *layers;
7067
7068 LayerMethod
7069 method;
7070
7071 register ssize_t
7072 i;
7073
7074 ssize_t
7075 option,
7076 sp;
7077
7078 struct PackageInfo
7079 *info;
7080
7081 SV
7082 *av_reference,
7083 *perl_exception,
7084 *reference,
7085 *rv,
7086 *sv;
7087
7088 PERL_UNUSED_VAR(ref);
7089 PERL_UNUSED_VAR(ix);
7090 exception=AcquireExceptionInfo();
7091 perl_exception=newSVpv("",0);
7092 sv=NULL;
7093 if (sv_isobject(ST(0)) == 0)
7094 {
7095 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7096 PackageName);
7097 goto PerlException;
7098 }
7099 reference=SvRV(ST(0));
7100 hv=SvSTASH(reference);
7101 av=newAV();
7102 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
7103 SvREFCNT_dec(av);
7104 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
7105 if (image == (Image *) NULL)
7106 {
7107 ThrowPerlException(exception,OptionError,"NoImagesDefined",
7108 PackageName);
7109 goto PerlException;
7110 }
7111 compose=image->compose;
7112 method=OptimizeLayer;
7113 for (i=2; i < items; i+=2)
7114 {
7115 attribute=(char *) SvPV(ST(i-1),na);
7116 switch (*attribute)
7117 {
7118 case 'C':
7119 case 'c':
7120 {
7121 if (LocaleCompare(attribute,"compose") == 0)
7122 {
7123 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
7124 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
7125 if (sp < 0)
7126 {
7127 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7128 SvPV(ST(i),na));
7129 break;
7130 }
7131 compose=(CompositeOperator) sp;
7132 break;
7133 }
7134 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7135 attribute);
7136 break;
7137 }
7138 case 'M':
7139 case 'm':
7140 {
7141 if (LocaleCompare(attribute,"method") == 0)
7142 {
7143 option=ParseCommandOption(MagickLayerOptions,MagickFalse,
7144 SvPV(ST(i),na));
7145 if (option < 0)
7146 {
7147 ThrowPerlException(exception,OptionError,"UnrecognizedType",
7148 SvPV(ST(i),na));
7149 break;
7150 }
7151 method=(LayerMethod) option;
7152 break;
7153 }
7154 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7155 attribute);
7156 break;
7157 }
7158 default:
7159 {
7160 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
7161 attribute);
7162 break;
7163 }
7164 }
7165 }
7166 layers=(Image *) NULL;
7167 switch (method)
7168 {
7169 case CompareAnyLayer:
7170 case CompareClearLayer:
7171 case CompareOverlayLayer:
7172 default:
7173 {
7174 layers=CompareImagesLayers(image,method,exception);
7175 break;
7176 }
7177 case MergeLayer:
7178 case FlattenLayer:
7179 case MosaicLayer:
7180 {
7181 layers=MergeImageLayers(image,method,exception);
7182 break;
7183 }
7184 case DisposeLayer:
7185 {
7186 layers=DisposeImages(image,exception);
7187 break;
7188 }
7189 case OptimizeImageLayer:
7190 {
7191 layers=OptimizeImageLayers(image,exception);
7192 break;
7193 }
7194 case OptimizePlusLayer:
7195 {
7196 layers=OptimizePlusImageLayers(image,exception);
7197 break;
7198 }
7199 case OptimizeTransLayer:
7200 {
7201 OptimizeImageTransparency(image,exception);
7202 break;
7203 }
7204 case RemoveDupsLayer:
7205 {
7206 RemoveDuplicateLayers(&image,exception);
7207 break;
7208 }
7209 case RemoveZeroLayer:
7210 {
7211 RemoveZeroDelayLayers(&image,exception);
7212 break;
7213 }
7214 case OptimizeLayer:
7215 {
7216 QuantizeInfo
7217 *quantize_info;
7218
7219 /*
7220 General Purpose, GIF Animation Optimizer.
7221 */
7222 layers=CoalesceImages(image,exception);
7223 if (layers == (Image *) NULL)
7224 break;
7225 image=layers;
7226 layers=OptimizeImageLayers(image,exception);
7227 if (layers == (Image *) NULL)
7228 break;
7229 image=DestroyImageList(image);
7230 image=layers;
7231 layers=(Image *) NULL;
7232 OptimizeImageTransparency(image,exception);
7233 quantize_info=AcquireQuantizeInfo(info->image_info);
7234 (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
7235 quantize_info=DestroyQuantizeInfo(quantize_info);
7236 break;
7237 }
7238 case CompositeLayer:
7239 {
7240 Image
7241 *source;
7242
7243 RectangleInfo
7244 geometry;
7245
7246 /*
7247 Split image sequence at the first 'NULL:' image.
7248 */
7249 source=image;
7250 while (source != (Image *) NULL)
7251 {
7252 source=GetNextImageInList(source);
7253 if ((source != (Image *) NULL) &&
7254 (LocaleCompare(source->magick,"NULL") == 0))
7255 break;
7256 }
7257 if (source != (Image *) NULL)
7258 {
7259 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7260 (GetNextImageInList(source) == (Image *) NULL))
7261 source=(Image *) NULL;
7262 else
7263 {
7264 /*
7265 Separate the two lists, junk the null: image.
7266 */
7267 source=SplitImageList(source->previous);
7268 DeleteImageFromList(&source);
7269 }
7270 }
7271 if (source == (Image *) NULL)
7272 {
7273 (void) ThrowMagickException(exception,GetMagickModule(),
7274 OptionError,"MissingNullSeparator","layers Composite");
7275 break;
7276 }
7277 /*
7278 Adjust offset with gravity and virtual canvas.
7279 */
7280 SetGeometry(image,&geometry);
7281 (void) ParseAbsoluteGeometry(image->geometry,&geometry);
7282 geometry.width=source->page.width != 0 ? source->page.width :
7283 source->columns;
7284 geometry.height=source->page.height != 0 ? source->page.height :
7285 source->rows;
7286 GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
7287 image->columns,image->page.height != 0 ? image->page.height :
7288 image->rows,image->gravity,&geometry);
7289 CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
7290 source=DestroyImageList(source);
7291 break;
7292 }
7293 }
7294 if (layers != (Image *) NULL)
7295 image=layers;
cristy83a28a02013-08-03 20:25:48 +00007296 else
7297 image=CloneImage(image,0,0,MagickTrue,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007298 if (image == (Image *) NULL)
7299 goto PerlException;
7300 for ( ; image; image=image->next)
7301 {
7302 AddImageToRegistry(sv,image);
7303 rv=newRV(sv);
7304 av_push(av,sv_bless(rv,hv));
7305 SvREFCNT_dec(sv);
7306 }
7307 exception=DestroyExceptionInfo(exception);
7308 ST(0)=av_reference;
7309 SvREFCNT_dec(perl_exception);
7310 XSRETURN(1);
7311
7312 PerlException:
7313 InheritPerlException(exception,perl_exception);
7314 exception=DestroyExceptionInfo(exception);
7315 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
7316 SvPOK_on(perl_exception);
7317 ST(0)=sv_2mortal(perl_exception);
7318 XSRETURN(1);
7319 }
7320
7321#
7322###############################################################################
7323# #
7324# #
7325# #
7326# M a g i c k T o M i m e #
7327# #
7328# #
7329# #
7330###############################################################################
7331#
7332#
7333SV *
7334MagickToMime(ref,name)
7335 Image::Magick ref=NO_INIT
7336 char *name
7337 ALIAS:
7338 magicktomime = 1
7339 CODE:
7340 {
7341 char
7342 *mime;
7343
7344 PERL_UNUSED_VAR(ref);
7345 PERL_UNUSED_VAR(ix);
7346 mime=MagickToMime(name);
7347 RETVAL=newSVpv(mime,0);
7348 mime=(char *) RelinquishMagickMemory(mime);
7349 }
7350 OUTPUT:
7351 RETVAL
7352
7353#
7354###############################################################################
7355# #
7356# #
7357# #
7358# M o g r i f y #
7359# #
7360# #
7361# #
7362###############################################################################
7363#
7364#
7365void
7366Mogrify(ref,...)
7367 Image::Magick ref=NO_INIT
7368 ALIAS:
7369 Comment = 1
7370 CommentImage = 2
7371 Label = 3
7372 LabelImage = 4
7373 AddNoise = 5
7374 AddNoiseImage = 6
7375 Colorize = 7
7376 ColorizeImage = 8
7377 Border = 9
7378 BorderImage = 10
7379 Blur = 11
7380 BlurImage = 12
7381 Chop = 13
7382 ChopImage = 14
7383 Crop = 15
7384 CropImage = 16
7385 Despeckle = 17
7386 DespeckleImage = 18
7387 Edge = 19
7388 EdgeImage = 20
7389 Emboss = 21
7390 EmbossImage = 22
7391 Enhance = 23
7392 EnhanceImage = 24
7393 Flip = 25
7394 FlipImage = 26
7395 Flop = 27
7396 FlopImage = 28
7397 Frame = 29
7398 FrameImage = 30
7399 Implode = 31
7400 ImplodeImage = 32
7401 Magnify = 33
7402 MagnifyImage = 34
7403 MedianFilter = 35
7404 MedianConvolveImage = 36
7405 Minify = 37
7406 MinifyImage = 38
7407 OilPaint = 39
7408 OilPaintImage = 40
7409 ReduceNoise = 41
7410 ReduceNoiseImage = 42
7411 Roll = 43
7412 RollImage = 44
7413 Rotate = 45
7414 RotateImage = 46
7415 Sample = 47
7416 SampleImage = 48
7417 Scale = 49
7418 ScaleImage = 50
7419 Shade = 51
7420 ShadeImage = 52
7421 Sharpen = 53
7422 SharpenImage = 54
7423 Shear = 55
7424 ShearImage = 56
7425 Spread = 57
7426 SpreadImage = 58
7427 Swirl = 59
7428 SwirlImage = 60
7429 Resize = 61
7430 ResizeImage = 62
7431 Zoom = 63
7432 ZoomImage = 64
7433 Annotate = 65
7434 AnnotateImage = 66
7435 ColorFloodfill = 67
7436 ColorFloodfillImage= 68
7437 Composite = 69
7438 CompositeImage = 70
7439 Contrast = 71
7440 ContrastImage = 72
7441 CycleColormap = 73
7442 CycleColormapImage = 74
7443 Draw = 75
7444 DrawImage = 76
7445 Equalize = 77
7446 EqualizeImage = 78
7447 Gamma = 79
7448 GammaImage = 80
7449 Map = 81
7450 MapImage = 82
7451 MatteFloodfill = 83
7452 MatteFloodfillImage= 84
7453 Modulate = 85
7454 ModulateImage = 86
7455 Negate = 87
7456 NegateImage = 88
7457 Normalize = 89
7458 NormalizeImage = 90
7459 NumberColors = 91
7460 NumberColorsImage = 92
7461 Opaque = 93
7462 OpaqueImage = 94
7463 Quantize = 95
7464 QuantizeImage = 96
7465 Raise = 97
7466 RaiseImage = 98
7467 Segment = 99
7468 SegmentImage = 100
7469 Signature = 101
7470 SignatureImage = 102
7471 Solarize = 103
7472 SolarizeImage = 104
7473 Sync = 105
7474 SyncImage = 106
7475 Texture = 107
7476 TextureImage = 108
7477 Evaluate = 109
7478 EvaluateImage = 110
7479 Transparent = 111
7480 TransparentImage = 112
7481 Threshold = 113
7482 ThresholdImage = 114
7483 Charcoal = 115
7484 CharcoalImage = 116
7485 Trim = 117
7486 TrimImage = 118
7487 Wave = 119
7488 WaveImage = 120
7489 Separate = 121
7490 SeparateImage = 122
7491 Stereo = 125
7492 StereoImage = 126
7493 Stegano = 127
7494 SteganoImage = 128
7495 Deconstruct = 129
7496 DeconstructImage = 130
7497 GaussianBlur = 131
7498 GaussianBlurImage = 132
7499 Convolve = 133
7500 ConvolveImage = 134
7501 Profile = 135
7502 ProfileImage = 136
7503 UnsharpMask = 137
7504 UnsharpMaskImage = 138
7505 MotionBlur = 139
7506 MotionBlurImage = 140
7507 OrderedDither = 141
7508 OrderedDitherImage = 142
7509 Shave = 143
7510 ShaveImage = 144
7511 Level = 145
7512 LevelImage = 146
7513 Clip = 147
7514 ClipImage = 148
7515 AffineTransform = 149
7516 AffineTransformImage = 150
7517 Difference = 151
7518 DifferenceImage = 152
7519 AdaptiveThreshold = 153
7520 AdaptiveThresholdImage = 154
7521 Resample = 155
7522 ResampleImage = 156
7523 Describe = 157
7524 DescribeImage = 158
7525 BlackThreshold = 159
7526 BlackThresholdImage= 160
7527 WhiteThreshold = 161
7528 WhiteThresholdImage= 162
cristy60c73c02014-03-25 12:09:58 +00007529 RotationalBlur = 163
7530 RotationalBlurImage= 164
cristy4a3ce0a2013-08-03 20:06:59 +00007531 Thumbnail = 165
7532 ThumbnailImage = 166
7533 Strip = 167
7534 StripImage = 168
7535 Tint = 169
7536 TintImage = 170
7537 Channel = 171
7538 ChannelImage = 172
7539 Splice = 173
7540 SpliceImage = 174
7541 Posterize = 175
7542 PosterizeImage = 176
7543 Shadow = 177
7544 ShadowImage = 178
7545 Identify = 179
7546 IdentifyImage = 180
7547 SepiaTone = 181
7548 SepiaToneImage = 182
7549 SigmoidalContrast = 183
7550 SigmoidalContrastImage = 184
7551 Extent = 185
7552 ExtentImage = 186
7553 Vignette = 187
7554 VignetteImage = 188
7555 ContrastStretch = 189
7556 ContrastStretchImage = 190
7557 Sans0 = 191
7558 Sans0Image = 192
7559 Sans1 = 193
7560 Sans1Image = 194
7561 AdaptiveSharpen = 195
7562 AdaptiveSharpenImage = 196
7563 Transpose = 197
7564 TransposeImage = 198
7565 Transverse = 199
7566 TransverseImage = 200
7567 AutoOrient = 201
7568 AutoOrientImage = 202
7569 AdaptiveBlur = 203
7570 AdaptiveBlurImage = 204
7571 Sketch = 205
7572 SketchImage = 206
7573 UniqueColors = 207
7574 UniqueColorsImage = 208
7575 AdaptiveResize = 209
7576 AdaptiveResizeImage= 210
7577 ClipMask = 211
7578 ClipMaskImage = 212
7579 LinearStretch = 213
7580 LinearStretchImage = 214
7581 ColorMatrix = 215
7582 ColorMatrixImage = 216
7583 Mask = 217
7584 MaskImage = 218
7585 Polaroid = 219
7586 PolaroidImage = 220
7587 FloodfillPaint = 221
7588 FloodfillPaintImage= 222
7589 Distort = 223
7590 DistortImage = 224
7591 Clut = 225
7592 ClutImage = 226
7593 LiquidRescale = 227
7594 LiquidRescaleImage = 228
7595 Encipher = 229
7596 EncipherImage = 230
7597 Decipher = 231
7598 DecipherImage = 232
7599 Deskew = 233
7600 DeskewImage = 234
7601 Remap = 235
7602 RemapImage = 236
7603 SparseColor = 237
7604 SparseColorImage = 238
7605 Function = 239
7606 FunctionImage = 240
7607 SelectiveBlur = 241
7608 SelectiveBlurImage = 242
7609 HaldClut = 243
7610 HaldClutImage = 244
7611 BlueShift = 245
7612 BlueShiftImage = 246
7613 ForwardFourierTransform = 247
7614 ForwardFourierTransformImage = 248
7615 InverseFourierTransform = 249
7616 InverseFourierTransformImage = 250
7617 ColorDecisionList = 251
7618 ColorDecisionListImage = 252
7619 AutoGamma = 253
7620 AutoGammaImage = 254
7621 AutoLevel = 255
7622 AutoLevelImage = 256
7623 LevelColors = 257
7624 LevelImageColors = 258
7625 Clamp = 259
7626 ClampImage = 260
7627 BrightnessContrast = 261
7628 BrightnessContrastImage = 262
7629 Morphology = 263
7630 MorphologyImage = 264
Cristy3ca633e2016-02-13 12:49:01 -05007631 Mode = 265
7632 ModeImage = 266
7633 Statistic = 267
7634 StatisticImage = 268
7635 Perceptible = 269
7636 PerceptibleImage = 270
7637 Poly = 271
7638 PolyImage = 272
7639 Grayscale = 273
7640 GrayscaleImage = 274
7641 CannyEdge = 275
7642 CannyEdgeImage = 276
7643 HoughLine = 277
7644 HoughLineImage = 278
7645 MeanShift = 279
7646 MeanShiftImage = 280
7647 Kuwahara = 281
7648 KuwaharaImage = 282
Cristy0f5df812017-07-04 18:30:05 -04007649 ConnectedComponents = 283
7650 ConnectedComponentsImage = 284
Cristy3ca633e2016-02-13 12:49:01 -05007651 CopyPixels = 285
7652 CopyImagePixels = 286
Cristy5488c982016-02-13 14:07:50 -05007653 Color = 287
7654 ColorImage = 288
Cristy2d830ed2016-02-21 10:54:16 -05007655 WaveletDenoise = 289
7656 WaveletDenoiseImage= 290
Cristy99a57162016-12-05 11:47:57 -05007657 Colorspace = 291
7658 ColorspaceImage = 292
Cristy53353872017-07-02 12:24:24 -04007659 AutoThreshold = 293
7660 AutoThresholdImage = 294
Cristy532b3382018-08-05 17:56:56 -04007661 RangeThreshold = 295
7662 RangeThresholdImage= 296
Cristy9f252542018-11-21 19:13:46 -05007663 CLAHE = 297
7664 CLAHEImage = 298
Cristyb4ab5192019-12-19 06:53:46 -05007665 Kmeans = 299
7666 KMeansImage = 300
Cristy89b4db02020-02-21 20:57:40 -05007667 ColorThreshold = 301
7668 ColorThresholdImage= 302
cristy4a3ce0a2013-08-03 20:06:59 +00007669 MogrifyRegion = 666
7670 PPCODE:
7671 {
7672 AffineMatrix
7673 affine,
7674 current;
7675
7676 char
7677 attribute_flag[MaxArguments],
cristy151b66d2015-04-15 10:50:31 +00007678 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00007679
7680 ChannelType
7681 channel,
7682 channel_mask;
7683
7684 CompositeOperator
7685 compose;
7686
7687 const char
7688 *attribute,
7689 *value;
7690
7691 double
7692 angle;
7693
7694 ExceptionInfo
7695 *exception;
7696
7697 GeometryInfo
7698 geometry_info;
7699
7700 Image
7701 *image,
Cristy7e567962018-02-03 12:42:20 -05007702 *next;
cristy4a3ce0a2013-08-03 20:06:59 +00007703
cristy4a3ce0a2013-08-03 20:06:59 +00007704 MagickStatusType
7705 flags;
7706
7707 PixelInfo
7708 fill_color;
7709
7710 RectangleInfo
7711 geometry,
7712 region_info;
7713
7714 register ssize_t
7715 i;
7716
7717 ssize_t
7718 base,
7719 j,
7720 number_images;
7721
7722 struct Methods
7723 *rp;
7724
7725 struct PackageInfo
7726 *info;
7727
7728 SV
7729 *perl_exception,
7730 **pv,
7731 *reference,
7732 **reference_vector;
7733
7734 struct ArgumentList
7735 argument_list[MaxArguments];
7736
7737 PERL_UNUSED_VAR(ref);
7738 PERL_UNUSED_VAR(ix);
7739 exception=AcquireExceptionInfo();
7740 perl_exception=newSVpv("",0);
7741 reference_vector=NULL;
cristy4a3ce0a2013-08-03 20:06:59 +00007742 number_images=0;
7743 base=2;
7744 if (sv_isobject(ST(0)) == 0)
7745 {
7746 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7747 PackageName);
7748 goto PerlException;
7749 }
7750 reference=SvRV(ST(0));
7751 region_info.width=0;
7752 region_info.height=0;
7753 region_info.x=0;
7754 region_info.y=0;
cristy4a3ce0a2013-08-03 20:06:59 +00007755 image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
7756 if (ix && (ix != 666))
7757 {
7758 /*
7759 Called as Method(...)
7760 */
7761 ix=(ix+1)/2;
7762 rp=(&Methods[ix-1]);
7763 attribute=rp->name;
7764 }
7765 else
7766 {
7767 /*
7768 Called as Mogrify("Method",...)
7769 */
7770 attribute=(char *) SvPV(ST(1),na);
7771 if (ix)
7772 {
7773 flags=ParseGravityGeometry(image,attribute,&region_info,exception);
7774 attribute=(char *) SvPV(ST(2),na);
7775 base++;
7776 }
7777 for (rp=Methods; ; rp++)
7778 {
7779 if (rp >= EndOf(Methods))
7780 {
7781 ThrowPerlException(exception,OptionError,
7782 "UnrecognizedPerlMagickMethod",attribute);
7783 goto PerlException;
7784 }
7785 if (strEQcase(attribute,rp->name))
7786 break;
7787 }
7788 ix=rp-Methods+1;
7789 base++;
7790 }
7791 if (image == (Image *) NULL)
7792 {
7793 ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
7794 goto PerlException;
7795 }
7796 Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
7797 Zero(&attribute_flag,NumberOf(attribute_flag),char);
7798 for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
7799 {
7800 Arguments
7801 *pp,
7802 *qq;
7803
7804 ssize_t
7805 ssize_test;
7806
7807 struct ArgumentList
7808 *al;
7809
7810 SV
7811 *sv;
7812
7813 sv=NULL;
7814 ssize_test=0;
7815 pp=(Arguments *) NULL;
7816 qq=rp->arguments;
7817 if (i == items)
7818 {
7819 pp=rp->arguments,
7820 sv=ST(i-1);
7821 }
7822 else
7823 for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
7824 {
7825 if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
7826 break;
7827 if (strEQcase(attribute,qq->method) > ssize_test)
7828 {
7829 pp=qq;
7830 ssize_test=strEQcase(attribute,qq->method);
7831 }
7832 }
7833 if (pp == (Arguments *) NULL)
7834 {
7835 ThrowPerlException(exception,OptionError,"UnrecognizedOption",
7836 attribute);
7837 goto continue_outer_loop;
7838 }
7839 al=(&argument_list[pp-rp->arguments]);
7840 switch (pp->type)
7841 {
7842 case ArrayReference:
7843 {
7844 if (SvTYPE(sv) != SVt_RV)
7845 {
cristy151b66d2015-04-15 10:50:31 +00007846 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007847 "invalid %.60s value",pp->method);
7848 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7849 goto continue_outer_loop;
7850 }
7851 al->array_reference=SvRV(sv);
7852 break;
7853 }
7854 case RealReference:
7855 {
7856 al->real_reference=SvNV(sv);
7857 break;
7858 }
7859 case FileReference:
7860 {
7861 al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
7862 break;
7863 }
7864 case ImageReference:
7865 {
7866 if (!sv_isobject(sv) ||
7867 !(al->image_reference=SetupList(aTHX_ SvRV(sv),
7868 (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
7869 {
7870 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
7871 PackageName);
7872 goto PerlException;
7873 }
7874 break;
7875 }
7876 case IntegerReference:
7877 {
7878 al->integer_reference=SvIV(sv);
7879 break;
7880 }
7881 case StringReference:
7882 {
7883 al->string_reference=(char *) SvPV(sv,al->length);
7884 if (sv_isobject(sv))
7885 al->image_reference=SetupList(aTHX_ SvRV(sv),
7886 (struct PackageInfo **) NULL,(SV ***) NULL,exception);
7887 break;
7888 }
7889 default:
7890 {
7891 /*
7892 Is a string; look up name.
7893 */
7894 if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
7895 {
7896 al->string_reference=(char *) SvPV(sv,al->length);
7897 al->integer_reference=(-1);
7898 break;
7899 }
7900 al->integer_reference=ParseCommandOption((CommandOption) pp->type,
7901 MagickFalse,SvPV(sv,na));
7902 if (pp->type == MagickChannelOptions)
7903 al->integer_reference=ParseChannelOption(SvPV(sv,na));
7904 if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
7905 {
cristy151b66d2015-04-15 10:50:31 +00007906 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00007907 "invalid %.60s value",pp->method);
7908 ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
7909 goto continue_outer_loop;
7910 }
7911 break;
7912 }
7913 }
7914 attribute_flag[pp-rp->arguments]++;
7915 continue_outer_loop: ;
7916 }
7917 (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
7918 pv=reference_vector;
7919 SetGeometryInfo(&geometry_info);
7920 channel=DefaultChannels;
7921 for (next=image; next; next=next->next)
7922 {
7923 image=next;
7924 SetGeometry(image,&geometry);
7925 if ((region_info.width*region_info.height) != 0)
Cristy7e567962018-02-03 12:42:20 -05007926 (void) SetImageRegionMask(image,WritePixelMask,&region_info,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007927 switch (ix)
7928 {
7929 default:
7930 {
cristy151b66d2015-04-15 10:50:31 +00007931 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double) ix);
cristy4a3ce0a2013-08-03 20:06:59 +00007932 ThrowPerlException(exception,OptionError,
7933 "UnrecognizedPerlMagickMethod",message);
7934 goto PerlException;
7935 }
7936 case 1: /* Comment */
7937 {
7938 if (attribute_flag[0] == 0)
7939 argument_list[0].string_reference=(char *) NULL;
Cristy935a4052017-03-31 17:45:37 -04007940 (void) SetImageProperty(image,"comment",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00007941 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04007942 argument_list[0].string_reference,exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007943 break;
7944 }
7945 case 2: /* Label */
7946 {
7947 if (attribute_flag[0] == 0)
7948 argument_list[0].string_reference=(char *) NULL;
Cristy935a4052017-03-31 17:45:37 -04007949 (void) SetImageProperty(image,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +00007950 info ? info->image_info : (ImageInfo *) NULL,image,
Cristy935a4052017-03-31 17:45:37 -04007951 argument_list[0].string_reference,exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +00007952 break;
7953 }
7954 case 3: /* AddNoise */
7955 {
7956 double
7957 attenuate;
7958
7959 if (attribute_flag[0] == 0)
7960 argument_list[0].integer_reference=UniformNoise;
7961 attenuate=1.0;
7962 if (attribute_flag[1] != 0)
7963 attenuate=argument_list[1].real_reference;
7964 if (attribute_flag[2] != 0)
7965 channel=(ChannelType) argument_list[2].integer_reference;
7966 channel_mask=SetImageChannelMask(image,channel);
7967 image=AddNoiseImage(image,(NoiseType)
7968 argument_list[0].integer_reference,attenuate,exception);
7969 if (image != (Image *) NULL)
7970 (void) SetImageChannelMask(image,channel_mask);
7971 break;
7972 }
7973 case 4: /* Colorize */
7974 {
7975 PixelInfo
7976 target;
7977
7978 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
7979 0,0,&target,exception);
7980 if (attribute_flag[0] != 0)
7981 (void) QueryColorCompliance(argument_list[0].string_reference,
7982 AllCompliance,&target,exception);
7983 if (attribute_flag[1] == 0)
7984 argument_list[1].string_reference="100%";
7985 image=ColorizeImage(image,argument_list[1].string_reference,&target,
7986 exception);
7987 break;
7988 }
7989 case 5: /* Border */
7990 {
7991 CompositeOperator
7992 compose;
7993
7994 geometry.width=0;
7995 geometry.height=0;
7996 if (attribute_flag[0] != 0)
7997 flags=ParsePageGeometry(image,argument_list[0].string_reference,
7998 &geometry,exception);
7999 if (attribute_flag[1] != 0)
8000 geometry.width=argument_list[1].integer_reference;
8001 if (attribute_flag[2] != 0)
8002 geometry.height=argument_list[2].integer_reference;
8003 if (attribute_flag[3] != 0)
8004 QueryColorCompliance(argument_list[3].string_reference,
8005 AllCompliance,&image->border_color,exception);
8006 if (attribute_flag[4] != 0)
8007 QueryColorCompliance(argument_list[4].string_reference,
8008 AllCompliance,&image->border_color,exception);
8009 if (attribute_flag[5] != 0)
8010 QueryColorCompliance(argument_list[5].string_reference,
8011 AllCompliance,&image->border_color,exception);
8012 compose=image->compose;
8013 if (attribute_flag[6] != 0)
8014 compose=(CompositeOperator) argument_list[6].integer_reference;
8015 image=BorderImage(image,&geometry,compose,exception);
8016 break;
8017 }
8018 case 6: /* Blur */
8019 {
8020 if (attribute_flag[0] != 0)
8021 {
8022 flags=ParseGeometry(argument_list[0].string_reference,
8023 &geometry_info);
8024 if ((flags & SigmaValue) == 0)
8025 geometry_info.sigma=1.0;
8026 }
8027 if (attribute_flag[1] != 0)
8028 geometry_info.rho=argument_list[1].real_reference;
8029 if (attribute_flag[2] != 0)
8030 geometry_info.sigma=argument_list[2].real_reference;
8031 if (attribute_flag[3] != 0)
8032 channel=(ChannelType) argument_list[3].integer_reference;
8033 channel_mask=SetImageChannelMask(image,channel);
8034 image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
8035 exception);
8036 if (image != (Image *) NULL)
8037 (void) SetImageChannelMask(image,channel_mask);
8038 break;
8039 }
8040 case 7: /* Chop */
8041 {
cristy260bd762014-08-15 12:46:34 +00008042 if (attribute_flag[5] != 0)
8043 image->gravity=(GravityType) argument_list[5].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00008044 if (attribute_flag[0] != 0)
8045 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
8046 &geometry,exception);
8047 if (attribute_flag[1] != 0)
8048 geometry.width=argument_list[1].integer_reference;
8049 if (attribute_flag[2] != 0)
8050 geometry.height=argument_list[2].integer_reference;
8051 if (attribute_flag[3] != 0)
8052 geometry.x=argument_list[3].integer_reference;
8053 if (attribute_flag[4] != 0)
8054 geometry.y=argument_list[4].integer_reference;
8055 image=ChopImage(image,&geometry,exception);
8056 break;
8057 }
8058 case 8: /* Crop */
8059 {
8060 if (attribute_flag[6] != 0)
8061 image->gravity=(GravityType) argument_list[6].integer_reference;
8062 if (attribute_flag[0] != 0)
8063 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
8064 &geometry,exception);
8065 if (attribute_flag[1] != 0)
8066 geometry.width=argument_list[1].integer_reference;
8067 if (attribute_flag[2] != 0)
8068 geometry.height=argument_list[2].integer_reference;
8069 if (attribute_flag[3] != 0)
8070 geometry.x=argument_list[3].integer_reference;
8071 if (attribute_flag[4] != 0)
8072 geometry.y=argument_list[4].integer_reference;
8073 if (attribute_flag[5] != 0)
8074 image->fuzz=StringToDoubleInterval(
8075 argument_list[5].string_reference,(double) QuantumRange+1.0);
8076 image=CropImage(image,&geometry,exception);
8077 break;
8078 }
8079 case 9: /* Despeckle */
8080 {
8081 image=DespeckleImage(image,exception);
8082 break;
8083 }
8084 case 10: /* Edge */
8085 {
8086 if (attribute_flag[0] != 0)
8087 geometry_info.rho=argument_list[0].real_reference;
8088 image=EdgeImage(image,geometry_info.rho,exception);
8089 break;
8090 }
8091 case 11: /* Emboss */
8092 {
8093 if (attribute_flag[0] != 0)
8094 {
8095 flags=ParseGeometry(argument_list[0].string_reference,
8096 &geometry_info);
8097 if ((flags & SigmaValue) == 0)
8098 geometry_info.sigma=1.0;
8099 }
8100 if (attribute_flag[1] != 0)
8101 geometry_info.rho=argument_list[1].real_reference;
8102 if (attribute_flag[2] != 0)
8103 geometry_info.sigma=argument_list[2].real_reference;
8104 image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
8105 exception);
8106 break;
8107 }
8108 case 12: /* Enhance */
8109 {
8110 image=EnhanceImage(image,exception);
8111 break;
8112 }
8113 case 13: /* Flip */
8114 {
8115 image=FlipImage(image,exception);
8116 break;
8117 }
8118 case 14: /* Flop */
8119 {
8120 image=FlopImage(image,exception);
8121 break;
8122 }
8123 case 15: /* Frame */
8124 {
8125 CompositeOperator
8126 compose;
8127
8128 FrameInfo
8129 frame_info;
8130
8131 if (attribute_flag[0] != 0)
8132 {
8133 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8134 &geometry,exception);
8135 frame_info.width=geometry.width;
8136 frame_info.height=geometry.height;
8137 frame_info.outer_bevel=geometry.x;
8138 frame_info.inner_bevel=geometry.y;
8139 }
8140 if (attribute_flag[1] != 0)
8141 frame_info.width=argument_list[1].integer_reference;
8142 if (attribute_flag[2] != 0)
8143 frame_info.height=argument_list[2].integer_reference;
8144 if (attribute_flag[3] != 0)
8145 frame_info.inner_bevel=argument_list[3].integer_reference;
8146 if (attribute_flag[4] != 0)
8147 frame_info.outer_bevel=argument_list[4].integer_reference;
8148 if (attribute_flag[5] != 0)
8149 QueryColorCompliance(argument_list[5].string_reference,
8150 AllCompliance,&fill_color,exception);
8151 if (attribute_flag[6] != 0)
8152 QueryColorCompliance(argument_list[6].string_reference,
8153 AllCompliance,&fill_color,exception);
8154 frame_info.x=(ssize_t) frame_info.width;
8155 frame_info.y=(ssize_t) frame_info.height;
8156 frame_info.width=image->columns+2*frame_info.x;
8157 frame_info.height=image->rows+2*frame_info.y;
8158 if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
Cristy8645e042016-02-03 16:35:29 -05008159 image->alpha_color=fill_color;
cristy4a3ce0a2013-08-03 20:06:59 +00008160 compose=image->compose;
8161 if (attribute_flag[7] != 0)
8162 compose=(CompositeOperator) argument_list[7].integer_reference;
8163 image=FrameImage(image,&frame_info,compose,exception);
8164 break;
8165 }
8166 case 16: /* Implode */
8167 {
8168 PixelInterpolateMethod
8169 method;
8170
8171 if (attribute_flag[0] == 0)
8172 argument_list[0].real_reference=0.5;
8173 method=UndefinedInterpolatePixel;
8174 if (attribute_flag[1] != 0)
8175 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8176 image=ImplodeImage(image,argument_list[0].real_reference,
8177 method,exception);
8178 break;
8179 }
8180 case 17: /* Magnify */
8181 {
8182 image=MagnifyImage(image,exception);
8183 break;
8184 }
8185 case 18: /* MedianFilter */
8186 {
8187 if (attribute_flag[0] != 0)
8188 {
8189 flags=ParseGeometry(argument_list[0].string_reference,
8190 &geometry_info);
8191 if ((flags & SigmaValue) == 0)
8192 geometry_info.sigma=geometry_info.rho;
8193 }
8194 if (attribute_flag[1] != 0)
8195 geometry_info.rho=argument_list[1].real_reference;
8196 if (attribute_flag[2] != 0)
8197 geometry_info.sigma=argument_list[2].real_reference;
8198 if (attribute_flag[3] != 0)
8199 channel=(ChannelType) argument_list[3].integer_reference;
8200 channel_mask=SetImageChannelMask(image,channel);
8201 image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
8202 (size_t) geometry_info.sigma,exception);
8203 if (image != (Image *) NULL)
8204 (void) SetImageChannelMask(image,channel_mask);
8205 break;
8206 }
8207 case 19: /* Minify */
8208 {
8209 image=MinifyImage(image,exception);
8210 break;
8211 }
8212 case 20: /* OilPaint */
8213 {
8214 if (attribute_flag[0] == 0)
8215 argument_list[0].real_reference=0.0;
8216 if (attribute_flag[1] == 0)
8217 argument_list[1].real_reference=1.0;
8218 image=OilPaintImage(image,argument_list[0].real_reference,
8219 argument_list[1].real_reference,exception);
8220 break;
8221 }
8222 case 21: /* ReduceNoise */
8223 {
8224 if (attribute_flag[0] != 0)
8225 {
8226 flags=ParseGeometry(argument_list[0].string_reference,
8227 &geometry_info);
8228 if ((flags & SigmaValue) == 0)
8229 geometry_info.sigma=1.0;
8230 }
8231 if (attribute_flag[1] != 0)
8232 geometry_info.rho=argument_list[1].real_reference;
8233 if (attribute_flag[2] != 0)
8234 geometry_info.sigma=argument_list[2].real_reference;
8235 if (attribute_flag[3] != 0)
8236 channel=(ChannelType) argument_list[3].integer_reference;
8237 channel_mask=SetImageChannelMask(image,channel);
8238 image=StatisticImage(image,NonpeakStatistic,(size_t)
8239 geometry_info.rho,(size_t) geometry_info.sigma,exception);
8240 if (image != (Image *) NULL)
8241 (void) SetImageChannelMask(image,channel_mask);
8242 break;
8243 }
8244 case 22: /* Roll */
8245 {
8246 if (attribute_flag[0] != 0)
Cristyf94b0842017-07-14 07:05:02 -04008247 {
8248 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8249 &geometry,exception);
8250 if ((flags & PercentValue) != 0)
8251 {
8252 geometry.x*=(double) image->columns/100.0;
8253 geometry.y*=(double) image->rows/100.0;
8254 }
8255 }
cristy4a3ce0a2013-08-03 20:06:59 +00008256 if (attribute_flag[1] != 0)
8257 geometry.x=argument_list[1].integer_reference;
8258 if (attribute_flag[2] != 0)
8259 geometry.y=argument_list[2].integer_reference;
8260 image=RollImage(image,geometry.x,geometry.y,exception);
8261 break;
8262 }
8263 case 23: /* Rotate */
8264 {
8265 if (attribute_flag[0] == 0)
8266 argument_list[0].real_reference=90.0;
8267 if (attribute_flag[1] != 0)
8268 {
8269 QueryColorCompliance(argument_list[1].string_reference,
8270 AllCompliance,&image->background_color,exception);
cristy17f11b02014-12-20 19:37:04 +00008271 if ((image->background_color.alpha_trait != UndefinedPixelTrait) &&
8272 (image->alpha_trait == UndefinedPixelTrait))
cristy4a3ce0a2013-08-03 20:06:59 +00008273 (void) SetImageAlpha(image,OpaqueAlpha,exception);
8274 }
8275 image=RotateImage(image,argument_list[0].real_reference,exception);
8276 break;
8277 }
8278 case 24: /* Sample */
8279 {
8280 if (attribute_flag[0] != 0)
8281 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8282 &geometry,exception);
8283 if (attribute_flag[1] != 0)
8284 geometry.width=argument_list[1].integer_reference;
8285 if (attribute_flag[2] != 0)
8286 geometry.height=argument_list[2].integer_reference;
8287 image=SampleImage(image,geometry.width,geometry.height,exception);
8288 break;
8289 }
8290 case 25: /* Scale */
8291 {
8292 if (attribute_flag[0] != 0)
8293 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8294 &geometry,exception);
8295 if (attribute_flag[1] != 0)
8296 geometry.width=argument_list[1].integer_reference;
8297 if (attribute_flag[2] != 0)
8298 geometry.height=argument_list[2].integer_reference;
8299 image=ScaleImage(image,geometry.width,geometry.height,exception);
8300 break;
8301 }
8302 case 26: /* Shade */
8303 {
8304 if (attribute_flag[0] != 0)
8305 {
8306 flags=ParseGeometry(argument_list[0].string_reference,
8307 &geometry_info);
8308 if ((flags & SigmaValue) == 0)
8309 geometry_info.sigma=0.0;
8310 }
8311 if (attribute_flag[1] != 0)
8312 geometry_info.rho=argument_list[1].real_reference;
8313 if (attribute_flag[2] != 0)
8314 geometry_info.sigma=argument_list[2].real_reference;
8315 image=ShadeImage(image,
8316 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
8317 geometry_info.rho,geometry_info.sigma,exception);
8318 break;
8319 }
8320 case 27: /* Sharpen */
8321 {
8322 if (attribute_flag[0] != 0)
8323 {
8324 flags=ParseGeometry(argument_list[0].string_reference,
8325 &geometry_info);
8326 if ((flags & SigmaValue) == 0)
8327 geometry_info.sigma=1.0;
8328 }
8329 if (attribute_flag[1] != 0)
8330 geometry_info.rho=argument_list[1].real_reference;
8331 if (attribute_flag[2] != 0)
8332 geometry_info.sigma=argument_list[2].real_reference;
8333 if (attribute_flag[3] != 0)
8334 channel=(ChannelType) argument_list[3].integer_reference;
8335 channel_mask=SetImageChannelMask(image,channel);
8336 image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
8337 exception);
8338 if (image != (Image *) NULL)
8339 (void) SetImageChannelMask(image,channel_mask);
8340 break;
8341 }
8342 case 28: /* Shear */
8343 {
8344 if (attribute_flag[0] != 0)
8345 {
8346 flags=ParseGeometry(argument_list[0].string_reference,
8347 &geometry_info);
8348 if ((flags & SigmaValue) == 0)
8349 geometry_info.sigma=geometry_info.rho;
8350 }
8351 if (attribute_flag[1] != 0)
8352 geometry_info.rho=argument_list[1].real_reference;
8353 if (attribute_flag[2] != 0)
8354 geometry_info.sigma=argument_list[2].real_reference;
8355 if (attribute_flag[3] != 0)
8356 QueryColorCompliance(argument_list[3].string_reference,
8357 AllCompliance,&image->background_color,exception);
8358 if (attribute_flag[4] != 0)
8359 QueryColorCompliance(argument_list[4].string_reference,
8360 AllCompliance,&image->background_color,exception);
8361 image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
8362 exception);
8363 break;
8364 }
8365 case 29: /* Spread */
8366 {
Cristye3319c12015-08-24 07:11:48 -04008367 PixelInterpolateMethod
8368 method;
8369
cristy4a3ce0a2013-08-03 20:06:59 +00008370 if (attribute_flag[0] == 0)
8371 argument_list[0].real_reference=1.0;
Cristye3319c12015-08-24 07:11:48 -04008372 method=UndefinedInterpolatePixel;
8373 if (attribute_flag[1] != 0)
8374 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8375 image=SpreadImage(image,method,argument_list[0].real_reference,
8376 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008377 break;
8378 }
8379 case 30: /* Swirl */
8380 {
8381 PixelInterpolateMethod
8382 method;
8383
8384 if (attribute_flag[0] == 0)
8385 argument_list[0].real_reference=50.0;
8386 method=UndefinedInterpolatePixel;
8387 if (attribute_flag[1] != 0)
8388 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
8389 image=SwirlImage(image,argument_list[0].real_reference,
8390 method,exception);
8391 break;
8392 }
8393 case 31: /* Resize */
8394 case 32: /* Zoom */
8395 {
8396 if (attribute_flag[0] != 0)
8397 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
8398 &geometry,exception);
8399 if (attribute_flag[1] != 0)
8400 geometry.width=argument_list[1].integer_reference;
8401 if (attribute_flag[2] != 0)
8402 geometry.height=argument_list[2].integer_reference;
8403 if (attribute_flag[3] == 0)
8404 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
8405 if (attribute_flag[4] != 0)
8406 SetImageArtifact(image,"filter:support",
8407 argument_list[4].string_reference);
8408 image=ResizeImage(image,geometry.width,geometry.height,
Cristy8645e042016-02-03 16:35:29 -05008409 (FilterType) argument_list[3].integer_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00008410 exception);
8411 break;
8412 }
8413 case 33: /* Annotate */
8414 {
8415 DrawInfo
8416 *draw_info;
8417
8418 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8419 (DrawInfo *) NULL);
8420 if (attribute_flag[0] != 0)
8421 {
8422 char
8423 *text;
8424
8425 text=InterpretImageProperties(info ? info->image_info :
8426 (ImageInfo *) NULL,image,argument_list[0].string_reference,
8427 exception);
8428 (void) CloneString(&draw_info->text,text);
8429 text=DestroyString(text);
8430 }
8431 if (attribute_flag[1] != 0)
8432 (void) CloneString(&draw_info->font,
8433 argument_list[1].string_reference);
8434 if (attribute_flag[2] != 0)
8435 draw_info->pointsize=argument_list[2].real_reference;
8436 if (attribute_flag[3] != 0)
8437 (void) CloneString(&draw_info->density,
8438 argument_list[3].string_reference);
8439 if (attribute_flag[4] != 0)
8440 (void) QueryColorCompliance(argument_list[4].string_reference,
8441 AllCompliance,&draw_info->undercolor,exception);
8442 if (attribute_flag[5] != 0)
8443 {
8444 (void) QueryColorCompliance(argument_list[5].string_reference,
8445 AllCompliance,&draw_info->stroke,exception);
8446 if (argument_list[5].image_reference != (Image *) NULL)
8447 draw_info->stroke_pattern=CloneImage(
8448 argument_list[5].image_reference,0,0,MagickTrue,exception);
8449 }
8450 if (attribute_flag[6] != 0)
8451 {
8452 (void) QueryColorCompliance(argument_list[6].string_reference,
8453 AllCompliance,&draw_info->fill,exception);
8454 if (argument_list[6].image_reference != (Image *) NULL)
8455 draw_info->fill_pattern=CloneImage(
8456 argument_list[6].image_reference,0,0,MagickTrue,exception);
8457 }
8458 if (attribute_flag[7] != 0)
8459 {
8460 (void) CloneString(&draw_info->geometry,
8461 argument_list[7].string_reference);
8462 flags=ParsePageGeometry(image,argument_list[7].string_reference,
8463 &geometry,exception);
8464 if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
8465 geometry_info.sigma=geometry_info.xi;
8466 }
8467 if (attribute_flag[8] != 0)
8468 (void) QueryColorCompliance(argument_list[8].string_reference,
8469 AllCompliance,&draw_info->fill,exception);
8470 if (attribute_flag[11] != 0)
8471 draw_info->gravity=(GravityType)
8472 argument_list[11].integer_reference;
8473 if (attribute_flag[25] != 0)
8474 {
8475 AV
8476 *av;
8477
8478 av=(AV *) argument_list[25].array_reference;
8479 if ((av_len(av) != 3) && (av_len(av) != 5))
8480 {
8481 ThrowPerlException(exception,OptionError,
8482 "affine matrix must have 4 or 6 elements",PackageName);
8483 goto PerlException;
8484 }
8485 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
8486 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
8487 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
8488 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
8489 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
8490 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
8491 {
8492 ThrowPerlException(exception,OptionError,
8493 "affine matrix is singular",PackageName);
8494 goto PerlException;
8495 }
8496 if (av_len(av) == 5)
8497 {
8498 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
8499 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
8500 }
8501 }
8502 for (j=12; j < 17; j++)
8503 {
8504 if (attribute_flag[j] == 0)
8505 continue;
8506 value=argument_list[j].string_reference;
8507 angle=argument_list[j].real_reference;
8508 current=draw_info->affine;
8509 GetAffineMatrix(&affine);
8510 switch (j)
8511 {
8512 case 12:
8513 {
8514 /*
8515 Translate.
8516 */
8517 flags=ParseGeometry(value,&geometry_info);
8518 affine.tx=geometry_info.xi;
8519 affine.ty=geometry_info.psi;
8520 if ((flags & PsiValue) == 0)
8521 affine.ty=affine.tx;
8522 break;
8523 }
8524 case 13:
8525 {
8526 /*
8527 Scale.
8528 */
8529 flags=ParseGeometry(value,&geometry_info);
8530 affine.sx=geometry_info.rho;
8531 affine.sy=geometry_info.sigma;
8532 if ((flags & SigmaValue) == 0)
8533 affine.sy=affine.sx;
8534 break;
8535 }
8536 case 14:
8537 {
8538 /*
8539 Rotate.
8540 */
8541 if (angle == 0.0)
8542 break;
8543 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
8544 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
8545 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
8546 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
8547 break;
8548 }
8549 case 15:
8550 {
8551 /*
8552 SkewX.
8553 */
8554 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
8555 break;
8556 }
8557 case 16:
8558 {
8559 /*
8560 SkewY.
8561 */
8562 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
8563 break;
8564 }
8565 }
8566 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
8567 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
8568 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
8569 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
8570 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
8571 current.tx;
8572 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
8573 current.ty;
8574 }
8575 if (attribute_flag[9] == 0)
8576 argument_list[9].real_reference=0.0;
8577 if (attribute_flag[10] == 0)
8578 argument_list[10].real_reference=0.0;
8579 if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
8580 {
8581 char
cristy151b66d2015-04-15 10:50:31 +00008582 geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008583
cristy151b66d2015-04-15 10:50:31 +00008584 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
cristy4a3ce0a2013-08-03 20:06:59 +00008585 (double) argument_list[9].real_reference+draw_info->affine.tx,
8586 (double) argument_list[10].real_reference+draw_info->affine.ty);
8587 (void) CloneString(&draw_info->geometry,geometry);
8588 }
8589 if (attribute_flag[17] != 0)
8590 draw_info->stroke_width=argument_list[17].real_reference;
8591 if (attribute_flag[18] != 0)
8592 {
8593 draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
8594 MagickTrue : MagickFalse;
8595 draw_info->stroke_antialias=draw_info->text_antialias;
8596 }
8597 if (attribute_flag[19] != 0)
8598 (void) CloneString(&draw_info->family,
8599 argument_list[19].string_reference);
8600 if (attribute_flag[20] != 0)
8601 draw_info->style=(StyleType) argument_list[20].integer_reference;
8602 if (attribute_flag[21] != 0)
8603 draw_info->stretch=(StretchType) argument_list[21].integer_reference;
8604 if (attribute_flag[22] != 0)
8605 draw_info->weight=argument_list[22].integer_reference;
8606 if (attribute_flag[23] != 0)
8607 draw_info->align=(AlignType) argument_list[23].integer_reference;
8608 if (attribute_flag[24] != 0)
8609 (void) CloneString(&draw_info->encoding,
8610 argument_list[24].string_reference);
8611 if (attribute_flag[25] != 0)
8612 draw_info->fill_pattern=CloneImage(
8613 argument_list[25].image_reference,0,0,MagickTrue,exception);
8614 if (attribute_flag[26] != 0)
8615 draw_info->fill_pattern=CloneImage(
8616 argument_list[26].image_reference,0,0,MagickTrue,exception);
8617 if (attribute_flag[27] != 0)
8618 draw_info->stroke_pattern=CloneImage(
8619 argument_list[27].image_reference,0,0,MagickTrue,exception);
8620 if (attribute_flag[29] != 0)
8621 draw_info->kerning=argument_list[29].real_reference;
8622 if (attribute_flag[30] != 0)
8623 draw_info->interline_spacing=argument_list[30].real_reference;
8624 if (attribute_flag[31] != 0)
8625 draw_info->interword_spacing=argument_list[31].real_reference;
8626 if (attribute_flag[32] != 0)
8627 draw_info->direction=(DirectionType)
8628 argument_list[32].integer_reference;
Cristy3d1de822019-02-15 18:06:30 -05008629 if (attribute_flag[33] != 0)
8630 draw_info->decorate=(DecorationType)
8631 argument_list[33].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00008632 (void) AnnotateImage(image,draw_info,exception);
8633 draw_info=DestroyDrawInfo(draw_info);
8634 break;
8635 }
8636 case 34: /* ColorFloodfill */
8637 {
8638 DrawInfo
8639 *draw_info;
8640
8641 MagickBooleanType
8642 invert;
8643
8644 PixelInfo
8645 target;
8646
8647 draw_info=CloneDrawInfo(info ? info->image_info :
8648 (ImageInfo *) NULL,(DrawInfo *) NULL);
8649 if (attribute_flag[0] != 0)
8650 flags=ParsePageGeometry(image,argument_list[0].string_reference,
8651 &geometry,exception);
8652 if (attribute_flag[1] != 0)
8653 geometry.x=argument_list[1].integer_reference;
8654 if (attribute_flag[2] != 0)
8655 geometry.y=argument_list[2].integer_reference;
8656 if (attribute_flag[3] != 0)
8657 (void) QueryColorCompliance(argument_list[3].string_reference,
8658 AllCompliance,&draw_info->fill,exception);
8659 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
8660 geometry.x,geometry.y,&target,exception);
8661 invert=MagickFalse;
8662 if (attribute_flag[4] != 0)
8663 {
8664 QueryColorCompliance(argument_list[4].string_reference,
8665 AllCompliance,&target,exception);
8666 invert=MagickTrue;
8667 }
8668 if (attribute_flag[5] != 0)
8669 image->fuzz=StringToDoubleInterval(
8670 argument_list[5].string_reference,(double) QuantumRange+1.0);
8671 if (attribute_flag[6] != 0)
8672 invert=(MagickBooleanType) argument_list[6].integer_reference;
8673 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
8674 geometry.y,invert,exception);
8675 draw_info=DestroyDrawInfo(draw_info);
8676 break;
8677 }
8678 case 35: /* Composite */
8679 {
8680 char
cristy151b66d2015-04-15 10:50:31 +00008681 composite_geometry[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00008682
8683 Image
8684 *composite_image,
8685 *rotate_image;
8686
8687 MagickBooleanType
8688 clip_to_self;
8689
8690 compose=OverCompositeOp;
8691 if (attribute_flag[0] != 0)
8692 composite_image=argument_list[0].image_reference;
8693 else
8694 {
8695 ThrowPerlException(exception,OptionError,
8696 "CompositeImageRequired",PackageName);
8697 goto PerlException;
8698 }
8699 /*
8700 Parameter Handling used for BOTH normal and tiled composition.
8701 */
8702 if (attribute_flag[1] != 0) /* compose */
8703 compose=(CompositeOperator) argument_list[1].integer_reference;
8704 if (attribute_flag[6] != 0) /* opacity */
8705 {
8706 if (compose != DissolveCompositeOp)
8707 (void) SetImageAlpha(composite_image,(Quantum)
8708 StringToDoubleInterval(argument_list[6].string_reference,
8709 (double) QuantumRange+1.0),exception);
8710 else
8711 {
8712 CacheView
8713 *composite_view;
8714
8715 double
8716 opacity;
8717
8718 MagickBooleanType
8719 sync;
8720
8721 register ssize_t
8722 x;
8723
8724 register Quantum
8725 *q;
8726
8727 ssize_t
8728 y;
8729
8730 /*
8731 Handle dissolve composite operator (patch by
8732 Kevin A. McGrail).
8733 */
8734 (void) CloneString(&image->geometry,
8735 argument_list[6].string_reference);
8736 opacity=(Quantum) StringToDoubleInterval(
8737 argument_list[6].string_reference,(double) QuantumRange+
8738 1.0);
cristy17f11b02014-12-20 19:37:04 +00008739 if (composite_image->alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00008740 (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
8741 composite_view=AcquireAuthenticCacheView(composite_image,exception);
8742 for (y=0; y < (ssize_t) composite_image->rows ; y++)
8743 {
8744 q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
8745 composite_image->columns,1,exception);
8746 for (x=0; x < (ssize_t) composite_image->columns; x++)
8747 {
8748 if (GetPixelAlpha(image,q) == OpaqueAlpha)
8749 SetPixelAlpha(composite_image,ClampToQuantum(opacity),
8750 q);
8751 q+=GetPixelChannels(composite_image);
8752 }
8753 sync=SyncCacheViewAuthenticPixels(composite_view,exception);
8754 if (sync == MagickFalse)
8755 break;
8756 }
8757 composite_view=DestroyCacheView(composite_view);
8758 }
8759 }
8760 if (attribute_flag[9] != 0) /* "color=>" */
8761 QueryColorCompliance(argument_list[9].string_reference,
8762 AllCompliance,&composite_image->background_color,exception);
8763 if (attribute_flag[12] != 0) /* "interpolate=>" */
8764 image->interpolate=(PixelInterpolateMethod)
8765 argument_list[12].integer_reference;
8766 if (attribute_flag[13] != 0) /* "args=>" */
8767 (void) SetImageArtifact(composite_image,"compose:args",
8768 argument_list[13].string_reference);
8769 if (attribute_flag[14] != 0) /* "blend=>" depreciated */
8770 (void) SetImageArtifact(composite_image,"compose:args",
8771 argument_list[14].string_reference);
Cristy72aed842018-07-08 18:25:50 -04008772 clip_to_self=MagickTrue;
8773 switch (compose)
8774 {
8775 case ClearCompositeOp:
8776 case SrcCompositeOp:
8777 case InCompositeOp:
8778 case SrcInCompositeOp:
8779 case OutCompositeOp:
8780 case SrcOutCompositeOp:
8781 case DstInCompositeOp:
8782 case DstAtopCompositeOp:
Cristy901f5212018-07-08 18:43:34 -04008783 case CopyAlphaCompositeOp:
Cristy72aed842018-07-08 18:25:50 -04008784 case ChangeMaskCompositeOp:
8785 case DissolveCompositeOp:
8786 case BlendCompositeOp:
8787 {
Cristy901f5212018-07-08 18:43:34 -04008788 clip_to_self=MagickFalse;
Cristy72aed842018-07-08 18:25:50 -04008789 break;
8790 }
8791 default:
8792 break;
8793 }
cristy4a3ce0a2013-08-03 20:06:59 +00008794 if (attribute_flag[15] != 0)
8795 clip_to_self=(MagickBooleanType)
8796 argument_list[15].integer_reference;
8797 /*
8798 Tiling Composition (with orthogonal rotate).
8799 */
8800 rotate_image=(Image *) NULL;
8801 if (attribute_flag[8] != 0) /* "rotate=>" */
8802 {
8803 /*
8804 Rotate image.
8805 */
8806 rotate_image=RotateImage(composite_image,
8807 argument_list[8].real_reference,exception);
8808 if (rotate_image == (Image *) NULL)
8809 break;
8810 }
8811 if ((attribute_flag[7] != 0) &&
8812 (argument_list[7].integer_reference != 0)) /* tile */
8813 {
8814 ssize_t
8815 x,
8816 y;
8817
8818 /*
8819 Tile the composite image.
8820 */
cristy4a3ce0a2013-08-03 20:06:59 +00008821 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
8822 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
8823 {
8824 if (attribute_flag[8] != 0) /* rotate */
8825 (void) CompositeImage(image,rotate_image,compose,
Cristyde6c67d2018-07-08 19:14:08 -04008826 MagickTrue,x,y,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008827 else
8828 (void) CompositeImage(image,composite_image,compose,
Cristyde6c67d2018-07-08 19:14:08 -04008829 MagickTrue,x,y,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008830 }
8831 if (attribute_flag[8] != 0) /* rotate */
8832 rotate_image=DestroyImage(rotate_image);
8833 break;
8834 }
8835 /*
8836 Parameter Handling used used ONLY for normal composition.
8837 */
8838 if (attribute_flag[5] != 0) /* gravity */
8839 image->gravity=(GravityType) argument_list[5].integer_reference;
8840 if (attribute_flag[2] != 0) /* geometry offset */
8841 {
8842 SetGeometry(image,&geometry);
8843 (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
8844 &geometry);
8845 GravityAdjustGeometry(image->columns,image->rows,image->gravity,
8846 &geometry);
8847 }
8848 if (attribute_flag[3] != 0) /* x offset */
8849 geometry.x=argument_list[3].integer_reference;
8850 if (attribute_flag[4] != 0) /* y offset */
8851 geometry.y=argument_list[4].integer_reference;
8852 if (attribute_flag[10] != 0) /* mask */
8853 {
8854 if ((image->compose == DisplaceCompositeOp) ||
8855 (image->compose == DistortCompositeOp))
8856 {
8857 /*
8858 Merge Y displacement into X displacement image.
8859 */
8860 composite_image=CloneImage(composite_image,0,0,MagickTrue,
8861 exception);
8862 (void) CompositeImage(composite_image,
8863 argument_list[10].image_reference,CopyGreenCompositeOp,
Cristy74e39292018-07-08 13:13:20 -04008864 clip_to_self,0,0,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008865 }
8866 else
8867 {
8868 Image
8869 *mask_image;
8870
8871 /*
8872 Set a blending mask for the composition.
8873 */
8874 mask_image=CloneImage(argument_list[10].image_reference,0,0,
8875 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +00008876 (void) SetImageMask(composite_image,ReadPixelMask,mask_image,
cristyf3023752015-07-28 17:13:22 +00008877 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008878 mask_image=DestroyImage(mask_image);
8879 }
8880 }
8881 if (attribute_flag[11] != 0) /* channel */
8882 channel=(ChannelType) argument_list[11].integer_reference;
8883 /*
8884 Composite two images (normal composition).
8885 */
cristy151b66d2015-04-15 10:50:31 +00008886 (void) FormatLocaleString(composite_geometry,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +00008887 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
8888 (double) composite_image->rows,(double) geometry.x,(double)
8889 geometry.y);
8890 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
8891 exception);
8892 channel_mask=SetImageChannelMask(image,channel);
8893 if (attribute_flag[8] == 0) /* no rotate */
8894 CompositeImage(image,composite_image,compose,clip_to_self,
8895 geometry.x,geometry.y,exception);
8896 else
8897 {
8898 /*
8899 Position adjust rotated image then composite.
8900 */
8901 geometry.x-=(ssize_t) (rotate_image->columns-
8902 composite_image->columns)/2;
8903 geometry.y-=(ssize_t) (rotate_image->rows-
8904 composite_image->rows)/2;
8905 CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
8906 geometry.y,exception);
8907 rotate_image=DestroyImage(rotate_image);
8908 }
8909 if (attribute_flag[10] != 0) /* mask */
8910 {
8911 if ((image->compose == DisplaceCompositeOp) ||
8912 (image->compose == DistortCompositeOp))
8913 composite_image=DestroyImage(composite_image);
8914 else
cristy1f7ffb72015-07-29 11:07:03 +00008915 (void) SetImageMask(image,ReadPixelMask,(Image *) NULL,
cristyf3023752015-07-28 17:13:22 +00008916 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00008917 }
8918 (void) SetImageChannelMask(image,channel_mask);
8919 break;
8920 }
8921 case 36: /* Contrast */
8922 {
8923 if (attribute_flag[0] == 0)
8924 argument_list[0].integer_reference=0;
8925 (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
8926 MagickTrue : MagickFalse,exception);
8927 break;
8928 }
8929 case 37: /* CycleColormap */
8930 {
8931 if (attribute_flag[0] == 0)
8932 argument_list[0].integer_reference=6;
8933 (void) CycleColormapImage(image,argument_list[0].integer_reference,
8934 exception);
8935 break;
8936 }
8937 case 38: /* Draw */
8938 {
8939 DrawInfo
8940 *draw_info;
8941
8942 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
8943 (DrawInfo *) NULL);
8944 (void) CloneString(&draw_info->primitive,"point");
8945 if (attribute_flag[0] != 0)
8946 {
8947 if (argument_list[0].integer_reference < 0)
8948 (void) CloneString(&draw_info->primitive,
8949 argument_list[0].string_reference);
8950 else
8951 (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
8952 MagickPrimitiveOptions,argument_list[0].integer_reference));
8953 }
8954 if (attribute_flag[1] != 0)
8955 {
8956 if (LocaleCompare(draw_info->primitive,"path") == 0)
8957 {
8958 (void) ConcatenateString(&draw_info->primitive," '");
8959 ConcatenateString(&draw_info->primitive,
8960 argument_list[1].string_reference);
8961 (void) ConcatenateString(&draw_info->primitive,"'");
8962 }
8963 else
8964 {
8965 (void) ConcatenateString(&draw_info->primitive," ");
8966 ConcatenateString(&draw_info->primitive,
8967 argument_list[1].string_reference);
8968 }
8969 }
8970 if (attribute_flag[2] != 0)
8971 {
8972 (void) ConcatenateString(&draw_info->primitive," ");
8973 (void) ConcatenateString(&draw_info->primitive,
8974 CommandOptionToMnemonic(MagickMethodOptions,
8975 argument_list[2].integer_reference));
8976 }
8977 if (attribute_flag[3] != 0)
8978 {
8979 (void) QueryColorCompliance(argument_list[3].string_reference,
8980 AllCompliance,&draw_info->stroke,exception);
8981 if (argument_list[3].image_reference != (Image *) NULL)
8982 draw_info->stroke_pattern=CloneImage(
8983 argument_list[3].image_reference,0,0,MagickTrue,exception);
8984 }
8985 if (attribute_flag[4] != 0)
8986 {
8987 (void) QueryColorCompliance(argument_list[4].string_reference,
8988 AllCompliance,&draw_info->fill,exception);
8989 if (argument_list[4].image_reference != (Image *) NULL)
8990 draw_info->fill_pattern=CloneImage(
8991 argument_list[4].image_reference,0,0,MagickTrue,exception);
8992 }
8993 if (attribute_flag[5] != 0)
8994 draw_info->stroke_width=argument_list[5].real_reference;
8995 if (attribute_flag[6] != 0)
8996 (void) CloneString(&draw_info->font,
8997 argument_list[6].string_reference);
8998 if (attribute_flag[7] != 0)
8999 (void) QueryColorCompliance(argument_list[7].string_reference,
9000 AllCompliance,&draw_info->border_color,exception);
9001 if (attribute_flag[8] != 0)
9002 draw_info->affine.tx=argument_list[8].real_reference;
9003 if (attribute_flag[9] != 0)
9004 draw_info->affine.ty=argument_list[9].real_reference;
9005 if (attribute_flag[20] != 0)
9006 {
9007 AV
9008 *av;
9009
9010 av=(AV *) argument_list[20].array_reference;
9011 if ((av_len(av) != 3) && (av_len(av) != 5))
9012 {
9013 ThrowPerlException(exception,OptionError,
9014 "affine matrix must have 4 or 6 elements",PackageName);
9015 goto PerlException;
9016 }
9017 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9018 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9019 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9020 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9021 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9022 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9023 {
9024 ThrowPerlException(exception,OptionError,
9025 "affine matrix is singular",PackageName);
9026 goto PerlException;
9027 }
9028 if (av_len(av) == 5)
9029 {
9030 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9031 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9032 }
9033 }
9034 for (j=10; j < 15; j++)
9035 {
9036 if (attribute_flag[j] == 0)
9037 continue;
9038 value=argument_list[j].string_reference;
9039 angle=argument_list[j].real_reference;
9040 current=draw_info->affine;
9041 GetAffineMatrix(&affine);
9042 switch (j)
9043 {
9044 case 10:
9045 {
9046 /*
9047 Translate.
9048 */
9049 flags=ParseGeometry(value,&geometry_info);
9050 affine.tx=geometry_info.xi;
9051 affine.ty=geometry_info.psi;
9052 if ((flags & PsiValue) == 0)
9053 affine.ty=affine.tx;
9054 break;
9055 }
9056 case 11:
9057 {
9058 /*
9059 Scale.
9060 */
9061 flags=ParseGeometry(value,&geometry_info);
9062 affine.sx=geometry_info.rho;
9063 affine.sy=geometry_info.sigma;
9064 if ((flags & SigmaValue) == 0)
9065 affine.sy=affine.sx;
9066 break;
9067 }
9068 case 12:
9069 {
9070 /*
9071 Rotate.
9072 */
9073 if (angle == 0.0)
9074 break;
9075 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
9076 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
9077 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
9078 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
9079 break;
9080 }
9081 case 13:
9082 {
9083 /*
9084 SkewX.
9085 */
9086 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
9087 break;
9088 }
9089 case 14:
9090 {
9091 /*
9092 SkewY.
9093 */
9094 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
9095 break;
9096 }
9097 }
9098 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
9099 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
9100 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
9101 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
9102 draw_info->affine.tx=
9103 current.sx*affine.tx+current.ry*affine.ty+current.tx;
9104 draw_info->affine.ty=
9105 current.rx*affine.tx+current.sy*affine.ty+current.ty;
9106 }
9107 if (attribute_flag[15] != 0)
9108 draw_info->fill_pattern=CloneImage(
9109 argument_list[15].image_reference,0,0,MagickTrue,exception);
9110 if (attribute_flag[16] != 0)
9111 draw_info->pointsize=argument_list[16].real_reference;
9112 if (attribute_flag[17] != 0)
9113 {
Cristy36c30b62018-11-22 09:33:30 -05009114 draw_info->stroke_antialias=argument_list[17].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009115 draw_info->text_antialias=draw_info->stroke_antialias;
9116 }
9117 if (attribute_flag[18] != 0)
9118 (void) CloneString(&draw_info->density,
9119 argument_list[18].string_reference);
9120 if (attribute_flag[19] != 0)
9121 draw_info->stroke_width=argument_list[19].real_reference;
9122 if (attribute_flag[21] != 0)
9123 draw_info->dash_offset=argument_list[21].real_reference;
9124 if (attribute_flag[22] != 0)
9125 {
9126 AV
9127 *av;
9128
9129 av=(AV *) argument_list[22].array_reference;
9130 draw_info->dash_pattern=(double *) AcquireQuantumMemory(
9131 av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
9132 if (draw_info->dash_pattern != (double *) NULL)
9133 {
9134 for (i=0; i <= av_len(av); i++)
9135 draw_info->dash_pattern[i]=(double)
9136 SvNV(*(av_fetch(av,i,0)));
9137 draw_info->dash_pattern[i]=0.0;
9138 }
9139 }
9140 if (attribute_flag[23] != 0)
9141 image->interpolate=(PixelInterpolateMethod)
9142 argument_list[23].integer_reference;
9143 if ((attribute_flag[24] != 0) &&
9144 (draw_info->fill_pattern != (Image *) NULL))
9145 flags=ParsePageGeometry(draw_info->fill_pattern,
9146 argument_list[24].string_reference,
9147 &draw_info->fill_pattern->tile_offset,exception);
9148 if (attribute_flag[25] != 0)
9149 {
9150 (void) ConcatenateString(&draw_info->primitive," '");
9151 (void) ConcatenateString(&draw_info->primitive,
9152 argument_list[25].string_reference);
9153 (void) ConcatenateString(&draw_info->primitive,"'");
9154 }
9155 if (attribute_flag[26] != 0)
9156 draw_info->fill_pattern=CloneImage(
9157 argument_list[26].image_reference,0,0,MagickTrue,exception);
9158 if (attribute_flag[27] != 0)
9159 draw_info->stroke_pattern=CloneImage(
9160 argument_list[27].image_reference,0,0,MagickTrue,exception);
9161 if (attribute_flag[28] != 0)
9162 (void) CloneString(&draw_info->primitive,
9163 argument_list[28].string_reference);
9164 if (attribute_flag[29] != 0)
9165 draw_info->kerning=argument_list[29].real_reference;
9166 if (attribute_flag[30] != 0)
9167 draw_info->interline_spacing=argument_list[30].real_reference;
9168 if (attribute_flag[31] != 0)
9169 draw_info->interword_spacing=argument_list[31].real_reference;
9170 if (attribute_flag[32] != 0)
9171 draw_info->direction=(DirectionType)
9172 argument_list[32].integer_reference;
Cristy36c30b62018-11-22 09:33:30 -05009173 (void) DrawImage(image,draw_info,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009174 draw_info=DestroyDrawInfo(draw_info);
9175 break;
9176 }
9177 case 39: /* Equalize */
9178 {
9179 if (attribute_flag[0] != 0)
9180 channel=(ChannelType) argument_list[0].integer_reference;
9181 channel_mask=SetImageChannelMask(image,channel);
Cristy36c30b62018-11-22 09:33:30 -05009182 (void) EqualizeImage(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009183 (void) SetImageChannelMask(image,channel_mask);
9184 break;
9185 }
9186 case 40: /* Gamma */
9187 {
9188 if (attribute_flag[1] != 0)
9189 channel=(ChannelType) argument_list[1].integer_reference;
9190 if (attribute_flag[2] == 0)
9191 argument_list[2].real_reference=1.0;
9192 if (attribute_flag[3] == 0)
9193 argument_list[3].real_reference=1.0;
9194 if (attribute_flag[4] == 0)
9195 argument_list[4].real_reference=1.0;
9196 if (attribute_flag[0] == 0)
9197 {
cristy151b66d2015-04-15 10:50:31 +00009198 (void) FormatLocaleString(message,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -05009199 "%.20g,%.20g,%.20g",(double) argument_list[2].real_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009200 (double) argument_list[3].real_reference,
9201 (double) argument_list[4].real_reference);
9202 argument_list[0].string_reference=message;
9203 }
9204 (void) GammaImage(image,StringToDouble(
9205 argument_list[0].string_reference,(char **) NULL),exception);
9206 break;
9207 }
9208 case 41: /* Map */
9209 {
9210 QuantizeInfo
9211 *quantize_info;
9212
9213 if (attribute_flag[0] == 0)
9214 {
9215 ThrowPerlException(exception,OptionError,"MapImageRequired",
9216 PackageName);
9217 goto PerlException;
9218 }
9219 quantize_info=AcquireQuantizeInfo(info->image_info);
9220 if (attribute_flag[1] != 0)
9221 quantize_info->dither_method=(DitherMethod)
9222 argument_list[1].integer_reference;
9223 (void) RemapImages(quantize_info,image,
9224 argument_list[0].image_reference,exception);
9225 quantize_info=DestroyQuantizeInfo(quantize_info);
9226 break;
9227 }
9228 case 42: /* MatteFloodfill */
9229 {
9230 DrawInfo
9231 *draw_info;
9232
9233 MagickBooleanType
9234 invert;
9235
9236 PixelInfo
9237 target;
9238
9239 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9240 (DrawInfo *) NULL);
9241 if (attribute_flag[0] != 0)
9242 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9243 &geometry,exception);
9244 if (attribute_flag[1] != 0)
9245 geometry.x=argument_list[1].integer_reference;
9246 if (attribute_flag[2] != 0)
9247 geometry.y=argument_list[2].integer_reference;
cristy17f11b02014-12-20 19:37:04 +00009248 if (image->alpha_trait == UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +00009249 (void) SetImageAlpha(image,OpaqueAlpha,exception);
9250 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
9251 geometry.x,geometry.y,&target,exception);
9252 if (attribute_flag[4] != 0)
9253 QueryColorCompliance(argument_list[4].string_reference,
9254 AllCompliance,&target,exception);
9255 if (attribute_flag[3] != 0)
9256 target.alpha=StringToDoubleInterval(
9257 argument_list[3].string_reference,(double) (double) QuantumRange+
9258 1.0);
9259 if (attribute_flag[5] != 0)
9260 image->fuzz=StringToDoubleInterval(
9261 argument_list[5].string_reference,(double) QuantumRange+1.0);
9262 invert=MagickFalse;
9263 if (attribute_flag[6] != 0)
9264 invert=(MagickBooleanType) argument_list[6].integer_reference;
9265 channel_mask=SetImageChannelMask(image,AlphaChannel);
9266 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
9267 geometry.y,invert,exception);
9268 (void) SetImageChannelMask(image,channel_mask);
9269 draw_info=DestroyDrawInfo(draw_info);
9270 break;
9271 }
9272 case 43: /* Modulate */
9273 {
9274 char
cristy151b66d2015-04-15 10:50:31 +00009275 modulate[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +00009276
9277 geometry_info.rho=100.0;
9278 geometry_info.sigma=100.0;
9279 geometry_info.xi=100.0;
9280 if (attribute_flag[0] != 0)
9281 (void)ParseGeometry(argument_list[0].string_reference,
9282 &geometry_info);
9283 if (attribute_flag[1] != 0)
9284 geometry_info.xi=argument_list[1].real_reference;
9285 if (attribute_flag[2] != 0)
9286 geometry_info.sigma=argument_list[2].real_reference;
9287 if (attribute_flag[3] != 0)
9288 {
9289 geometry_info.sigma=argument_list[3].real_reference;
9290 SetImageArtifact(image,"modulate:colorspace","HWB");
9291 }
9292 if (attribute_flag[4] != 0)
9293 {
9294 geometry_info.rho=argument_list[4].real_reference;
9295 SetImageArtifact(image,"modulate:colorspace","HSB");
9296 }
9297 if (attribute_flag[5] != 0)
9298 {
9299 geometry_info.sigma=argument_list[5].real_reference;
9300 SetImageArtifact(image,"modulate:colorspace","HSL");
9301 }
9302 if (attribute_flag[6] != 0)
9303 {
9304 geometry_info.rho=argument_list[6].real_reference;
9305 SetImageArtifact(image,"modulate:colorspace","HWB");
9306 }
Cristy935a4052017-03-31 17:45:37 -04009307 (void) FormatLocaleString(modulate,MagickPathExtent,"%.20g,%.20g,%.20g",
9308 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
cristy4a3ce0a2013-08-03 20:06:59 +00009309 (void) ModulateImage(image,modulate,exception);
9310 break;
9311 }
9312 case 44: /* Negate */
9313 {
9314 if (attribute_flag[0] == 0)
9315 argument_list[0].integer_reference=0;
9316 if (attribute_flag[1] != 0)
9317 channel=(ChannelType) argument_list[1].integer_reference;
9318 channel_mask=SetImageChannelMask(image,channel);
9319 (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
9320 MagickTrue : MagickFalse,exception);
9321 (void) SetImageChannelMask(image,channel_mask);
9322 break;
9323 }
9324 case 45: /* Normalize */
9325 {
9326 if (attribute_flag[0] != 0)
9327 channel=(ChannelType) argument_list[0].integer_reference;
9328 channel_mask=SetImageChannelMask(image,channel);
9329 NormalizeImage(image,exception);
9330 (void) SetImageChannelMask(image,channel_mask);
9331 break;
9332 }
9333 case 46: /* NumberColors */
9334 break;
9335 case 47: /* Opaque */
9336 {
9337 MagickBooleanType
9338 invert;
9339
9340 PixelInfo
9341 fill_color,
9342 target;
9343
9344 (void) QueryColorCompliance("none",AllCompliance,&target,
9345 exception);
9346 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
9347 exception);
9348 if (attribute_flag[0] != 0)
9349 (void) QueryColorCompliance(argument_list[0].string_reference,
9350 AllCompliance,&target,exception);
9351 if (attribute_flag[1] != 0)
9352 (void) QueryColorCompliance(argument_list[1].string_reference,
9353 AllCompliance,&fill_color,exception);
9354 if (attribute_flag[2] != 0)
9355 image->fuzz=StringToDoubleInterval(
9356 argument_list[2].string_reference,(double) QuantumRange+1.0);
9357 if (attribute_flag[3] != 0)
9358 channel=(ChannelType) argument_list[3].integer_reference;
9359 invert=MagickFalse;
9360 if (attribute_flag[4] != 0)
9361 invert=(MagickBooleanType) argument_list[4].integer_reference;
9362 channel_mask=SetImageChannelMask(image,channel);
9363 (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
9364 (void) SetImageChannelMask(image,channel_mask);
9365 break;
9366 }
9367 case 48: /* Quantize */
9368 {
9369 QuantizeInfo
9370 *quantize_info;
9371
9372 quantize_info=AcquireQuantizeInfo(info->image_info);
9373 if (attribute_flag[0] != 0)
9374 quantize_info->number_colors=(size_t)
9375 argument_list[0].integer_reference;
9376 if (attribute_flag[1] != 0)
9377 quantize_info->tree_depth=(size_t)
9378 argument_list[1].integer_reference;
9379 if (attribute_flag[2] != 0)
9380 quantize_info->colorspace=(ColorspaceType)
9381 argument_list[2].integer_reference;
9382 if (attribute_flag[3] != 0)
cristy785c9342014-03-19 22:06:39 +00009383 quantize_info->dither_method=(DitherMethod)
9384 argument_list[3].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +00009385 if (attribute_flag[4] != 0)
cristy71716d52014-03-19 10:11:11 +00009386 quantize_info->measure_error=
9387 argument_list[4].integer_reference != 0 ? MagickTrue : MagickFalse;
cristy4a3ce0a2013-08-03 20:06:59 +00009388 if (attribute_flag[6] != 0)
cristyd472dd82014-03-19 22:04:36 +00009389 (void) QueryColorCompliance(argument_list[6].string_reference,
cristyf7563392014-03-25 13:54:04 +00009390 AllCompliance,&image->transparent_color,exception);
cristy71716d52014-03-19 10:11:11 +00009391 if (attribute_flag[7] != 0)
cristy4a3ce0a2013-08-03 20:06:59 +00009392 quantize_info->dither_method=(DitherMethod)
cristy71716d52014-03-19 10:11:11 +00009393 argument_list[7].integer_reference;
9394 if (attribute_flag[5] && argument_list[5].integer_reference)
cristyf7563392014-03-25 13:54:04 +00009395 (void) QuantizeImages(quantize_info,image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009396 else
cristyf7563392014-03-25 13:54:04 +00009397 if ((image->storage_class == DirectClass) ||
9398 (image->colors > quantize_info->number_colors) ||
9399 (quantize_info->colorspace == GRAYColorspace))
9400 (void) QuantizeImage(quantize_info,image,exception);
9401 else
9402 CompressImageColormap(image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009403 quantize_info=DestroyQuantizeInfo(quantize_info);
9404 break;
9405 }
9406 case 49: /* Raise */
9407 {
9408 if (attribute_flag[0] != 0)
9409 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9410 &geometry,exception);
9411 if (attribute_flag[1] != 0)
9412 geometry.width=argument_list[1].integer_reference;
9413 if (attribute_flag[2] != 0)
9414 geometry.height=argument_list[2].integer_reference;
9415 if (attribute_flag[3] == 0)
9416 argument_list[3].integer_reference=1;
9417 (void) RaiseImage(image,&geometry,
9418 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
9419 exception);
9420 break;
9421 }
9422 case 50: /* Segment */
9423 {
9424 ColorspaceType
9425 colorspace;
9426
9427 double
9428 cluster_threshold,
9429 smoothing_threshold;
9430
9431 MagickBooleanType
9432 verbose;
9433
9434 cluster_threshold=1.0;
9435 smoothing_threshold=1.5;
9436 colorspace=sRGBColorspace;
9437 verbose=MagickFalse;
9438 if (attribute_flag[0] != 0)
9439 {
9440 flags=ParseGeometry(argument_list[0].string_reference,
9441 &geometry_info);
9442 cluster_threshold=geometry_info.rho;
9443 if (flags & SigmaValue)
9444 smoothing_threshold=geometry_info.sigma;
9445 }
9446 if (attribute_flag[1] != 0)
9447 cluster_threshold=argument_list[1].real_reference;
9448 if (attribute_flag[2] != 0)
9449 smoothing_threshold=argument_list[2].real_reference;
9450 if (attribute_flag[3] != 0)
9451 colorspace=(ColorspaceType) argument_list[3].integer_reference;
9452 if (attribute_flag[4] != 0)
9453 verbose=argument_list[4].integer_reference != 0 ?
9454 MagickTrue : MagickFalse;
9455 (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
9456 smoothing_threshold,exception);
9457 break;
9458 }
9459 case 51: /* Signature */
9460 {
9461 (void) SignatureImage(image,exception);
9462 break;
9463 }
9464 case 52: /* Solarize */
9465 {
9466 geometry_info.rho=QuantumRange/2.0;
9467 if (attribute_flag[0] != 0)
9468 flags=ParseGeometry(argument_list[0].string_reference,
9469 &geometry_info);
9470 if (attribute_flag[1] != 0)
9471 geometry_info.rho=StringToDoubleInterval(
9472 argument_list[1].string_reference,(double) QuantumRange+1.0);
9473 (void) SolarizeImage(image,geometry_info.rho,exception);
9474 break;
9475 }
9476 case 53: /* Sync */
9477 {
9478 (void) SyncImage(image,exception);
9479 break;
9480 }
9481 case 54: /* Texture */
9482 {
9483 if (attribute_flag[0] == 0)
9484 break;
9485 TextureImage(image,argument_list[0].image_reference,exception);
9486 break;
9487 }
9488 case 55: /* Evalute */
9489 {
9490 MagickEvaluateOperator
9491 op;
9492
9493 op=SetEvaluateOperator;
9494 if (attribute_flag[0] == MagickFalse)
9495 argument_list[0].real_reference=0.0;
9496 if (attribute_flag[1] != MagickFalse)
9497 op=(MagickEvaluateOperator) argument_list[1].integer_reference;
9498 if (attribute_flag[2] != MagickFalse)
9499 channel=(ChannelType) argument_list[2].integer_reference;
9500 channel_mask=SetImageChannelMask(image,channel);
9501 (void) EvaluateImage(image,op,argument_list[0].real_reference,
9502 exception);
9503 (void) SetImageChannelMask(image,channel_mask);
9504 break;
9505 }
9506 case 56: /* Transparent */
9507 {
9508 double
9509 opacity;
9510
9511 MagickBooleanType
9512 invert;
9513
9514 PixelInfo
9515 target;
9516
9517 (void) QueryColorCompliance("none",AllCompliance,&target,
9518 exception);
9519 if (attribute_flag[0] != 0)
9520 (void) QueryColorCompliance(argument_list[0].string_reference,
9521 AllCompliance,&target,exception);
9522 opacity=TransparentAlpha;
9523 if (attribute_flag[1] != 0)
9524 opacity=StringToDoubleInterval(argument_list[1].string_reference,
9525 (double) QuantumRange+1.0);
9526 if (attribute_flag[2] != 0)
9527 image->fuzz=StringToDoubleInterval(
9528 argument_list[2].string_reference,(double) QuantumRange+1.0);
9529 if (attribute_flag[3] == 0)
9530 argument_list[3].integer_reference=0;
9531 invert=MagickFalse;
9532 if (attribute_flag[3] != 0)
9533 invert=(MagickBooleanType) argument_list[3].integer_reference;
9534 (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
9535 invert,exception);
9536 break;
9537 }
9538 case 57: /* Threshold */
9539 {
9540 double
9541 threshold;
9542
9543 if (attribute_flag[0] == 0)
9544 argument_list[0].string_reference="50%";
9545 if (attribute_flag[1] != 0)
9546 channel=(ChannelType) argument_list[1].integer_reference;
9547 threshold=StringToDoubleInterval(argument_list[0].string_reference,
9548 (double) QuantumRange+1.0);
9549 channel_mask=SetImageChannelMask(image,channel);
9550 (void) BilevelImage(image,threshold,exception);
9551 (void) SetImageChannelMask(image,channel_mask);
9552 break;
9553 }
9554 case 58: /* Charcoal */
9555 {
9556 if (attribute_flag[0] != 0)
9557 {
9558 flags=ParseGeometry(argument_list[0].string_reference,
9559 &geometry_info);
9560 if ((flags & SigmaValue) == 0)
9561 geometry_info.sigma=1.0;
9562 }
9563 if (attribute_flag[1] != 0)
9564 geometry_info.rho=argument_list[1].real_reference;
9565 if (attribute_flag[2] != 0)
9566 geometry_info.sigma=argument_list[2].real_reference;
9567 image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
9568 exception);
9569 break;
9570 }
9571 case 59: /* Trim */
9572 {
9573 if (attribute_flag[0] != 0)
9574 image->fuzz=StringToDoubleInterval(
9575 argument_list[0].string_reference,(double) QuantumRange+1.0);
9576 image=TrimImage(image,exception);
9577 break;
9578 }
9579 case 60: /* Wave */
9580 {
9581 PixelInterpolateMethod
9582 method;
9583
9584 if (attribute_flag[0] != 0)
9585 {
9586 flags=ParseGeometry(argument_list[0].string_reference,
9587 &geometry_info);
9588 if ((flags & SigmaValue) == 0)
9589 geometry_info.sigma=1.0;
9590 }
9591 if (attribute_flag[1] != 0)
9592 geometry_info.rho=argument_list[1].real_reference;
9593 if (attribute_flag[2] != 0)
9594 geometry_info.sigma=argument_list[2].real_reference;
9595 method=UndefinedInterpolatePixel;
9596 if (attribute_flag[3] != 0)
9597 method=(PixelInterpolateMethod) argument_list[3].integer_reference;
9598 image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
9599 method,exception);
9600 break;
9601 }
9602 case 61: /* Separate */
9603 {
9604 if (attribute_flag[0] != 0)
9605 channel=(ChannelType) argument_list[0].integer_reference;
9606 image=SeparateImage(image,channel,exception);
9607 break;
9608 }
9609 case 63: /* Stereo */
9610 {
9611 if (attribute_flag[0] == 0)
9612 {
9613 ThrowPerlException(exception,OptionError,"StereoImageRequired",
9614 PackageName);
9615 goto PerlException;
9616 }
9617 if (attribute_flag[1] != 0)
9618 geometry.x=argument_list[1].integer_reference;
9619 if (attribute_flag[2] != 0)
9620 geometry.y=argument_list[2].integer_reference;
9621 image=StereoAnaglyphImage(image,argument_list[0].image_reference,
9622 geometry.x,geometry.y,exception);
9623 break;
9624 }
9625 case 64: /* Stegano */
9626 {
9627 if (attribute_flag[0] == 0)
9628 {
9629 ThrowPerlException(exception,OptionError,"SteganoImageRequired",
9630 PackageName);
9631 goto PerlException;
9632 }
9633 if (attribute_flag[1] == 0)
9634 argument_list[1].integer_reference=0;
9635 image->offset=argument_list[1].integer_reference;
9636 image=SteganoImage(image,argument_list[0].image_reference,exception);
9637 break;
9638 }
9639 case 65: /* Deconstruct */
9640 {
9641 image=CompareImagesLayers(image,CompareAnyLayer,exception);
9642 break;
9643 }
9644 case 66: /* GaussianBlur */
9645 {
9646 if (attribute_flag[0] != 0)
9647 {
9648 flags=ParseGeometry(argument_list[0].string_reference,
9649 &geometry_info);
9650 if ((flags & SigmaValue) == 0)
9651 geometry_info.sigma=1.0;
9652 }
9653 if (attribute_flag[1] != 0)
9654 geometry_info.rho=argument_list[1].real_reference;
9655 if (attribute_flag[2] != 0)
9656 geometry_info.sigma=argument_list[2].real_reference;
9657 if (attribute_flag[3] != 0)
9658 channel=(ChannelType) argument_list[3].integer_reference;
9659 channel_mask=SetImageChannelMask(image,channel);
9660 image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
9661 exception);
9662 if (image != (Image *) NULL)
9663 (void) SetImageChannelMask(image,channel_mask);
9664 break;
9665 }
9666 case 67: /* Convolve */
9667 {
9668 KernelInfo
9669 *kernel;
9670
9671 kernel=(KernelInfo *) NULL;
9672 if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
9673 break;
9674 if (attribute_flag[0] != 0)
9675 {
9676 AV
9677 *av;
9678
9679 size_t
9680 order;
9681
cristy2c57b742014-10-31 00:40:34 +00009682 kernel=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009683 if (kernel == (KernelInfo *) NULL)
9684 break;
9685 av=(AV *) argument_list[0].array_reference;
9686 order=(size_t) sqrt(av_len(av)+1);
9687 kernel->width=order;
9688 kernel->height=order;
9689 kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
9690 order*sizeof(*kernel->values));
9691 if (kernel->values == (MagickRealType *) NULL)
9692 {
9693 kernel=DestroyKernelInfo(kernel);
9694 ThrowPerlException(exception,ResourceLimitFatalError,
9695 "MemoryAllocationFailed",PackageName);
9696 goto PerlException;
9697 }
9698 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
9699 kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
9700 for ( ; j < (ssize_t) (order*order); j++)
9701 kernel->values[j]=0.0;
9702 }
9703 if (attribute_flag[1] != 0)
9704 channel=(ChannelType) argument_list[1].integer_reference;
9705 if (attribute_flag[2] != 0)
Cristyc4ff6bd2017-07-05 21:00:11 -04009706 SetImageArtifact(image,"convolve:bias",
cristy4a3ce0a2013-08-03 20:06:59 +00009707 argument_list[2].string_reference);
9708 if (attribute_flag[3] != 0)
9709 {
cristy2c57b742014-10-31 00:40:34 +00009710 kernel=AcquireKernelInfo(argument_list[3].string_reference,
9711 exception);
cristy4a3ce0a2013-08-03 20:06:59 +00009712 if (kernel == (KernelInfo *) NULL)
9713 break;
9714 }
9715 channel_mask=SetImageChannelMask(image,channel);
9716 image=ConvolveImage(image,kernel,exception);
9717 if (image != (Image *) NULL)
9718 (void) SetImageChannelMask(image,channel_mask);
9719 kernel=DestroyKernelInfo(kernel);
9720 break;
9721 }
9722 case 68: /* Profile */
9723 {
9724 const char
9725 *name;
9726
9727 Image
9728 *profile_image;
9729
9730 ImageInfo
9731 *profile_info;
9732
9733 StringInfo
9734 *profile;
9735
9736 name="*";
9737 if (attribute_flag[0] != 0)
9738 name=argument_list[0].string_reference;
9739 if (attribute_flag[2] != 0)
9740 image->rendering_intent=(RenderingIntent)
9741 argument_list[2].integer_reference;
9742 if (attribute_flag[3] != 0)
9743 image->black_point_compensation=
9744 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
9745 if (attribute_flag[1] != 0)
9746 {
9747 if (argument_list[1].length == 0)
9748 {
9749 /*
9750 Remove a profile from the image.
9751 */
9752 (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
9753 exception);
9754 break;
9755 }
9756 /*
9757 Associate user supplied profile with the image.
9758 */
9759 profile=AcquireStringInfo(argument_list[1].length);
9760 SetStringInfoDatum(profile,(const unsigned char *)
9761 argument_list[1].string_reference);
9762 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9763 (size_t) GetStringInfoLength(profile),exception);
9764 profile=DestroyStringInfo(profile);
9765 break;
9766 }
9767 /*
9768 Associate a profile with the image.
9769 */
9770 profile_info=CloneImageInfo(info ? info->image_info :
9771 (ImageInfo *) NULL);
9772 profile_image=ReadImages(profile_info,name,exception);
9773 if (profile_image == (Image *) NULL)
9774 break;
9775 ResetImageProfileIterator(profile_image);
9776 name=GetNextImageProfile(profile_image);
9777 while (name != (const char *) NULL)
9778 {
9779 const StringInfo
9780 *profile;
9781
9782 profile=GetImageProfile(profile_image,name);
9783 if (profile != (const StringInfo *) NULL)
9784 (void) ProfileImage(image,name,GetStringInfoDatum(profile),
9785 (size_t) GetStringInfoLength(profile),exception);
9786 name=GetNextImageProfile(profile_image);
9787 }
9788 profile_image=DestroyImage(profile_image);
9789 profile_info=DestroyImageInfo(profile_info);
9790 break;
9791 }
9792 case 69: /* UnsharpMask */
9793 {
9794 if (attribute_flag[0] != 0)
9795 {
9796 flags=ParseGeometry(argument_list[0].string_reference,
9797 &geometry_info);
9798 if ((flags & SigmaValue) == 0)
9799 geometry_info.sigma=1.0;
9800 if ((flags & XiValue) == 0)
9801 geometry_info.xi=1.0;
9802 if ((flags & PsiValue) == 0)
9803 geometry_info.psi=0.5;
9804 }
9805 if (attribute_flag[1] != 0)
9806 geometry_info.rho=argument_list[1].real_reference;
9807 if (attribute_flag[2] != 0)
9808 geometry_info.sigma=argument_list[2].real_reference;
9809 if (attribute_flag[3] != 0)
9810 geometry_info.xi=argument_list[3].real_reference;
9811 if (attribute_flag[4] != 0)
9812 geometry_info.psi=argument_list[4].real_reference;
9813 if (attribute_flag[5] != 0)
9814 channel=(ChannelType) argument_list[5].integer_reference;
9815 channel_mask=SetImageChannelMask(image,channel);
9816 image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
9817 geometry_info.xi,geometry_info.psi,exception);
9818 if (image != (Image *) NULL)
9819 (void) SetImageChannelMask(image,channel_mask);
9820 break;
9821 }
9822 case 70: /* MotionBlur */
9823 {
9824 if (attribute_flag[0] != 0)
9825 {
9826 flags=ParseGeometry(argument_list[0].string_reference,
9827 &geometry_info);
9828 if ((flags & SigmaValue) == 0)
9829 geometry_info.sigma=1.0;
9830 if ((flags & XiValue) == 0)
9831 geometry_info.xi=1.0;
9832 }
9833 if (attribute_flag[1] != 0)
9834 geometry_info.rho=argument_list[1].real_reference;
9835 if (attribute_flag[2] != 0)
9836 geometry_info.sigma=argument_list[2].real_reference;
9837 if (attribute_flag[3] != 0)
9838 geometry_info.xi=argument_list[3].real_reference;
9839 if (attribute_flag[4] != 0)
9840 channel=(ChannelType) argument_list[4].integer_reference;
9841 channel_mask=SetImageChannelMask(image,channel);
9842 image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
9843 geometry_info.xi,exception);
9844 if (image != (Image *) NULL)
9845 (void) SetImageChannelMask(image,channel_mask);
9846 break;
9847 }
9848 case 71: /* OrderedDither */
9849 {
9850 if (attribute_flag[0] == 0)
9851 argument_list[0].string_reference="o8x8";
9852 if (attribute_flag[1] != 0)
9853 channel=(ChannelType) argument_list[1].integer_reference;
9854 channel_mask=SetImageChannelMask(image,channel);
Cristy6b93c072016-02-04 07:45:48 -05009855 (void) OrderedDitherImage(image,argument_list[0].string_reference,
cristy4a3ce0a2013-08-03 20:06:59 +00009856 exception);
9857 (void) SetImageChannelMask(image,channel_mask);
9858 break;
9859 }
9860 case 72: /* Shave */
9861 {
9862 if (attribute_flag[0] != 0)
9863 flags=ParsePageGeometry(image,argument_list[0].string_reference,
9864 &geometry,exception);
9865 if (attribute_flag[1] != 0)
9866 geometry.width=argument_list[1].integer_reference;
9867 if (attribute_flag[2] != 0)
9868 geometry.height=argument_list[2].integer_reference;
9869 image=ShaveImage(image,&geometry,exception);
9870 break;
9871 }
9872 case 73: /* Level */
9873 {
9874 double
9875 black_point,
9876 gamma,
9877 white_point;
9878
9879 black_point=0.0;
9880 white_point=(double) image->columns*image->rows;
9881 gamma=1.0;
9882 if (attribute_flag[0] != 0)
9883 {
9884 flags=ParseGeometry(argument_list[0].string_reference,
9885 &geometry_info);
9886 black_point=geometry_info.rho;
9887 if ((flags & SigmaValue) != 0)
9888 white_point=geometry_info.sigma;
9889 if ((flags & XiValue) != 0)
9890 gamma=geometry_info.xi;
9891 if ((flags & PercentValue) != 0)
9892 {
9893 black_point*=(double) (QuantumRange/100.0);
9894 white_point*=(double) (QuantumRange/100.0);
9895 }
9896 if ((flags & SigmaValue) == 0)
9897 white_point=(double) QuantumRange-black_point;
9898 }
9899 if (attribute_flag[1] != 0)
9900 black_point=argument_list[1].real_reference;
9901 if (attribute_flag[2] != 0)
9902 white_point=argument_list[2].real_reference;
9903 if (attribute_flag[3] != 0)
9904 gamma=argument_list[3].real_reference;
9905 if (attribute_flag[4] != 0)
9906 channel=(ChannelType) argument_list[4].integer_reference;
9907 if (attribute_flag[5] != 0)
9908 {
9909 argument_list[0].real_reference=argument_list[5].real_reference;
9910 attribute_flag[0]=attribute_flag[5];
9911 }
9912 channel_mask=SetImageChannelMask(image,channel);
9913 (void) LevelImage(image,black_point,white_point,gamma,exception);
9914 (void) SetImageChannelMask(image,channel_mask);
9915 break;
9916 }
9917 case 74: /* Clip */
9918 {
9919 if (attribute_flag[0] == 0)
9920 argument_list[0].string_reference="#1";
9921 if (attribute_flag[1] == 0)
9922 argument_list[1].integer_reference=MagickTrue;
9923 (void) ClipImagePath(image,argument_list[0].string_reference,
9924 argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
9925 exception);
9926 break;
9927 }
9928 case 75: /* AffineTransform */
9929 {
9930 DrawInfo
9931 *draw_info;
9932
9933 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
9934 (DrawInfo *) NULL);
9935 if (attribute_flag[0] != 0)
9936 {
9937 AV
9938 *av;
9939
9940 av=(AV *) argument_list[0].array_reference;
9941 if ((av_len(av) != 3) && (av_len(av) != 5))
9942 {
9943 ThrowPerlException(exception,OptionError,
9944 "affine matrix must have 4 or 6 elements",PackageName);
9945 goto PerlException;
9946 }
9947 draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
9948 draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
9949 draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
9950 draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
9951 if (fabs(draw_info->affine.sx*draw_info->affine.sy-
9952 draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
9953 {
9954 ThrowPerlException(exception,OptionError,
9955 "affine matrix is singular",PackageName);
9956 goto PerlException;
9957 }
9958 if (av_len(av) == 5)
9959 {
9960 draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
9961 draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
9962 }
9963 }
9964 for (j=1; j < 6; j++)
9965 {
9966 if (attribute_flag[j] == 0)
9967 continue;
9968 value=argument_list[j].string_reference;
9969 angle=argument_list[j].real_reference;
9970 current=draw_info->affine;
9971 GetAffineMatrix(&affine);
9972 switch (j)
9973 {
9974 case 1:
9975 {
9976 /*
9977 Translate.
9978 */
9979 flags=ParseGeometry(value,&geometry_info);
9980 affine.tx=geometry_info.xi;
9981 affine.ty=geometry_info.psi;
9982 if ((flags & PsiValue) == 0)
9983 affine.ty=affine.tx;
9984 break;
9985 }
9986 case 2:
9987 {
9988 /*
9989 Scale.
9990 */
9991 flags=ParseGeometry(value,&geometry_info);
9992 affine.sx=geometry_info.rho;
9993 affine.sy=geometry_info.sigma;
9994 if ((flags & SigmaValue) == 0)
9995 affine.sy=affine.sx;
9996 break;
9997 }
9998 case 3:
9999 {
10000 /*
10001 Rotate.
10002 */
10003 if (angle == 0.0)
10004 break;
10005 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
10006 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
10007 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
10008 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
10009 break;
10010 }
10011 case 4:
10012 {
10013 /*
10014 SkewX.
10015 */
10016 affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
10017 break;
10018 }
10019 case 5:
10020 {
10021 /*
10022 SkewY.
10023 */
10024 affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
10025 break;
10026 }
10027 }
10028 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
10029 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
10030 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
10031 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
10032 draw_info->affine.tx=
10033 current.sx*affine.tx+current.ry*affine.ty+current.tx;
10034 draw_info->affine.ty=
10035 current.rx*affine.tx+current.sy*affine.ty+current.ty;
10036 }
10037 if (attribute_flag[6] != 0)
10038 image->interpolate=(PixelInterpolateMethod)
10039 argument_list[6].integer_reference;
10040 if (attribute_flag[7] != 0)
10041 QueryColorCompliance(argument_list[7].string_reference,
10042 AllCompliance,&image->background_color,exception);
10043 image=AffineTransformImage(image,&draw_info->affine,exception);
10044 draw_info=DestroyDrawInfo(draw_info);
10045 break;
10046 }
10047 case 76: /* Difference */
10048 {
10049 if (attribute_flag[0] == 0)
10050 {
10051 ThrowPerlException(exception,OptionError,
10052 "ReferenceImageRequired",PackageName);
10053 goto PerlException;
10054 }
10055 if (attribute_flag[1] != 0)
10056 image->fuzz=StringToDoubleInterval(
10057 argument_list[1].string_reference,(double) QuantumRange+1.0);
Cristyf2479812015-12-12 12:17:43 -050010058 (void) SetImageColorMetric(image,argument_list[0].image_reference,
cristy4a3ce0a2013-08-03 20:06:59 +000010059 exception);
10060 break;
10061 }
10062 case 77: /* AdaptiveThreshold */
10063 {
10064 if (attribute_flag[0] != 0)
10065 {
10066 flags=ParseGeometry(argument_list[0].string_reference,
10067 &geometry_info);
10068 if ((flags & PercentValue) != 0)
10069 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10070 }
10071 if (attribute_flag[1] != 0)
10072 geometry_info.rho=argument_list[1].integer_reference;
10073 if (attribute_flag[2] != 0)
10074 geometry_info.sigma=argument_list[2].integer_reference;
10075 if (attribute_flag[3] != 0)
10076 geometry_info.xi=argument_list[3].integer_reference;;
10077 image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
10078 (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
10079 break;
10080 }
10081 case 78: /* Resample */
10082 {
10083 size_t
10084 height,
10085 width;
10086
10087 if (attribute_flag[0] != 0)
10088 {
10089 flags=ParseGeometry(argument_list[0].string_reference,
10090 &geometry_info);
10091 if ((flags & SigmaValue) == 0)
10092 geometry_info.sigma=geometry_info.rho;
10093 }
10094 if (attribute_flag[1] != 0)
10095 geometry_info.rho=argument_list[1].real_reference;
10096 if (attribute_flag[2] != 0)
10097 geometry_info.sigma=argument_list[2].real_reference;
10098 if (attribute_flag[3] == 0)
10099 argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
10100 if (attribute_flag[4] == 0)
10101 SetImageArtifact(image,"filter:support",
10102 argument_list[4].string_reference);
10103 width=(size_t) (geometry_info.rho*image->columns/
10104 (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
10105 height=(size_t) (geometry_info.sigma*image->rows/
10106 (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
Cristy8645e042016-02-03 16:35:29 -050010107 image=ResizeImage(image,width,height,(FilterType)
cristy4a3ce0a2013-08-03 20:06:59 +000010108 argument_list[3].integer_reference,exception);
10109 if (image != (Image *) NULL)
10110 {
10111 image->resolution.x=geometry_info.rho;
10112 image->resolution.y=geometry_info.sigma;
10113 }
10114 break;
10115 }
10116 case 79: /* Describe */
10117 {
10118 if (attribute_flag[0] == 0)
10119 argument_list[0].file_reference=(FILE *) NULL;
cristy4a3ce0a2013-08-03 20:06:59 +000010120 (void) IdentifyImage(image,argument_list[0].file_reference,
10121 MagickTrue,exception);
10122 break;
10123 }
10124 case 80: /* BlackThreshold */
10125 {
10126 if (attribute_flag[0] == 0)
10127 argument_list[0].string_reference="50%";
10128 if (attribute_flag[2] != 0)
10129 channel=(ChannelType) argument_list[2].integer_reference;
10130 channel_mask=SetImageChannelMask(image,channel);
Cristy89b4db02020-02-21 20:57:40 -050010131 (void) BlackThresholdImage(image,argument_list[0].string_reference,
cristy4a3ce0a2013-08-03 20:06:59 +000010132 exception);
10133 (void) SetImageChannelMask(image,channel_mask);
10134 break;
10135 }
10136 case 81: /* WhiteThreshold */
10137 {
10138 if (attribute_flag[0] == 0)
10139 argument_list[0].string_reference="50%";
10140 if (attribute_flag[2] != 0)
10141 channel=(ChannelType) argument_list[2].integer_reference;
10142 channel_mask=SetImageChannelMask(image,channel);
10143 WhiteThresholdImage(image,argument_list[0].string_reference,
10144 exception);
10145 (void) SetImageChannelMask(image,channel_mask);
10146 break;
10147 }
cristy60c73c02014-03-25 12:09:58 +000010148 case 82: /* RotationalBlur */
cristy4a3ce0a2013-08-03 20:06:59 +000010149 {
10150 if (attribute_flag[0] != 0)
10151 {
10152 flags=ParseGeometry(argument_list[0].string_reference,
10153 &geometry_info);
10154 }
10155 if (attribute_flag[1] != 0)
10156 geometry_info.rho=argument_list[1].real_reference;
10157 if (attribute_flag[2] != 0)
10158 channel=(ChannelType) argument_list[2].integer_reference;
10159 channel_mask=SetImageChannelMask(image,channel);
cristy49d4d222014-03-16 00:37:58 +000010160 image=RotationalBlurImage(image,geometry_info.rho,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010161 if (image != (Image *) NULL)
10162 (void) SetImageChannelMask(image,channel_mask);
10163 break;
10164 }
10165 case 83: /* Thumbnail */
10166 {
10167 if (attribute_flag[0] != 0)
10168 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10169 &geometry,exception);
10170 if (attribute_flag[1] != 0)
10171 geometry.width=argument_list[1].integer_reference;
10172 if (attribute_flag[2] != 0)
10173 geometry.height=argument_list[2].integer_reference;
10174 image=ThumbnailImage(image,geometry.width,geometry.height,exception);
10175 break;
10176 }
10177 case 84: /* Strip */
10178 {
10179 (void) StripImage(image,exception);
10180 break;
10181 }
10182 case 85: /* Tint */
10183 {
10184 PixelInfo
10185 tint;
10186
10187 GetPixelInfo(image,&tint);
10188 if (attribute_flag[0] != 0)
10189 (void) QueryColorCompliance(argument_list[0].string_reference,
10190 AllCompliance,&tint,exception);
10191 if (attribute_flag[1] == 0)
10192 argument_list[1].string_reference="100";
10193 image=TintImage(image,argument_list[1].string_reference,&tint,
10194 exception);
10195 break;
10196 }
10197 case 86: /* Channel */
10198 {
10199 if (attribute_flag[0] != 0)
10200 channel=(ChannelType) argument_list[0].integer_reference;
10201 image=SeparateImage(image,channel,exception);
10202 break;
10203 }
10204 case 87: /* Splice */
10205 {
cristy260bd762014-08-15 12:46:34 +000010206 if (attribute_flag[7] != 0)
10207 image->gravity=(GravityType) argument_list[7].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010208 if (attribute_flag[0] != 0)
10209 flags=ParseGravityGeometry(image,argument_list[0].string_reference,
10210 &geometry,exception);
10211 if (attribute_flag[1] != 0)
10212 geometry.width=argument_list[1].integer_reference;
10213 if (attribute_flag[2] != 0)
10214 geometry.height=argument_list[2].integer_reference;
10215 if (attribute_flag[3] != 0)
10216 geometry.x=argument_list[3].integer_reference;
10217 if (attribute_flag[4] != 0)
10218 geometry.y=argument_list[4].integer_reference;
10219 if (attribute_flag[5] != 0)
10220 image->fuzz=StringToDoubleInterval(
10221 argument_list[5].string_reference,(double) QuantumRange+1.0);
10222 if (attribute_flag[6] != 0)
10223 (void) QueryColorCompliance(argument_list[6].string_reference,
10224 AllCompliance,&image->background_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010225 image=SpliceImage(image,&geometry,exception);
10226 break;
10227 }
10228 case 88: /* Posterize */
10229 {
10230 if (attribute_flag[0] == 0)
10231 argument_list[0].integer_reference=3;
10232 if (attribute_flag[1] == 0)
10233 argument_list[1].integer_reference=0;
10234 (void) PosterizeImage(image,argument_list[0].integer_reference,
10235 argument_list[1].integer_reference ? RiemersmaDitherMethod :
10236 NoDitherMethod,exception);
10237 break;
10238 }
10239 case 89: /* Shadow */
10240 {
10241 if (attribute_flag[0] != 0)
10242 {
10243 flags=ParseGeometry(argument_list[0].string_reference,
10244 &geometry_info);
10245 if ((flags & SigmaValue) == 0)
10246 geometry_info.sigma=1.0;
10247 if ((flags & XiValue) == 0)
10248 geometry_info.xi=4.0;
10249 if ((flags & PsiValue) == 0)
10250 geometry_info.psi=4.0;
10251 }
10252 if (attribute_flag[1] != 0)
10253 geometry_info.rho=argument_list[1].real_reference;
10254 if (attribute_flag[2] != 0)
10255 geometry_info.sigma=argument_list[2].real_reference;
10256 if (attribute_flag[3] != 0)
10257 geometry_info.xi=argument_list[3].integer_reference;
10258 if (attribute_flag[4] != 0)
10259 geometry_info.psi=argument_list[4].integer_reference;
10260 image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
10261 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10262 ceil(geometry_info.psi-0.5),exception);
10263 break;
10264 }
10265 case 90: /* Identify */
10266 {
10267 if (attribute_flag[0] == 0)
10268 argument_list[0].file_reference=(FILE *) NULL;
10269 if (attribute_flag[1] != 0)
10270 (void) SetImageArtifact(image,"identify:features",
10271 argument_list[1].string_reference);
10272 if ((attribute_flag[2] != 0) &&
10273 (argument_list[2].integer_reference != 0))
Cristy8b3ffe62020-02-17 12:36:53 -050010274 (void) SetImageArtifact(image,"identify:moments","true");
10275 if ((attribute_flag[3] != 0) &&
10276 (argument_list[3].integer_reference != 0))
cristy4a3ce0a2013-08-03 20:06:59 +000010277 (void) SetImageArtifact(image,"identify:unique","true");
10278 (void) IdentifyImage(image,argument_list[0].file_reference,
10279 MagickTrue,exception);
10280 break;
10281 }
10282 case 91: /* SepiaTone */
10283 {
10284 if (attribute_flag[0] == 0)
10285 argument_list[0].real_reference=80.0*QuantumRange/100.0;
10286 image=SepiaToneImage(image,argument_list[0].real_reference,
10287 exception);
10288 break;
10289 }
10290 case 92: /* SigmoidalContrast */
10291 {
10292 MagickBooleanType
10293 sharpen;
10294
10295 if (attribute_flag[0] != 0)
10296 {
10297 flags=ParseGeometry(argument_list[0].string_reference,
10298 &geometry_info);
10299 if ((flags & SigmaValue) == 0)
10300 geometry_info.sigma=QuantumRange/2.0;
10301 if ((flags & PercentValue) != 0)
10302 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
10303 }
10304 if (attribute_flag[1] != 0)
10305 geometry_info.rho=argument_list[1].real_reference;
10306 if (attribute_flag[2] != 0)
10307 geometry_info.sigma=argument_list[2].real_reference;
10308 if (attribute_flag[3] != 0)
10309 channel=(ChannelType) argument_list[3].integer_reference;
10310 sharpen=MagickTrue;
10311 if (attribute_flag[4] != 0)
10312 sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
10313 MagickFalse;
10314 channel_mask=SetImageChannelMask(image,channel);
10315 (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
10316 geometry_info.sigma,exception);
10317 (void) SetImageChannelMask(image,channel_mask);
10318 break;
10319 }
10320 case 93: /* Extent */
10321 {
10322 if (attribute_flag[7] != 0)
10323 image->gravity=(GravityType) argument_list[7].integer_reference;
10324 if (attribute_flag[0] != 0)
10325 {
10326 int
10327 flags;
10328
10329 flags=ParseGravityGeometry(image,
10330 argument_list[0].string_reference,&geometry,exception);
10331 (void) flags;
10332 if (geometry.width == 0)
10333 geometry.width=image->columns;
10334 if (geometry.height == 0)
10335 geometry.height=image->rows;
10336 }
10337 if (attribute_flag[1] != 0)
10338 geometry.width=argument_list[1].integer_reference;
10339 if (attribute_flag[2] != 0)
10340 geometry.height=argument_list[2].integer_reference;
10341 if (attribute_flag[3] != 0)
10342 geometry.x=argument_list[3].integer_reference;
10343 if (attribute_flag[4] != 0)
10344 geometry.y=argument_list[4].integer_reference;
10345 if (attribute_flag[5] != 0)
10346 image->fuzz=StringToDoubleInterval(
10347 argument_list[5].string_reference,(double) QuantumRange+1.0);
10348 if (attribute_flag[6] != 0)
10349 (void) QueryColorCompliance(argument_list[6].string_reference,
10350 AllCompliance,&image->background_color,exception);
10351 image=ExtentImage(image,&geometry,exception);
10352 break;
10353 }
10354 case 94: /* Vignette */
10355 {
10356 if (attribute_flag[0] != 0)
10357 {
10358 flags=ParseGeometry(argument_list[0].string_reference,
10359 &geometry_info);
10360 if ((flags & SigmaValue) == 0)
10361 geometry_info.sigma=1.0;
10362 if ((flags & XiValue) == 0)
10363 geometry_info.xi=0.1*image->columns;
10364 if ((flags & PsiValue) == 0)
10365 geometry_info.psi=0.1*image->rows;
10366 }
10367 if (attribute_flag[1] != 0)
10368 geometry_info.rho=argument_list[1].real_reference;
10369 if (attribute_flag[2] != 0)
10370 geometry_info.sigma=argument_list[2].real_reference;
10371 if (attribute_flag[3] != 0)
10372 geometry_info.xi=argument_list[3].integer_reference;
10373 if (attribute_flag[4] != 0)
10374 geometry_info.psi=argument_list[4].integer_reference;
10375 if (attribute_flag[5] != 0)
10376 (void) QueryColorCompliance(argument_list[5].string_reference,
10377 AllCompliance,&image->background_color,exception);
10378 image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
10379 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
10380 ceil(geometry_info.psi-0.5),exception);
10381 break;
10382 }
10383 case 95: /* ContrastStretch */
10384 {
10385 double
10386 black_point,
10387 white_point;
10388
10389 black_point=0.0;
10390 white_point=(double) image->columns*image->rows;
10391 if (attribute_flag[0] != 0)
10392 {
10393 flags=ParseGeometry(argument_list[0].string_reference,
10394 &geometry_info);
10395 black_point=geometry_info.rho;
10396 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
10397 black_point;
10398 if ((flags & PercentValue) != 0)
10399 {
10400 black_point*=(double) image->columns*image->rows/100.0;
10401 white_point*=(double) image->columns*image->rows/100.0;
10402 }
10403 white_point=(double) image->columns*image->rows-
10404 white_point;
10405 }
10406 if (attribute_flag[1] != 0)
10407 black_point=argument_list[1].real_reference;
10408 if (attribute_flag[2] != 0)
10409 white_point=argument_list[2].real_reference;
10410 if (attribute_flag[4] != 0)
10411 channel=(ChannelType) argument_list[4].integer_reference;
10412 channel_mask=SetImageChannelMask(image,channel);
10413 (void) ContrastStretchImage(image,black_point,white_point,exception);
10414 (void) SetImageChannelMask(image,channel_mask);
10415 break;
10416 }
10417 case 96: /* Sans0 */
10418 {
10419 break;
10420 }
10421 case 97: /* Sans1 */
10422 {
10423 break;
10424 }
10425 case 98: /* AdaptiveSharpen */
10426 {
10427 if (attribute_flag[0] != 0)
10428 {
10429 flags=ParseGeometry(argument_list[0].string_reference,
10430 &geometry_info);
10431 if ((flags & SigmaValue) == 0)
10432 geometry_info.sigma=1.0;
10433 if ((flags & XiValue) == 0)
10434 geometry_info.xi=0.0;
10435 }
10436 if (attribute_flag[1] != 0)
10437 geometry_info.rho=argument_list[1].real_reference;
10438 if (attribute_flag[2] != 0)
10439 geometry_info.sigma=argument_list[2].real_reference;
10440 if (attribute_flag[3] != 0)
10441 geometry_info.xi=argument_list[3].real_reference;
10442 if (attribute_flag[4] != 0)
10443 channel=(ChannelType) argument_list[4].integer_reference;
10444 channel_mask=SetImageChannelMask(image,channel);
10445 image=AdaptiveSharpenImage(image,geometry_info.rho,
10446 geometry_info.sigma,exception);
10447 if (image != (Image *) NULL)
10448 (void) SetImageChannelMask(image,channel_mask);
10449 break;
10450 }
10451 case 99: /* Transpose */
10452 {
10453 image=TransposeImage(image,exception);
10454 break;
10455 }
10456 case 100: /* Tranverse */
10457 {
10458 image=TransverseImage(image,exception);
10459 break;
10460 }
10461 case 101: /* AutoOrient */
10462 {
10463 image=AutoOrientImage(image,image->orientation,exception);
10464 break;
10465 }
10466 case 102: /* AdaptiveBlur */
10467 {
10468 if (attribute_flag[0] != 0)
10469 {
10470 flags=ParseGeometry(argument_list[0].string_reference,
10471 &geometry_info);
10472 if ((flags & SigmaValue) == 0)
10473 geometry_info.sigma=1.0;
10474 if ((flags & XiValue) == 0)
10475 geometry_info.xi=0.0;
10476 }
10477 if (attribute_flag[1] != 0)
10478 geometry_info.rho=argument_list[1].real_reference;
10479 if (attribute_flag[2] != 0)
10480 geometry_info.sigma=argument_list[2].real_reference;
10481 if (attribute_flag[3] != 0)
10482 channel=(ChannelType) argument_list[3].integer_reference;
10483 channel_mask=SetImageChannelMask(image,channel);
10484 image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10485 exception);
10486 if (image != (Image *) NULL)
10487 (void) SetImageChannelMask(image,channel_mask);
10488 break;
10489 }
10490 case 103: /* Sketch */
10491 {
10492 if (attribute_flag[0] != 0)
10493 {
10494 flags=ParseGeometry(argument_list[0].string_reference,
10495 &geometry_info);
10496 if ((flags & SigmaValue) == 0)
10497 geometry_info.sigma=1.0;
10498 if ((flags & XiValue) == 0)
10499 geometry_info.xi=1.0;
10500 }
10501 if (attribute_flag[1] != 0)
10502 geometry_info.rho=argument_list[1].real_reference;
10503 if (attribute_flag[2] != 0)
10504 geometry_info.sigma=argument_list[2].real_reference;
10505 if (attribute_flag[3] != 0)
10506 geometry_info.xi=argument_list[3].real_reference;
10507 image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
10508 geometry_info.xi,exception);
10509 break;
10510 }
10511 case 104: /* UniqueColors */
10512 {
10513 image=UniqueImageColors(image,exception);
10514 break;
10515 }
10516 case 105: /* AdaptiveResize */
10517 {
10518 if (attribute_flag[0] != 0)
10519 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10520 &geometry,exception);
10521 if (attribute_flag[1] != 0)
10522 geometry.width=argument_list[1].integer_reference;
10523 if (attribute_flag[2] != 0)
10524 geometry.height=argument_list[2].integer_reference;
10525 if (attribute_flag[3] != 0)
Cristy8645e042016-02-03 16:35:29 -050010526 image->filter=(FilterType) argument_list[4].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010527 if (attribute_flag[4] != 0)
10528 SetImageArtifact(image,"filter:support",
10529 argument_list[4].string_reference);
10530 image=AdaptiveResizeImage(image,geometry.width,geometry.height,
10531 exception);
10532 break;
10533 }
10534 case 106: /* ClipMask */
10535 {
10536 Image
10537 *mask_image;
10538
10539 if (attribute_flag[0] == 0)
10540 {
10541 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10542 PackageName);
10543 goto PerlException;
10544 }
10545 mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
10546 exception);
cristy1f7ffb72015-07-29 11:07:03 +000010547 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010548 mask_image=DestroyImage(mask_image);
10549 break;
10550 }
10551 case 107: /* LinearStretch */
10552 {
10553 double
10554 black_point,
10555 white_point;
10556
10557 black_point=0.0;
10558 white_point=(double) image->columns*image->rows;
10559 if (attribute_flag[0] != 0)
10560 {
10561 flags=ParseGeometry(argument_list[0].string_reference,
10562 &geometry_info);
10563 if ((flags & SigmaValue) != 0)
10564 white_point=geometry_info.sigma;
10565 if ((flags & PercentValue) != 0)
10566 {
10567 black_point*=(double) image->columns*image->rows/100.0;
10568 white_point*=(double) image->columns*image->rows/100.0;
10569 }
10570 if ((flags & SigmaValue) == 0)
10571 white_point=(double) image->columns*image->rows-black_point;
10572 }
10573 if (attribute_flag[1] != 0)
10574 black_point=argument_list[1].real_reference;
10575 if (attribute_flag[2] != 0)
10576 white_point=argument_list[2].real_reference;
10577 (void) LinearStretchImage(image,black_point,white_point,exception);
10578 break;
10579 }
10580 case 108: /* ColorMatrix */
10581 {
10582 AV
10583 *av;
10584
10585 double
10586 *color_matrix;
10587
10588 KernelInfo
10589 *kernel_info;
10590
10591 size_t
10592 order;
10593
10594 if (attribute_flag[0] == 0)
10595 break;
10596 av=(AV *) argument_list[0].array_reference;
10597 order=(size_t) sqrt(av_len(av)+1);
10598 color_matrix=(double *) AcquireQuantumMemory(order,order*
10599 sizeof(*color_matrix));
10600 if (color_matrix == (double *) NULL)
10601 {
10602 ThrowPerlException(exception,ResourceLimitFatalError,
10603 "MemoryAllocationFailed",PackageName);
10604 goto PerlException;
10605 }
10606 for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
10607 color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
10608 for ( ; j < (ssize_t) (order*order); j++)
10609 color_matrix[j]=0.0;
cristy2c57b742014-10-31 00:40:34 +000010610 kernel_info=AcquireKernelInfo((const char *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010611 if (kernel_info == (KernelInfo *) NULL)
10612 break;
10613 kernel_info->width=order;
10614 kernel_info->height=order;
10615 kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
10616 order*sizeof(*kernel_info->values));
10617 if (kernel_info->values != (MagickRealType *) NULL)
10618 {
10619 for (i=0; i < (ssize_t) (order*order); i++)
10620 kernel_info->values[i]=(MagickRealType) color_matrix[i];
10621 image=ColorMatrixImage(image,kernel_info,exception);
10622 }
10623 kernel_info=DestroyKernelInfo(kernel_info);
10624 color_matrix=(double *) RelinquishMagickMemory(color_matrix);
10625 break;
10626 }
10627 case 109: /* Mask */
10628 {
10629 Image
10630 *mask_image;
10631
10632 if (attribute_flag[0] == 0)
10633 {
10634 ThrowPerlException(exception,OptionError,"MaskImageRequired",
10635 PackageName);
10636 goto PerlException;
10637 }
10638 mask_image=CloneImage(argument_list[0].image_reference,0,0,
10639 MagickTrue,exception);
cristy1f7ffb72015-07-29 11:07:03 +000010640 (void) SetImageMask(image,ReadPixelMask,mask_image,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000010641 mask_image=DestroyImage(mask_image);
10642 break;
10643 }
10644 case 110: /* Polaroid */
10645 {
10646 char
10647 *caption;
10648
10649 DrawInfo
10650 *draw_info;
10651
10652 double
10653 angle;
10654
10655 PixelInterpolateMethod
10656 method;
10657
10658 draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
10659 (DrawInfo *) NULL);
10660 caption=(char *) NULL;
10661 if (attribute_flag[0] != 0)
10662 caption=InterpretImageProperties(info ? info->image_info :
10663 (ImageInfo *) NULL,image,argument_list[0].string_reference,
10664 exception);
10665 angle=0.0;
10666 if (attribute_flag[1] != 0)
10667 angle=argument_list[1].real_reference;
10668 if (attribute_flag[2] != 0)
10669 (void) CloneString(&draw_info->font,
10670 argument_list[2].string_reference);
10671 if (attribute_flag[3] != 0)
10672 (void) QueryColorCompliance(argument_list[3].string_reference,
10673 AllCompliance,&draw_info->stroke,exception);
10674 if (attribute_flag[4] != 0)
10675 (void) QueryColorCompliance(argument_list[4].string_reference,
10676 AllCompliance,&draw_info->fill,exception);
10677 if (attribute_flag[5] != 0)
10678 draw_info->stroke_width=argument_list[5].real_reference;
10679 if (attribute_flag[6] != 0)
10680 draw_info->pointsize=argument_list[6].real_reference;
10681 if (attribute_flag[7] != 0)
10682 draw_info->gravity=(GravityType) argument_list[7].integer_reference;
10683 if (attribute_flag[8] != 0)
10684 (void) QueryColorCompliance(argument_list[8].string_reference,
10685 AllCompliance,&image->background_color,exception);
10686 method=UndefinedInterpolatePixel;
10687 if (attribute_flag[9] != 0)
10688 method=(PixelInterpolateMethod) argument_list[9].integer_reference;
10689 image=PolaroidImage(image,draw_info,caption,angle,method,exception);
10690 draw_info=DestroyDrawInfo(draw_info);
10691 if (caption != (char *) NULL)
10692 caption=DestroyString(caption);
10693 break;
10694 }
10695 case 111: /* FloodfillPaint */
10696 {
10697 DrawInfo
10698 *draw_info;
10699
10700 MagickBooleanType
10701 invert;
10702
10703 PixelInfo
10704 target;
10705
10706 draw_info=CloneDrawInfo(info ? info->image_info :
10707 (ImageInfo *) NULL,(DrawInfo *) NULL);
10708 if (attribute_flag[0] != 0)
10709 flags=ParsePageGeometry(image,argument_list[0].string_reference,
10710 &geometry,exception);
10711 if (attribute_flag[1] != 0)
10712 geometry.x=argument_list[1].integer_reference;
10713 if (attribute_flag[2] != 0)
10714 geometry.y=argument_list[2].integer_reference;
10715 if (attribute_flag[3] != 0)
10716 (void) QueryColorCompliance(argument_list[3].string_reference,
10717 AllCompliance,&draw_info->fill,exception);
10718 (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
10719 geometry.x,geometry.y,&target,exception);
10720 if (attribute_flag[4] != 0)
10721 QueryColorCompliance(argument_list[4].string_reference,
10722 AllCompliance,&target,exception);
10723 if (attribute_flag[5] != 0)
10724 image->fuzz=StringToDoubleInterval(
10725 argument_list[5].string_reference,(double) QuantumRange+1.0);
10726 if (attribute_flag[6] != 0)
10727 channel=(ChannelType) argument_list[6].integer_reference;
10728 invert=MagickFalse;
10729 if (attribute_flag[7] != 0)
10730 invert=(MagickBooleanType) argument_list[7].integer_reference;
10731 channel_mask=SetImageChannelMask(image,channel);
10732 (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
10733 geometry.y,invert,exception);
10734 (void) SetImageChannelMask(image,channel_mask);
10735 draw_info=DestroyDrawInfo(draw_info);
10736 break;
10737 }
10738 case 112: /* Distort */
10739 {
10740 AV
10741 *av;
10742
10743 double
10744 *coordinates;
10745
Cristy8645e042016-02-03 16:35:29 -050010746 DistortMethod
cristy4a3ce0a2013-08-03 20:06:59 +000010747 method;
10748
10749 size_t
10750 number_coordinates;
10751
10752 VirtualPixelMethod
10753 virtual_pixel;
10754
10755 if (attribute_flag[0] == 0)
10756 break;
10757 method=UndefinedDistortion;
10758 if (attribute_flag[1] != 0)
Cristy8645e042016-02-03 16:35:29 -050010759 method=(DistortMethod) argument_list[1].integer_reference;
cristy4a3ce0a2013-08-03 20:06:59 +000010760 av=(AV *) argument_list[0].array_reference;
10761 number_coordinates=(size_t) av_len(av)+1;
10762 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10763 sizeof(*coordinates));
10764 if (coordinates == (double *) NULL)
10765 {
10766 ThrowPerlException(exception,ResourceLimitFatalError,
10767 "MemoryAllocationFailed",PackageName);
10768 goto PerlException;
10769 }
10770 for (j=0; j < (ssize_t) number_coordinates; j++)
10771 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10772 virtual_pixel=UndefinedVirtualPixelMethod;
10773 if (attribute_flag[2] != 0)
10774 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10775 argument_list[2].integer_reference,exception);
10776 image=DistortImage(image,method,number_coordinates,coordinates,
10777 argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
10778 exception);
10779 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10780 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10781 exception);
10782 coordinates=(double *) RelinquishMagickMemory(coordinates);
10783 break;
10784 }
10785 case 113: /* Clut */
10786 {
10787 PixelInterpolateMethod
10788 method;
10789
10790 if (attribute_flag[0] == 0)
10791 {
10792 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10793 PackageName);
10794 goto PerlException;
10795 }
10796 method=UndefinedInterpolatePixel;
10797 if (attribute_flag[1] != 0)
10798 method=(PixelInterpolateMethod) argument_list[1].integer_reference;
10799 if (attribute_flag[2] != 0)
10800 channel=(ChannelType) argument_list[2].integer_reference;
10801 channel_mask=SetImageChannelMask(image,channel);
10802 (void) ClutImage(image,argument_list[0].image_reference,method,
10803 exception);
10804 (void) SetImageChannelMask(image,channel_mask);
10805 break;
10806 }
10807 case 114: /* LiquidRescale */
10808 {
10809 if (attribute_flag[0] != 0)
10810 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
10811 &geometry,exception);
10812 if (attribute_flag[1] != 0)
10813 geometry.width=argument_list[1].integer_reference;
10814 if (attribute_flag[2] != 0)
10815 geometry.height=argument_list[2].integer_reference;
10816 if (attribute_flag[3] == 0)
10817 argument_list[3].real_reference=1.0;
10818 if (attribute_flag[4] == 0)
10819 argument_list[4].real_reference=0.0;
10820 image=LiquidRescaleImage(image,geometry.width,geometry.height,
10821 argument_list[3].real_reference,argument_list[4].real_reference,
10822 exception);
10823 break;
10824 }
10825 case 115: /* EncipherImage */
10826 {
10827 (void) EncipherImage(image,argument_list[0].string_reference,
10828 exception);
10829 break;
10830 }
10831 case 116: /* DecipherImage */
10832 {
10833 (void) DecipherImage(image,argument_list[0].string_reference,
10834 exception);
10835 break;
10836 }
10837 case 117: /* Deskew */
10838 {
10839 geometry_info.rho=QuantumRange/2.0;
10840 if (attribute_flag[0] != 0)
10841 flags=ParseGeometry(argument_list[0].string_reference,
10842 &geometry_info);
10843 if (attribute_flag[1] != 0)
10844 geometry_info.rho=StringToDoubleInterval(
10845 argument_list[1].string_reference,(double) QuantumRange+1.0);
10846 image=DeskewImage(image,geometry_info.rho,exception);
10847 break;
10848 }
10849 case 118: /* Remap */
10850 {
10851 QuantizeInfo
10852 *quantize_info;
10853
10854 if (attribute_flag[0] == 0)
10855 {
10856 ThrowPerlException(exception,OptionError,"RemapImageRequired",
10857 PackageName);
10858 goto PerlException;
10859 }
10860 quantize_info=AcquireQuantizeInfo(info->image_info);
10861 if (attribute_flag[1] != 0)
10862 quantize_info->dither_method=(DitherMethod)
10863 argument_list[1].integer_reference;
10864 (void) RemapImages(quantize_info,image,
10865 argument_list[0].image_reference,exception);
10866 quantize_info=DestroyQuantizeInfo(quantize_info);
10867 break;
10868 }
10869 case 119: /* SparseColor */
10870 {
10871 AV
10872 *av;
10873
10874 double
10875 *coordinates;
10876
10877 SparseColorMethod
10878 method;
10879
10880 size_t
10881 number_coordinates;
10882
10883 VirtualPixelMethod
10884 virtual_pixel;
10885
10886 if (attribute_flag[0] == 0)
10887 break;
10888 method=UndefinedColorInterpolate;
10889 if (attribute_flag[1] != 0)
10890 method=(SparseColorMethod) argument_list[1].integer_reference;
10891 av=(AV *) argument_list[0].array_reference;
10892 number_coordinates=(size_t) av_len(av)+1;
10893 coordinates=(double *) AcquireQuantumMemory(number_coordinates,
10894 sizeof(*coordinates));
10895 if (coordinates == (double *) NULL)
10896 {
10897 ThrowPerlException(exception,ResourceLimitFatalError,
10898 "MemoryAllocationFailed",PackageName);
10899 goto PerlException;
10900 }
10901 for (j=0; j < (ssize_t) number_coordinates; j++)
10902 coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
10903 virtual_pixel=UndefinedVirtualPixelMethod;
10904 if (attribute_flag[2] != 0)
10905 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10906 argument_list[2].integer_reference,exception);
10907 if (attribute_flag[3] != 0)
10908 channel=(ChannelType) argument_list[3].integer_reference;
10909 channel_mask=SetImageChannelMask(image,channel);
10910 image=SparseColorImage(image,method,number_coordinates,coordinates,
10911 exception);
10912 if (image != (Image *) NULL)
10913 (void) SetImageChannelMask(image,channel_mask);
10914 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10915 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10916 exception);
10917 coordinates=(double *) RelinquishMagickMemory(coordinates);
10918 break;
10919 }
10920 case 120: /* Function */
10921 {
10922 AV
10923 *av;
10924
10925 double
10926 *parameters;
10927
10928 MagickFunction
10929 function;
10930
10931 size_t
10932 number_parameters;
10933
10934 VirtualPixelMethod
10935 virtual_pixel;
10936
10937 if (attribute_flag[0] == 0)
10938 break;
10939 function=UndefinedFunction;
10940 if (attribute_flag[1] != 0)
10941 function=(MagickFunction) argument_list[1].integer_reference;
10942 av=(AV *) argument_list[0].array_reference;
10943 number_parameters=(size_t) av_len(av)+1;
10944 parameters=(double *) AcquireQuantumMemory(number_parameters,
10945 sizeof(*parameters));
10946 if (parameters == (double *) NULL)
10947 {
10948 ThrowPerlException(exception,ResourceLimitFatalError,
10949 "MemoryAllocationFailed",PackageName);
10950 goto PerlException;
10951 }
10952 for (j=0; j < (ssize_t) number_parameters; j++)
10953 parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
10954 virtual_pixel=UndefinedVirtualPixelMethod;
10955 if (attribute_flag[2] != 0)
10956 virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
10957 argument_list[2].integer_reference,exception);
10958 (void) FunctionImage(image,function,number_parameters,parameters,
10959 exception);
10960 if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
10961 virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
10962 exception);
10963 parameters=(double *) RelinquishMagickMemory(parameters);
10964 break;
10965 }
10966 case 121: /* SelectiveBlur */
10967 {
10968 if (attribute_flag[0] != 0)
10969 {
10970 flags=ParseGeometry(argument_list[0].string_reference,
10971 &geometry_info);
10972 if ((flags & SigmaValue) == 0)
10973 geometry_info.sigma=1.0;
10974 if ((flags & PercentValue) != 0)
10975 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
10976 }
10977 if (attribute_flag[1] != 0)
10978 geometry_info.rho=argument_list[1].real_reference;
10979 if (attribute_flag[2] != 0)
10980 geometry_info.sigma=argument_list[2].real_reference;
10981 if (attribute_flag[3] != 0)
10982 geometry_info.xi=argument_list[3].integer_reference;;
10983 if (attribute_flag[5] != 0)
10984 channel=(ChannelType) argument_list[5].integer_reference;
10985 channel_mask=SetImageChannelMask(image,channel);
10986 image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
10987 geometry_info.xi,exception);
10988 if (image != (Image *) NULL)
10989 (void) SetImageChannelMask(image,channel_mask);
10990 break;
10991 }
10992 case 122: /* HaldClut */
10993 {
10994 if (attribute_flag[0] == 0)
10995 {
10996 ThrowPerlException(exception,OptionError,"ClutImageRequired",
10997 PackageName);
10998 goto PerlException;
10999 }
11000 if (attribute_flag[1] != 0)
11001 channel=(ChannelType) argument_list[1].integer_reference;
11002 channel_mask=SetImageChannelMask(image,channel);
11003 (void) HaldClutImage(image,argument_list[0].image_reference,
11004 exception);
11005 (void) SetImageChannelMask(image,channel_mask);
11006 break;
11007 }
11008 case 123: /* BlueShift */
11009 {
11010 if (attribute_flag[0] != 0)
11011 (void) ParseGeometry(argument_list[0].string_reference,
11012 &geometry_info);
11013 image=BlueShiftImage(image,geometry_info.rho,exception);
11014 break;
11015 }
11016 case 124: /* ForwardFourierTransformImage */
11017 {
11018 image=ForwardFourierTransformImage(image,
11019 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
11020 exception);
11021 break;
11022 }
11023 case 125: /* InverseFourierTransformImage */
11024 {
11025 image=InverseFourierTransformImage(image,image->next,
11026 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
11027 exception);
11028 break;
11029 }
11030 case 126: /* ColorDecisionList */
11031 {
11032 if (attribute_flag[0] == 0)
11033 argument_list[0].string_reference=(char *) NULL;
11034 (void) ColorDecisionListImage(image,
11035 argument_list[0].string_reference,exception);
11036 break;
11037 }
11038 case 127: /* AutoGamma */
11039 {
11040 if (attribute_flag[0] != 0)
11041 channel=(ChannelType) argument_list[0].integer_reference;
11042 channel_mask=SetImageChannelMask(image,channel);
11043 (void) AutoGammaImage(image,exception);
11044 (void) SetImageChannelMask(image,channel_mask);
11045 break;
11046 }
11047 case 128: /* AutoLevel */
11048 {
11049 if (attribute_flag[0] != 0)
11050 channel=(ChannelType) argument_list[0].integer_reference;
11051 channel_mask=SetImageChannelMask(image,channel);
11052 (void) AutoLevelImage(image,exception);
11053 (void) SetImageChannelMask(image,channel_mask);
11054 break;
11055 }
11056 case 129: /* LevelColors */
11057 {
11058 PixelInfo
11059 black_point,
11060 white_point;
11061
11062 (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
11063 exception);
11064 (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
11065 exception);
11066 if (attribute_flag[1] != 0)
11067 (void) QueryColorCompliance(
11068 argument_list[1].string_reference,AllCompliance,&black_point,
11069 exception);
11070 if (attribute_flag[2] != 0)
11071 (void) QueryColorCompliance(
11072 argument_list[2].string_reference,AllCompliance,&white_point,
11073 exception);
11074 if (attribute_flag[3] != 0)
11075 channel=(ChannelType) argument_list[3].integer_reference;
11076 channel_mask=SetImageChannelMask(image,channel);
11077 (void) LevelImageColors(image,&black_point,&white_point,
11078 argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
11079 exception);
11080 (void) SetImageChannelMask(image,channel_mask);
11081 break;
11082 }
11083 case 130: /* Clamp */
11084 {
11085 if (attribute_flag[0] != 0)
11086 channel=(ChannelType) argument_list[0].integer_reference;
11087 channel_mask=SetImageChannelMask(image,channel);
11088 (void) ClampImage(image,exception);
11089 (void) SetImageChannelMask(image,channel_mask);
11090 break;
11091 }
11092 case 131: /* BrightnessContrast */
11093 {
11094 double
11095 brightness,
11096 contrast;
11097
11098 brightness=0.0;
11099 contrast=0.0;
11100 if (attribute_flag[0] != 0)
11101 {
11102 flags=ParseGeometry(argument_list[0].string_reference,
11103 &geometry_info);
11104 brightness=geometry_info.rho;
11105 if ((flags & SigmaValue) == 0)
11106 contrast=geometry_info.sigma;
11107 }
11108 if (attribute_flag[1] != 0)
11109 brightness=argument_list[1].real_reference;
11110 if (attribute_flag[2] != 0)
11111 contrast=argument_list[2].real_reference;
11112 if (attribute_flag[4] != 0)
11113 channel=(ChannelType) argument_list[4].integer_reference;
11114 channel_mask=SetImageChannelMask(image,channel);
11115 (void) BrightnessContrastImage(image,brightness,contrast,exception);
11116 (void) SetImageChannelMask(image,channel_mask);
11117 break;
11118 }
11119 case 132: /* Morphology */
11120 {
11121 KernelInfo
11122 *kernel;
11123
11124 MorphologyMethod
11125 method;
11126
11127 ssize_t
11128 iterations;
11129
11130 if (attribute_flag[0] == 0)
11131 break;
cristy2c57b742014-10-31 00:40:34 +000011132 kernel=AcquireKernelInfo(argument_list[0].string_reference,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011133 if (kernel == (KernelInfo *) NULL)
11134 break;
11135 if (attribute_flag[1] != 0)
11136 channel=(ChannelType) argument_list[1].integer_reference;
11137 method=UndefinedMorphology;
11138 if (attribute_flag[2] != 0)
11139 method=argument_list[2].integer_reference;
11140 iterations=1;
11141 if (attribute_flag[3] != 0)
11142 iterations=argument_list[3].integer_reference;
11143 channel_mask=SetImageChannelMask(image,channel);
11144 image=MorphologyImage(image,method,iterations,kernel,exception);
11145 if (image != (Image *) NULL)
11146 (void) SetImageChannelMask(image,channel_mask);
11147 kernel=DestroyKernelInfo(kernel);
11148 break;
11149 }
11150 case 133: /* Mode */
11151 {
11152 if (attribute_flag[0] != 0)
11153 {
11154 flags=ParseGeometry(argument_list[0].string_reference,
11155 &geometry_info);
11156 if ((flags & SigmaValue) == 0)
11157 geometry_info.sigma=1.0;
11158 }
11159 if (attribute_flag[1] != 0)
11160 geometry_info.rho=argument_list[1].real_reference;
11161 if (attribute_flag[2] != 0)
11162 geometry_info.sigma=argument_list[2].real_reference;
11163 if (attribute_flag[3] != 0)
11164 channel=(ChannelType) argument_list[3].integer_reference;
11165 channel_mask=SetImageChannelMask(image,channel);
11166 image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
11167 (size_t) geometry_info.sigma,exception);
11168 if (image != (Image *) NULL)
11169 (void) SetImageChannelMask(image,channel_mask);
11170 break;
11171 }
11172 case 134: /* Statistic */
11173 {
11174 StatisticType
11175 statistic;
11176
11177 statistic=UndefinedStatistic;
11178 if (attribute_flag[0] != 0)
11179 {
11180 flags=ParseGeometry(argument_list[0].string_reference,
11181 &geometry_info);
11182 if ((flags & SigmaValue) == 0)
11183 geometry_info.sigma=1.0;
11184 }
11185 if (attribute_flag[1] != 0)
11186 geometry_info.rho=argument_list[1].real_reference;
11187 if (attribute_flag[2] != 0)
11188 geometry_info.sigma=argument_list[2].real_reference;
11189 if (attribute_flag[3] != 0)
11190 channel=(ChannelType) argument_list[3].integer_reference;
11191 if (attribute_flag[4] != 0)
11192 statistic=(StatisticType) argument_list[4].integer_reference;
11193 channel_mask=SetImageChannelMask(image,channel);
11194 image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
11195 (size_t) geometry_info.sigma,exception);
11196 if (image != (Image *) NULL)
11197 (void) SetImageChannelMask(image,channel_mask);
11198 break;
11199 }
11200 case 135: /* Perceptible */
11201 {
11202 double
11203 epsilon;
11204
11205 epsilon=MagickEpsilon;
11206 if (attribute_flag[0] != 0)
11207 epsilon=argument_list[0].real_reference;
11208 if (attribute_flag[1] != 0)
11209 channel=(ChannelType) argument_list[1].integer_reference;
11210 channel_mask=SetImageChannelMask(image,channel);
11211 (void) PerceptibleImage(image,epsilon,exception);
11212 (void) SetImageChannelMask(image,channel_mask);
11213 break;
11214 }
11215 case 136: /* Poly */
11216 {
11217 AV
11218 *av;
11219
11220 double
11221 *terms;
11222
11223 size_t
11224 number_terms;
11225
11226 if (attribute_flag[0] == 0)
11227 break;
11228 if (attribute_flag[1] != 0)
11229 channel=(ChannelType) argument_list[1].integer_reference;
11230 av=(AV *) argument_list[0].array_reference;
11231 number_terms=(size_t) av_len(av);
11232 terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
11233 if (terms == (double *) NULL)
11234 {
11235 ThrowPerlException(exception,ResourceLimitFatalError,
11236 "MemoryAllocationFailed",PackageName);
11237 goto PerlException;
11238 }
11239 for (j=0; j < av_len(av); j++)
11240 terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
11241 image=PolynomialImage(image,number_terms >> 1,terms,exception);
11242 terms=(double *) RelinquishMagickMemory(terms);
11243 break;
11244 }
11245 case 137: /* Grayscale */
11246 {
11247 PixelIntensityMethod
11248 method;
11249
11250 method=UndefinedPixelIntensityMethod;
11251 if (attribute_flag[0] != 0)
11252 method=(PixelIntensityMethod) argument_list[0].integer_reference;
11253 (void) GrayscaleImage(image,method,exception);
11254 break;
11255 }
cristy4ceadb82014-03-29 15:30:43 +000011256 case 138: /* Canny */
11257 {
11258 if (attribute_flag[0] != 0)
11259 {
11260 flags=ParseGeometry(argument_list[0].string_reference,
11261 &geometry_info);
11262 if ((flags & SigmaValue) == 0)
11263 geometry_info.sigma=1.0;
11264 if ((flags & XiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011265 geometry_info.xi=0.10;
cristy4ceadb82014-03-29 15:30:43 +000011266 if ((flags & PsiValue) == 0)
cristyed9cf8c2014-04-10 18:27:13 +000011267 geometry_info.psi=0.30;
cristy41814f22014-04-09 20:53:11 +000011268 if ((flags & PercentValue) != 0)
11269 {
11270 geometry_info.xi/=100.0;
11271 geometry_info.psi/=100.0;
11272 }
cristy4ceadb82014-03-29 15:30:43 +000011273 }
11274 if (attribute_flag[1] != 0)
11275 geometry_info.rho=argument_list[1].real_reference;
11276 if (attribute_flag[2] != 0)
11277 geometry_info.sigma=argument_list[2].real_reference;
11278 if (attribute_flag[3] != 0)
11279 geometry_info.xi=argument_list[3].real_reference;
11280 if (attribute_flag[4] != 0)
11281 geometry_info.psi=argument_list[4].real_reference;
11282 if (attribute_flag[5] != 0)
11283 channel=(ChannelType) argument_list[5].integer_reference;
11284 channel_mask=SetImageChannelMask(image,channel);
11285 image=CannyEdgeImage(image,geometry_info.rho,geometry_info.sigma,
11286 geometry_info.xi,geometry_info.psi,exception);
11287 if (image != (Image *) NULL)
11288 (void) SetImageChannelMask(image,channel_mask);
11289 break;
11290 }
cristy2fc10e52014-04-26 14:13:53 +000011291 case 139: /* HoughLine */
cristy4e215022014-04-19 18:02:35 +000011292 {
11293 if (attribute_flag[0] != 0)
11294 {
11295 flags=ParseGeometry(argument_list[0].string_reference,
11296 &geometry_info);
11297 if ((flags & SigmaValue) == 0)
11298 geometry_info.sigma=geometry_info.rho;
cristy20f90422014-04-27 13:34:21 +000011299 if ((flags & XiValue) == 0)
11300 geometry_info.xi=40;
cristy4e215022014-04-19 18:02:35 +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;
cristy2fc10e52014-04-26 14:13:53 +000011308 image=HoughLineImage(image,(size_t) geometry_info.rho,(size_t)
11309 geometry_info.sigma,(size_t) geometry_info.xi,exception);
11310 break;
11311 }
11312 case 140: /* MeanShift */
11313 {
11314 if (attribute_flag[0] != 0)
11315 {
11316 flags=ParseGeometry(argument_list[0].string_reference,
11317 &geometry_info);
11318 if ((flags & SigmaValue) == 0)
11319 geometry_info.sigma=geometry_info.rho;
cristy2fc10e52014-04-26 14:13:53 +000011320 if ((flags & XiValue) == 0)
cristy1309fc32014-04-26 18:48:37 +000011321 geometry_info.xi=0.10*QuantumRange;
11322 if ((flags & PercentValue) != 0)
11323 geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
cristy2fc10e52014-04-26 14:13:53 +000011324 }
11325 if (attribute_flag[1] != 0)
11326 geometry_info.rho=(double) argument_list[1].integer_reference;
11327 if (attribute_flag[2] != 0)
11328 geometry_info.sigma=(double) argument_list[2].integer_reference;
11329 if (attribute_flag[3] != 0)
11330 geometry_info.xi=(double) argument_list[3].integer_reference;
11331 image=MeanShiftImage(image,(size_t) geometry_info.rho,(size_t)
cristy1309fc32014-04-26 18:48:37 +000011332 geometry_info.sigma,geometry_info.xi,exception);
cristy4e215022014-04-19 18:02:35 +000011333 break;
11334 }
cristy3b207f82014-09-27 14:21:20 +000011335 case 141: /* Kuwahara */
11336 {
11337 if (attribute_flag[0] != 0)
11338 {
11339 flags=ParseGeometry(argument_list[0].string_reference,
11340 &geometry_info);
11341 if ((flags & SigmaValue) == 0)
cristy3a9903c2014-10-04 01:14:20 +000011342 geometry_info.sigma=geometry_info.rho-0.5;
cristy3b207f82014-09-27 14:21:20 +000011343 }
11344 if (attribute_flag[1] != 0)
11345 geometry_info.rho=argument_list[1].real_reference;
11346 if (attribute_flag[2] != 0)
11347 geometry_info.sigma=argument_list[2].real_reference;
11348 if (attribute_flag[3] != 0)
11349 channel=(ChannelType) argument_list[3].integer_reference;
11350 channel_mask=SetImageChannelMask(image,channel);
11351 image=KuwaharaImage(image,geometry_info.rho,geometry_info.sigma,
11352 exception);
11353 if (image != (Image *) NULL)
11354 (void) SetImageChannelMask(image,channel_mask);
11355 break;
11356 }
Cristy0f5df812017-07-04 18:30:05 -040011357 case 142: /* ConnectedComponents */
cristy6e0b3bc2014-10-19 17:51:42 +000011358 {
11359 size_t
11360 connectivity;
11361
11362 connectivity=4;
11363 if (attribute_flag[0] != 0)
11364 connectivity=argument_list[0].integer_reference;
Cristy2ca0e9a2016-01-01 08:36:14 -050011365 image=ConnectedComponentsImage(image,connectivity,
Cristy4f83be82015-12-31 08:40:53 -050011366 (CCObjectInfo **) NULL,exception);
cristy6e0b3bc2014-10-19 17:51:42 +000011367 break;
11368 }
cristy0b94b392015-06-22 18:56:37 +000011369 case 143: /* Copy */
11370 {
11371 Image
11372 *source_image;
11373
11374 OffsetInfo
11375 offset;
11376
cristy2ffdb092015-06-25 14:31:20 +000011377 RectangleInfo
11378 offset_geometry;
11379
cristyf3a724a2015-06-25 13:02:53 +000011380 source_image=image;
cristy0b94b392015-06-22 18:56:37 +000011381 if (attribute_flag[0] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011382 source_image=argument_list[0].image_reference;
cristy2ffdb092015-06-25 14:31:20 +000011383 SetGeometry(source_image,&geometry);
cristy0b94b392015-06-22 18:56:37 +000011384 if (attribute_flag[1] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011385 flags=ParseGravityGeometry(source_image,
11386 argument_list[1].string_reference,&geometry,exception);
cristy0b94b392015-06-22 18:56:37 +000011387 if (attribute_flag[2] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011388 geometry.width=argument_list[2].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011389 if (attribute_flag[3] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011390 geometry.height=argument_list[3].integer_reference;
cristy0b94b392015-06-22 18:56:37 +000011391 if (attribute_flag[4] != 0)
cristyf3a724a2015-06-25 13:02:53 +000011392 geometry.x=argument_list[4].integer_reference;
11393 if (attribute_flag[5] != 0)
11394 geometry.y=argument_list[5].integer_reference;
11395 if (attribute_flag[6] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011396 image->gravity=(GravityType) argument_list[6].integer_reference;
dirk169d1642015-06-27 19:51:08 +000011397 SetGeometry(image,&offset_geometry);
cristyf3a724a2015-06-25 13:02:53 +000011398 if (attribute_flag[7] != 0)
cristy2ffdb092015-06-25 14:31:20 +000011399 flags=ParseGravityGeometry(image,argument_list[7].string_reference,
11400 &offset_geometry,exception);
11401 offset.x=offset_geometry.x;
11402 offset.y=offset_geometry.y;
cristyf3a724a2015-06-25 13:02:53 +000011403 if (attribute_flag[8] != 0)
11404 offset.x=argument_list[8].integer_reference;
11405 if (attribute_flag[9] != 0)
11406 offset.y=argument_list[9].integer_reference;
cristycd6d5182015-06-23 17:22:15 +000011407 (void) CopyImagePixels(image,source_image,&geometry,&offset,
11408 exception);
cristy0b94b392015-06-22 18:56:37 +000011409 break;
11410 }
Cristy5488c982016-02-13 14:07:50 -050011411 case 144: /* Color */
11412 {
11413 PixelInfo
11414 color;
11415
Cristyf20e3562016-02-14 09:08:15 -050011416 (void) QueryColorCompliance("none",AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011417 if (attribute_flag[0] != 0)
Cristyf20e3562016-02-14 09:08:15 -050011418 (void) QueryColorCompliance(argument_list[0].string_reference,
11419 AllCompliance,&color,exception);
Cristy5488c982016-02-13 14:07:50 -050011420 (void) SetImageColor(image,&color,exception);
11421 break;
11422 }
Cristy2d830ed2016-02-21 10:54:16 -050011423 case 145: /* WaveletDenoise */
11424 {
Cristyc1759412016-02-27 12:17:58 -050011425 if (attribute_flag[0] != 0)
Cristyee21f7f2016-02-27 15:56:49 -050011426 {
11427 flags=ParseGeometry(argument_list[0].string_reference,
11428 &geometry_info);
11429 if ((flags & PercentValue) != 0)
Cristy23446632016-02-29 09:36:34 -050011430 {
11431 geometry_info.rho=QuantumRange*geometry_info.rho/100.0;
11432 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
11433 }
Cristyee21f7f2016-02-27 15:56:49 -050011434 if ((flags & SigmaValue) == 0)
11435 geometry_info.sigma=0.0;
11436 }
Cristyc1759412016-02-27 12:17:58 -050011437 if (attribute_flag[1] != 0)
11438 geometry_info.rho=argument_list[1].real_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011439 if (attribute_flag[2] != 0)
Cristyc1759412016-02-27 12:17:58 -050011440 geometry_info.sigma=argument_list[2].real_reference;
11441 if (attribute_flag[3] != 0)
11442 channel=(ChannelType) argument_list[3].integer_reference;
Cristy2d830ed2016-02-21 10:54:16 -050011443 channel_mask=SetImageChannelMask(image,channel);
Cristyc1759412016-02-27 12:17:58 -050011444 image=WaveletDenoiseImage(image,geometry_info.rho,geometry_info.sigma,
11445 exception);
Cristy2d830ed2016-02-21 10:54:16 -050011446 if (image != (Image *) NULL)
11447 (void) SetImageChannelMask(image,channel_mask);
11448 break;
11449 }
Cristy99a57162016-12-05 11:47:57 -050011450 case 146: /* Colorspace */
11451 {
11452 ColorspaceType
11453 colorspace;
11454
11455 colorspace=sRGBColorspace;
11456 if (attribute_flag[0] != 0)
11457 colorspace=(ColorspaceType) argument_list[0].integer_reference;
11458 (void) TransformImageColorspace(image,colorspace,exception);
11459 break;
11460 }
Cristy53353872017-07-02 12:24:24 -040011461 case 147: /* AutoThreshold */
11462 {
11463 AutoThresholdMethod
11464 method;
11465
11466 method=UndefinedThresholdMethod;
11467 if (attribute_flag[0] != 0)
Cristyb63e7752017-07-02 13:22:01 -040011468 method=(AutoThresholdMethod) argument_list[0].integer_reference;
Cristy53353872017-07-02 12:24:24 -040011469 (void) AutoThresholdImage(image,method,exception);
11470 break;
11471 }
Cristy532b3382018-08-05 17:56:56 -040011472 case 148: /* RangeThreshold */
11473 {
11474 if (attribute_flag[0] != 0)
11475 {
11476 flags=ParseGeometry(argument_list[0].string_reference,
11477 &geometry_info);
11478 if ((flags & SigmaValue) == 0)
11479 geometry_info.sigma=geometry_info.rho;
11480 if ((flags & XiValue) == 0)
11481 geometry_info.xi=geometry_info.sigma;
11482 if ((flags & PsiValue) == 0)
11483 geometry_info.psi=geometry_info.xi;
11484 }
11485 if (attribute_flag[1] != 0)
11486 geometry_info.rho=argument_list[1].real_reference;
11487 if (attribute_flag[2] != 0)
11488 geometry_info.sigma=argument_list[2].real_reference;
11489 if (attribute_flag[3] != 0)
11490 geometry_info.xi=argument_list[3].real_reference;
11491 if (attribute_flag[4] != 0)
11492 geometry_info.psi=argument_list[4].real_reference;
11493 if (attribute_flag[5] != 0)
11494 channel=(ChannelType) argument_list[5].integer_reference;
11495 channel_mask=SetImageChannelMask(image,channel);
Cristy9b220db2018-08-05 18:02:28 -040011496 (void) RangeThresholdImage(image,geometry_info.rho,
11497 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
Cristy532b3382018-08-05 17:56:56 -040011498 if (image != (Image *) NULL)
11499 (void) SetImageChannelMask(image,channel_mask);
11500 break;
11501 }
Cristy9f252542018-11-21 19:13:46 -050011502 case 149: /* CLAHE */
11503 {
11504 if (attribute_flag[0] != 0)
Cristy768e9002019-01-08 07:35:16 -050011505 {
11506 flags=ParseGeometry(argument_list[0].string_reference,
11507 &geometry_info);
11508 flags=ParseRegionGeometry(image,argument_list[0].string_reference,
11509 &geometry,exception);
11510 }
Cristy9f252542018-11-21 19:13:46 -050011511 if (attribute_flag[1] != 0)
Cristy30263282018-12-11 16:40:25 -050011512 geometry.width=argument_list[1].integer_reference;
Cristy9f252542018-11-21 19:13:46 -050011513 if (attribute_flag[2] != 0)
Cristy30263282018-12-11 16:40:25 -050011514 geometry.height=argument_list[2].integer_reference;
Cristy9f252542018-11-21 19:13:46 -050011515 if (attribute_flag[3] != 0)
Cristy768e9002019-01-08 07:35:16 -050011516 geometry.x=argument_list[3].integer_reference;
Cristy9f252542018-11-21 19:13:46 -050011517 if (attribute_flag[4] != 0)
Cristy768e9002019-01-08 07:35:16 -050011518 geometry_info.psi=argument_list[4].real_reference;
Cristyd9b98812018-12-16 09:30:05 -050011519 (void) CLAHEImage(image,geometry.width,geometry.height,geometry.x,
Cristy768e9002019-01-08 07:35:16 -050011520 geometry_info.psi,exception);
Cristy9f252542018-11-21 19:13:46 -050011521 break;
11522 }
Cristyb4ab5192019-12-19 06:53:46 -050011523 case 150: /* Kmeans */
11524 {
11525 if (attribute_flag[0] != 0)
11526 {
11527 flags=ParseGeometry(argument_list[0].string_reference,
11528 &geometry_info);
11529 if ((flags & SigmaValue) == 0)
Cristyc809e482019-12-21 09:59:52 -050011530 geometry_info.sigma=100.0;
Cristyb4ab5192019-12-19 06:53:46 -050011531 if ((flags & XiValue) == 0)
Cristyc809e482019-12-21 09:59:52 -050011532 geometry_info.xi=0.01;
Cristyb4ab5192019-12-19 06:53:46 -050011533 }
11534 if (attribute_flag[1] != 0)
11535 geometry_info.rho=argument_list[1].integer_reference;
11536 if (attribute_flag[2] != 0)
11537 geometry_info.sigma=argument_list[2].integer_reference;
11538 if (attribute_flag[3] != 0)
11539 geometry_info.xi=(ChannelType) argument_list[3].real_reference;
11540 (void) KmeansImage(image,geometry_info.rho,geometry_info.sigma,
11541 geometry_info.xi,exception);
11542 break;
11543 }
Cristy89b4db02020-02-21 20:57:40 -050011544 case 151: /* ColorThreshold */
11545 {
Cristyca5ba782020-02-22 08:17:19 -050011546 PixelInfo
11547 start_color,
11548 stop_color;
11549
11550 (void) QueryColorCompliance("black",AllCompliance,&start_color,
11551 exception);
11552 (void) QueryColorCompliance("white",AllCompliance,&stop_color,
11553 exception);
11554 if (attribute_flag[0] != 0)
11555 (void) QueryColorCompliance(argument_list[0].string_reference,
11556 AllCompliance,&start_color,exception);
11557 if (attribute_flag[1] != 0)
11558 (void) QueryColorCompliance(argument_list[1].string_reference,
11559 AllCompliance,&stop_color,exception);
Cristy89b4db02020-02-21 20:57:40 -050011560 channel_mask=SetImageChannelMask(image,channel);
11561 (void) ColorThresholdImage(image,argument_list[0].string_reference,
11562 exception);
11563 (void) SetImageChannelMask(image,channel_mask);
11564 break;
11565 }
cristy4a3ce0a2013-08-03 20:06:59 +000011566 }
11567 if (next != (Image *) NULL)
11568 (void) CatchImageException(next);
Cristy7e567962018-02-03 12:42:20 -050011569 if ((region_info.width*region_info.height) != 0)
11570 (void) SetImageRegionMask(image,WritePixelMask,
11571 (const RectangleInfo *) NULL,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011572 if (image != (Image *) NULL)
11573 {
11574 number_images++;
11575 if (next && (next != image))
11576 {
11577 image->next=next->next;
11578 if (image->next != (Image *) NULL)
11579 image->next->previous=image;
11580 DeleteImageFromRegistry(*pv,next);
11581 }
11582 sv_setiv(*pv,PTR2IV(image));
11583 next=image;
11584 }
11585 if (*pv)
11586 pv++;
11587 }
11588
11589 PerlException:
11590 if (reference_vector)
11591 reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
11592 InheritPerlException(exception,perl_exception);
11593 exception=DestroyExceptionInfo(exception);
11594 sv_setiv(perl_exception,(IV) number_images);
11595 SvPOK_on(perl_exception);
11596 ST(0)=sv_2mortal(perl_exception);
11597 XSRETURN(1);
11598 }
11599
11600#
11601###############################################################################
11602# #
11603# #
11604# #
11605# M o n t a g e #
11606# #
11607# #
11608# #
11609###############################################################################
11610#
11611#
11612void
11613Montage(ref,...)
11614 Image::Magick ref=NO_INIT
11615 ALIAS:
11616 MontageImage = 1
11617 montage = 2
11618 montageimage = 3
11619 PPCODE:
11620 {
11621 AV
11622 *av;
11623
11624 char
11625 *attribute;
11626
11627 ExceptionInfo
11628 *exception;
11629
11630 HV
11631 *hv;
11632
11633 Image
11634 *image,
11635 *next;
11636
11637 PixelInfo
11638 transparent_color;
11639
11640 MontageInfo
11641 *montage_info;
11642
11643 register ssize_t
11644 i;
11645
11646 ssize_t
11647 sp;
11648
11649 struct PackageInfo
11650 *info;
11651
11652 SV
11653 *av_reference,
11654 *perl_exception,
11655 *reference,
11656 *rv,
11657 *sv;
11658
11659 PERL_UNUSED_VAR(ref);
11660 PERL_UNUSED_VAR(ix);
11661 exception=AcquireExceptionInfo();
11662 perl_exception=newSVpv("",0);
11663 sv=NULL;
11664 attribute=NULL;
11665 if (sv_isobject(ST(0)) == 0)
11666 {
11667 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
11668 PackageName);
11669 goto PerlException;
11670 }
11671 reference=SvRV(ST(0));
11672 hv=SvSTASH(reference);
11673 av=newAV();
11674 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
11675 SvREFCNT_dec(av);
11676 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
11677 if (image == (Image *) NULL)
11678 {
11679 ThrowPerlException(exception,OptionError,"NoImagesDefined",
11680 PackageName);
11681 goto PerlException;
11682 }
11683 /*
11684 Get options.
11685 */
11686 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
11687 montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
11688 (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
11689 exception);
11690 for (i=2; i < items; i+=2)
11691 {
11692 attribute=(char *) SvPV(ST(i-1),na);
11693 switch (*attribute)
11694 {
11695 case 'B':
11696 case 'b':
11697 {
11698 if (LocaleCompare(attribute,"background") == 0)
11699 {
11700 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11701 &montage_info->background_color,exception);
11702 for (next=image; next; next=next->next)
11703 next->background_color=montage_info->background_color;
11704 break;
11705 }
11706 if (LocaleCompare(attribute,"border") == 0)
11707 {
11708 montage_info->border_width=SvIV(ST(i));
11709 break;
11710 }
11711 if (LocaleCompare(attribute,"bordercolor") == 0)
11712 {
11713 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11714 &montage_info->border_color,exception);
11715 for (next=image; next; next=next->next)
11716 next->border_color=montage_info->border_color;
11717 break;
11718 }
11719 if (LocaleCompare(attribute,"borderwidth") == 0)
11720 {
11721 montage_info->border_width=SvIV(ST(i));
11722 break;
11723 }
11724 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11725 attribute);
11726 break;
11727 }
11728 case 'C':
11729 case 'c':
11730 {
11731 if (LocaleCompare(attribute,"compose") == 0)
11732 {
11733 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11734 MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
11735 if (sp < 0)
11736 {
11737 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11738 SvPV(ST(i),na));
11739 break;
11740 }
11741 for (next=image; next; next=next->next)
11742 next->compose=(CompositeOperator) sp;
11743 break;
11744 }
11745 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11746 attribute);
11747 break;
11748 }
11749 case 'F':
11750 case 'f':
11751 {
11752 if (LocaleCompare(attribute,"fill") == 0)
11753 {
11754 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11755 &montage_info->fill,exception);
11756 break;
11757 }
11758 if (LocaleCompare(attribute,"font") == 0)
11759 {
11760 (void) CloneString(&montage_info->font,SvPV(ST(i),na));
11761 break;
11762 }
11763 if (LocaleCompare(attribute,"frame") == 0)
11764 {
11765 char
11766 *p;
11767
11768 p=SvPV(ST(i),na);
11769 if (IsGeometry(p) == MagickFalse)
11770 {
11771 ThrowPerlException(exception,OptionError,"MissingGeometry",
11772 p);
11773 break;
11774 }
11775 (void) CloneString(&montage_info->frame,p);
11776 if (*p == '\0')
11777 montage_info->frame=(char *) NULL;
11778 break;
11779 }
11780 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11781 attribute);
11782 break;
11783 }
11784 case 'G':
11785 case 'g':
11786 {
11787 if (LocaleCompare(attribute,"geometry") == 0)
11788 {
11789 char
11790 *p;
11791
11792 p=SvPV(ST(i),na);
11793 if (IsGeometry(p) == MagickFalse)
11794 {
11795 ThrowPerlException(exception,OptionError,"MissingGeometry",
11796 p);
11797 break;
11798 }
11799 (void) CloneString(&montage_info->geometry,p);
11800 if (*p == '\0')
11801 montage_info->geometry=(char *) NULL;
11802 break;
11803 }
11804 if (LocaleCompare(attribute,"gravity") == 0)
11805 {
11806 ssize_t
11807 in;
11808
11809 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11810 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
11811 if (in < 0)
11812 {
11813 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11814 SvPV(ST(i),na));
11815 return;
11816 }
11817 montage_info->gravity=(GravityType) in;
11818 for (next=image; next; next=next->next)
11819 next->gravity=(GravityType) in;
11820 break;
11821 }
11822 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11823 attribute);
11824 break;
11825 }
11826 case 'L':
11827 case 'l':
11828 {
11829 if (LocaleCompare(attribute,"label") == 0)
11830 {
11831 for (next=image; next; next=next->next)
Cristy935a4052017-03-31 17:45:37 -040011832 (void) SetImageProperty(next,"label",InterpretImageProperties(
cristy4a3ce0a2013-08-03 20:06:59 +000011833 info ? info->image_info : (ImageInfo *) NULL,next,
Cristy935a4052017-03-31 17:45:37 -040011834 SvPV(ST(i),na),exception),exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011835 break;
11836 }
11837 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11838 attribute);
11839 break;
11840 }
11841 case 'M':
11842 case 'm':
11843 {
11844 if (LocaleCompare(attribute,"mattecolor") == 0)
11845 {
11846 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
Cristy8645e042016-02-03 16:35:29 -050011847 &montage_info->alpha_color,exception);
cristy4a3ce0a2013-08-03 20:06:59 +000011848 for (next=image; next; next=next->next)
Cristy8645e042016-02-03 16:35:29 -050011849 next->alpha_color=montage_info->alpha_color;
cristy4a3ce0a2013-08-03 20:06:59 +000011850 break;
11851 }
11852 if (LocaleCompare(attribute,"mode") == 0)
11853 {
11854 ssize_t
11855 in;
11856
11857 in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11858 MagickModeOptions,MagickFalse,SvPV(ST(i),na));
11859 switch (in)
11860 {
11861 default:
11862 {
11863 ThrowPerlException(exception,OptionError,
11864 "UnrecognizedModeType",SvPV(ST(i),na));
11865 break;
11866 }
11867 case FrameMode:
11868 {
11869 (void) CloneString(&montage_info->frame,"15x15+3+3");
11870 montage_info->shadow=MagickTrue;
11871 break;
11872 }
11873 case UnframeMode:
11874 {
11875 montage_info->frame=(char *) NULL;
11876 montage_info->shadow=MagickFalse;
11877 montage_info->border_width=0;
11878 break;
11879 }
11880 case ConcatenateMode:
11881 {
11882 montage_info->frame=(char *) NULL;
11883 montage_info->shadow=MagickFalse;
11884 (void) CloneString(&montage_info->geometry,"+0+0");
11885 montage_info->border_width=0;
11886 }
11887 }
11888 break;
11889 }
11890 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11891 attribute);
11892 break;
11893 }
11894 case 'P':
11895 case 'p':
11896 {
11897 if (LocaleCompare(attribute,"pointsize") == 0)
11898 {
11899 montage_info->pointsize=SvIV(ST(i));
11900 break;
11901 }
11902 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11903 attribute);
11904 break;
11905 }
11906 case 'S':
11907 case 's':
11908 {
11909 if (LocaleCompare(attribute,"shadow") == 0)
11910 {
11911 sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
11912 MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
11913 if (sp < 0)
11914 {
11915 ThrowPerlException(exception,OptionError,"UnrecognizedType",
11916 SvPV(ST(i),na));
11917 break;
11918 }
11919 montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
11920 break;
11921 }
11922 if (LocaleCompare(attribute,"stroke") == 0)
11923 {
11924 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11925 &montage_info->stroke,exception);
11926 break;
11927 }
11928 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11929 attribute);
11930 break;
11931 }
11932 case 'T':
11933 case 't':
11934 {
11935 if (LocaleCompare(attribute,"texture") == 0)
11936 {
11937 (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
11938 break;
11939 }
11940 if (LocaleCompare(attribute,"tile") == 0)
11941 {
11942 char *p=SvPV(ST(i),na);
11943 if (IsGeometry(p) == MagickFalse)
11944 {
11945 ThrowPerlException(exception,OptionError,"MissingGeometry",
11946 p);
11947 break;
11948 }
11949 (void) CloneString(&montage_info->tile,p);
11950 if (*p == '\0')
11951 montage_info->tile=(char *) NULL;
11952 break;
11953 }
11954 if (LocaleCompare(attribute,"title") == 0)
11955 {
11956 (void) CloneString(&montage_info->title,SvPV(ST(i),na));
11957 break;
11958 }
11959 if (LocaleCompare(attribute,"transparent") == 0)
11960 {
11961 PixelInfo
11962 transparent_color;
11963
11964 QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
11965 &transparent_color,exception);
11966 for (next=image; next; next=next->next)
11967 (void) TransparentPaintImage(next,&transparent_color,
11968 TransparentAlpha,MagickFalse,exception);
11969 break;
11970 }
11971 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11972 attribute);
11973 break;
11974 }
11975 default:
11976 {
11977 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
11978 attribute);
11979 break;
11980 }
11981 }
11982 }
11983 image=MontageImageList(info->image_info,montage_info,image,exception);
11984 montage_info=DestroyMontageInfo(montage_info);
11985 if (image == (Image *) NULL)
11986 goto PerlException;
11987 if (transparent_color.alpha != TransparentAlpha)
11988 for (next=image; next; next=next->next)
11989 (void) TransparentPaintImage(next,&transparent_color,
11990 TransparentAlpha,MagickFalse,exception);
11991 for ( ; image; image=image->next)
11992 {
11993 AddImageToRegistry(sv,image);
11994 rv=newRV(sv);
11995 av_push(av,sv_bless(rv,hv));
11996 SvREFCNT_dec(sv);
11997 }
11998 exception=DestroyExceptionInfo(exception);
11999 ST(0)=av_reference;
12000 SvREFCNT_dec(perl_exception);
12001 XSRETURN(1);
12002
12003 PerlException:
12004 InheritPerlException(exception,perl_exception);
12005 exception=DestroyExceptionInfo(exception);
12006 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12007 SvPOK_on(perl_exception);
12008 ST(0)=sv_2mortal(perl_exception);
12009 XSRETURN(1);
12010 }
12011
12012#
12013###############################################################################
12014# #
12015# #
12016# #
12017# M o r p h #
12018# #
12019# #
12020# #
12021###############################################################################
12022#
12023#
12024void
12025Morph(ref,...)
12026 Image::Magick ref=NO_INIT
12027 ALIAS:
12028 MorphImage = 1
12029 morph = 2
12030 morphimage = 3
12031 PPCODE:
12032 {
12033 AV
12034 *av;
12035
12036 char
12037 *attribute;
12038
12039 ExceptionInfo
12040 *exception;
12041
12042 HV
12043 *hv;
12044
12045 Image
12046 *image;
12047
12048 register ssize_t
12049 i;
12050
12051 ssize_t
12052 number_frames;
12053
12054 struct PackageInfo
12055 *info;
12056
12057 SV
12058 *av_reference,
12059 *perl_exception,
12060 *reference,
12061 *rv,
12062 *sv;
12063
12064 PERL_UNUSED_VAR(ref);
12065 PERL_UNUSED_VAR(ix);
12066 exception=AcquireExceptionInfo();
12067 perl_exception=newSVpv("",0);
12068 sv=NULL;
12069 av=NULL;
12070 attribute=NULL;
12071 if (sv_isobject(ST(0)) == 0)
12072 {
12073 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12074 PackageName);
12075 goto PerlException;
12076 }
12077 reference=SvRV(ST(0));
12078 hv=SvSTASH(reference);
12079 av=newAV();
12080 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12081 SvREFCNT_dec(av);
12082 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12083 if (image == (Image *) NULL)
12084 {
12085 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12086 PackageName);
12087 goto PerlException;
12088 }
12089 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12090 /*
12091 Get attribute.
12092 */
12093 number_frames=30;
12094 for (i=2; i < items; i+=2)
12095 {
12096 attribute=(char *) SvPV(ST(i-1),na);
12097 switch (*attribute)
12098 {
12099 case 'F':
12100 case 'f':
12101 {
12102 if (LocaleCompare(attribute,"frames") == 0)
12103 {
12104 number_frames=SvIV(ST(i));
12105 break;
12106 }
12107 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12108 attribute);
12109 break;
12110 }
12111 default:
12112 {
12113 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12114 attribute);
12115 break;
12116 }
12117 }
12118 }
12119 image=MorphImages(image,number_frames,exception);
12120 if (image == (Image *) NULL)
12121 goto PerlException;
12122 for ( ; image; image=image->next)
12123 {
12124 AddImageToRegistry(sv,image);
12125 rv=newRV(sv);
12126 av_push(av,sv_bless(rv,hv));
12127 SvREFCNT_dec(sv);
12128 }
12129 exception=DestroyExceptionInfo(exception);
12130 ST(0)=av_reference;
12131 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12132 XSRETURN(1);
12133
12134 PerlException:
12135 InheritPerlException(exception,perl_exception);
12136 exception=DestroyExceptionInfo(exception);
12137 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12138 SvPOK_on(perl_exception);
12139 ST(0)=sv_2mortal(perl_exception);
12140 XSRETURN(1);
12141 }
12142
12143#
12144###############################################################################
12145# #
12146# #
12147# #
12148# M o s a i c #
12149# #
12150# #
12151# #
12152###############################################################################
12153#
12154#
12155void
12156Mosaic(ref)
12157 Image::Magick ref=NO_INIT
12158 ALIAS:
12159 MosaicImage = 1
12160 mosaic = 2
12161 mosaicimage = 3
12162 PPCODE:
12163 {
12164 AV
12165 *av;
12166
12167 ExceptionInfo
12168 *exception;
12169
12170 HV
12171 *hv;
12172
12173 Image
12174 *image;
12175
12176 struct PackageInfo
12177 *info;
12178
12179 SV
12180 *perl_exception,
12181 *reference,
12182 *rv,
12183 *sv;
12184
12185 PERL_UNUSED_VAR(ref);
12186 PERL_UNUSED_VAR(ix);
12187 exception=AcquireExceptionInfo();
12188 perl_exception=newSVpv("",0);
12189 sv=NULL;
12190 if (sv_isobject(ST(0)) == 0)
12191 {
12192 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12193 PackageName);
12194 goto PerlException;
12195 }
12196 reference=SvRV(ST(0));
12197 hv=SvSTASH(reference);
12198 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12199 if (image == (Image *) NULL)
12200 {
12201 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12202 PackageName);
12203 goto PerlException;
12204 }
12205 image=MergeImageLayers(image,MosaicLayer,exception);
12206 /*
12207 Create blessed Perl array for the returned image.
12208 */
12209 av=newAV();
12210 ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12211 SvREFCNT_dec(av);
12212 AddImageToRegistry(sv,image);
12213 rv=newRV(sv);
12214 av_push(av,sv_bless(rv,hv));
12215 SvREFCNT_dec(sv);
cristy4a3ce0a2013-08-03 20:06:59 +000012216 (void) CopyMagickString(info->image_info->filename,image->filename,
cristy151b66d2015-04-15 10:50:31 +000012217 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012218 SetImageInfo(info->image_info,0,exception);
12219 exception=DestroyExceptionInfo(exception);
12220 SvREFCNT_dec(perl_exception);
12221 XSRETURN(1);
12222
12223 PerlException:
12224 InheritPerlException(exception,perl_exception);
12225 exception=DestroyExceptionInfo(exception);
12226 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12227 SvPOK_on(perl_exception); /* return messages in string context */
12228 ST(0)=sv_2mortal(perl_exception);
12229 XSRETURN(1);
12230 }
12231
12232#
12233###############################################################################
12234# #
12235# #
12236# #
12237# P i n g #
12238# #
12239# #
12240# #
12241###############################################################################
12242#
12243#
12244void
12245Ping(ref,...)
12246 Image::Magick ref=NO_INIT
12247 ALIAS:
12248 PingImage = 1
12249 ping = 2
12250 pingimage = 3
12251 PPCODE:
12252 {
12253 AV
12254 *av;
12255
12256 char
12257 **keep,
12258 **list;
12259
12260 ExceptionInfo
12261 *exception;
12262
12263 Image
12264 *image,
12265 *next;
12266
12267 int
12268 n;
12269
12270 MagickBooleanType
12271 status;
12272
12273 register char
12274 **p;
12275
12276 register ssize_t
12277 i;
12278
12279 ssize_t
12280 ac;
12281
12282 STRLEN
12283 *length;
12284
12285 struct PackageInfo
12286 *info,
12287 *package_info;
12288
12289 SV
12290 *perl_exception,
12291 *reference;
12292
12293 size_t
12294 count;
12295
12296 PERL_UNUSED_VAR(ref);
12297 PERL_UNUSED_VAR(ix);
12298 exception=AcquireExceptionInfo();
12299 perl_exception=newSVpv("",0);
12300 package_info=(struct PackageInfo *) NULL;
12301 ac=(items < 2) ? 1 : items-1;
12302 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
12303 keep=list;
12304 length=(STRLEN *) NULL;
12305 if (list == (char **) NULL)
12306 {
12307 ThrowPerlException(exception,ResourceLimitError,
12308 "MemoryAllocationFailed",PackageName);
12309 goto PerlException;
12310 }
12311 keep=list;
12312 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
12313 if (length == (STRLEN *) NULL)
12314 {
12315 ThrowPerlException(exception,ResourceLimitError,
12316 "MemoryAllocationFailed",PackageName);
12317 goto PerlException;
12318 }
12319 if (sv_isobject(ST(0)) == 0)
12320 {
12321 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12322 PackageName);
12323 goto PerlException;
12324 }
12325 reference=SvRV(ST(0));
12326 if (SvTYPE(reference) != SVt_PVAV)
12327 {
12328 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12329 PackageName);
12330 goto PerlException;
12331 }
12332 av=(AV *) reference;
12333 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12334 exception);
12335 package_info=ClonePackageInfo(info,exception);
12336 n=1;
12337 if (items <= 1)
12338 *list=(char *) (*package_info->image_info->filename ?
12339 package_info->image_info->filename : "XC:black");
12340 else
12341 for (n=0, i=0; i < ac; i++)
12342 {
12343 list[n]=(char *) SvPV(ST(i+1),length[n]);
12344 if ((items >= 3) && strEQcase(list[n],"blob"))
12345 {
12346 void
12347 *blob;
12348
12349 i++;
12350 blob=(void *) (SvPV(ST(i+1),length[n]));
12351 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
12352 }
12353 if ((items >= 3) && strEQcase(list[n],"filename"))
12354 continue;
12355 if ((items >= 3) && strEQcase(list[n],"file"))
12356 {
12357 FILE
12358 *file;
12359
12360 PerlIO
12361 *io_info;
12362
12363 i++;
12364 io_info=IoIFP(sv_2io(ST(i+1)));
12365 if (io_info == (PerlIO *) NULL)
12366 {
12367 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12368 PackageName);
12369 continue;
12370 }
12371 file=PerlIO_findFILE(io_info);
12372 if (file == (FILE *) NULL)
12373 {
12374 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
12375 PackageName);
12376 continue;
12377 }
12378 SetImageInfoFile(package_info->image_info,file);
12379 }
12380 if ((items >= 3) && strEQcase(list[n],"magick"))
12381 continue;
12382 n++;
12383 }
12384 list[n]=(char *) NULL;
12385 keep=list;
12386 status=ExpandFilenames(&n,&list);
12387 if (status == MagickFalse)
12388 {
12389 ThrowPerlException(exception,ResourceLimitError,
12390 "MemoryAllocationFailed",PackageName);
12391 goto PerlException;
12392 }
12393 count=0;
12394 for (i=0; i < n; i++)
12395 {
12396 (void) CopyMagickString(package_info->image_info->filename,list[i],
cristy151b66d2015-04-15 10:50:31 +000012397 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000012398 image=PingImage(package_info->image_info,exception);
12399 if (image == (Image *) NULL)
12400 break;
12401 if ((package_info->image_info->file != (FILE *) NULL) ||
12402 (package_info->image_info->blob != (void *) NULL))
12403 DisassociateImageStream(image);
12404 count+=GetImageListLength(image);
12405 EXTEND(sp,4*count);
12406 for (next=image; next; next=next->next)
12407 {
12408 PUSHs(sv_2mortal(newSViv(next->columns)));
12409 PUSHs(sv_2mortal(newSViv(next->rows)));
12410 PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
12411 PUSHs(sv_2mortal(newSVpv(next->magick,0)));
12412 }
12413 image=DestroyImageList(image);
12414 }
12415 /*
12416 Free resources.
12417 */
12418 for (i=0; i < n; i++)
12419 if (list[i] != (char *) NULL)
12420 for (p=keep; list[i] != *p++; )
12421 if (*p == NULL)
12422 {
12423 list[i]=(char *) RelinquishMagickMemory(list[i]);
12424 break;
12425 }
12426
12427 PerlException:
12428 if (package_info != (struct PackageInfo *) NULL)
12429 DestroyPackageInfo(package_info);
12430 if (list && (list != keep))
12431 list=(char **) RelinquishMagickMemory(list);
12432 if (keep)
12433 keep=(char **) RelinquishMagickMemory(keep);
12434 if (length)
12435 length=(STRLEN *) RelinquishMagickMemory(length);
12436 InheritPerlException(exception,perl_exception);
12437 exception=DestroyExceptionInfo(exception);
12438 SvREFCNT_dec(perl_exception); /* throw away all errors */
12439 }
12440
12441#
12442###############################################################################
12443# #
12444# #
12445# #
12446# P r e v i e w #
12447# #
12448# #
12449# #
12450###############################################################################
12451#
12452#
12453void
12454Preview(ref,...)
12455 Image::Magick ref=NO_INIT
12456 ALIAS:
12457 PreviewImage = 1
12458 preview = 2
12459 previewimage = 3
12460 PPCODE:
12461 {
12462 AV
12463 *av;
12464
12465 ExceptionInfo
12466 *exception;
12467
12468 HV
12469 *hv;
12470
12471 Image
12472 *image,
12473 *preview_image;
12474
12475 PreviewType
12476 preview_type;
12477
12478 struct PackageInfo
12479 *info;
12480
12481 SV
12482 *av_reference,
12483 *perl_exception,
12484 *reference,
12485 *rv,
12486 *sv;
12487
12488 PERL_UNUSED_VAR(ref);
12489 PERL_UNUSED_VAR(ix);
12490 exception=AcquireExceptionInfo();
12491 perl_exception=newSVpv("",0);
12492 sv=NULL;
12493 av=NULL;
12494 if (sv_isobject(ST(0)) == 0)
12495 {
12496 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
12497 PackageName);
12498 goto PerlException;
12499 }
12500 reference=SvRV(ST(0));
12501 hv=SvSTASH(reference);
12502 av=newAV();
12503 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
12504 SvREFCNT_dec(av);
12505 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12506 if (image == (Image *) NULL)
12507 {
12508 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12509 PackageName);
12510 goto PerlException;
12511 }
12512 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
12513 preview_type=GammaPreview;
12514 if (items > 1)
12515 preview_type=(PreviewType)
12516 ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
12517 for ( ; image; image=image->next)
12518 {
12519 preview_image=PreviewImage(image,preview_type,exception);
12520 if (preview_image == (Image *) NULL)
12521 goto PerlException;
12522 AddImageToRegistry(sv,preview_image);
12523 rv=newRV(sv);
12524 av_push(av,sv_bless(rv,hv));
12525 SvREFCNT_dec(sv);
12526 }
12527 exception=DestroyExceptionInfo(exception);
12528 ST(0)=av_reference;
12529 SvREFCNT_dec(perl_exception); /* can't return warning messages */
12530 XSRETURN(1);
12531
12532 PerlException:
12533 InheritPerlException(exception,perl_exception);
12534 exception=DestroyExceptionInfo(exception);
12535 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
12536 SvPOK_on(perl_exception);
12537 ST(0)=sv_2mortal(perl_exception);
12538 XSRETURN(1);
12539 }
12540
12541#
12542###############################################################################
12543# #
12544# #
12545# #
12546# Q u e r y C o l o r #
12547# #
12548# #
12549# #
12550###############################################################################
12551#
12552#
12553void
12554QueryColor(ref,...)
12555 Image::Magick ref=NO_INIT
12556 ALIAS:
12557 querycolor = 1
12558 PPCODE:
12559 {
12560 char
12561 *name;
12562
12563 ExceptionInfo
12564 *exception;
12565
12566 PixelInfo
12567 color;
12568
12569 register ssize_t
12570 i;
12571
12572 SV
12573 *perl_exception;
12574
12575 PERL_UNUSED_VAR(ref);
12576 PERL_UNUSED_VAR(ix);
12577 exception=AcquireExceptionInfo();
12578 perl_exception=newSVpv("",0);
12579 if (items == 1)
12580 {
12581 const ColorInfo
12582 **colorlist;
12583
12584 size_t
12585 colors;
12586
12587 colorlist=GetColorInfoList("*",&colors,exception);
12588 EXTEND(sp,colors);
12589 for (i=0; i < (ssize_t) colors; i++)
12590 {
12591 PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
12592 }
12593 colorlist=(const ColorInfo **)
12594 RelinquishMagickMemory((ColorInfo **) colorlist);
12595 goto PerlException;
12596 }
12597 EXTEND(sp,5*items);
12598 for (i=1; i < items; i++)
12599 {
12600 name=(char *) SvPV(ST(i),na);
12601 if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
12602 {
12603 PUSHs(&sv_undef);
12604 continue;
12605 }
12606 PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
12607 PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
12608 PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
12609 if (color.colorspace == CMYKColorspace)
12610 PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
cristy17f11b02014-12-20 19:37:04 +000012611 if (color.alpha_trait != UndefinedPixelTrait)
cristy4a3ce0a2013-08-03 20:06:59 +000012612 PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
12613 }
12614
12615 PerlException:
12616 InheritPerlException(exception,perl_exception);
12617 exception=DestroyExceptionInfo(exception);
12618 SvREFCNT_dec(perl_exception);
12619 }
12620
12621#
12622###############################################################################
12623# #
12624# #
12625# #
12626# Q u e r y C o l o r N a m e #
12627# #
12628# #
12629# #
12630###############################################################################
12631#
12632#
12633void
12634QueryColorname(ref,...)
12635 Image::Magick ref=NO_INIT
12636 ALIAS:
12637 querycolorname = 1
12638 PPCODE:
12639 {
12640 AV
12641 *av;
12642
12643 char
cristy151b66d2015-04-15 10:50:31 +000012644 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012645
12646 ExceptionInfo
12647 *exception;
12648
12649 Image
12650 *image;
12651
12652 PixelInfo
12653 target_color;
12654
12655 register ssize_t
12656 i;
12657
12658 struct PackageInfo
12659 *info;
12660
12661 SV
12662 *perl_exception,
12663 *reference; /* reference is the SV* of ref=SvIV(reference) */
12664
12665 PERL_UNUSED_VAR(ref);
12666 PERL_UNUSED_VAR(ix);
12667 exception=AcquireExceptionInfo();
12668 perl_exception=newSVpv("",0);
12669 reference=SvRV(ST(0));
12670 av=(AV *) reference;
12671 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12672 exception);
12673 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12674 if (image == (Image *) NULL)
12675 {
12676 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12677 PackageName);
12678 goto PerlException;
12679 }
12680 EXTEND(sp,items);
12681 for (i=1; i < items; i++)
12682 {
12683 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
12684 exception);
12685 (void) QueryColorname(image,&target_color,SVGCompliance,message,
12686 exception);
12687 PUSHs(sv_2mortal(newSVpv(message,0)));
12688 }
12689
12690 PerlException:
12691 InheritPerlException(exception,perl_exception);
12692 exception=DestroyExceptionInfo(exception);
12693 SvREFCNT_dec(perl_exception);
12694 }
12695
12696#
12697###############################################################################
12698# #
12699# #
12700# #
12701# Q u e r y F o n t #
12702# #
12703# #
12704# #
12705###############################################################################
12706#
12707#
12708void
12709QueryFont(ref,...)
12710 Image::Magick ref=NO_INIT
12711 ALIAS:
12712 queryfont = 1
12713 PPCODE:
12714 {
12715 char
12716 *name,
cristy151b66d2015-04-15 10:50:31 +000012717 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000012718
12719 ExceptionInfo
12720 *exception;
12721
12722 register ssize_t
12723 i;
12724
12725 SV
12726 *perl_exception;
12727
12728 volatile const TypeInfo
12729 *type_info;
12730
12731 PERL_UNUSED_VAR(ref);
12732 PERL_UNUSED_VAR(ix);
12733 exception=AcquireExceptionInfo();
12734 perl_exception=newSVpv("",0);
12735 if (items == 1)
12736 {
12737 const TypeInfo
12738 **typelist;
12739
12740 size_t
12741 types;
12742
12743 typelist=GetTypeInfoList("*",&types,exception);
12744 EXTEND(sp,types);
12745 for (i=0; i < (ssize_t) types; i++)
12746 {
12747 PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
12748 }
12749 typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
12750 typelist);
12751 goto PerlException;
12752 }
12753 EXTEND(sp,10*items);
12754 for (i=1; i < items; i++)
12755 {
12756 name=(char *) SvPV(ST(i),na);
12757 type_info=GetTypeInfo(name,exception);
12758 if (type_info == (TypeInfo *) NULL)
12759 {
12760 PUSHs(&sv_undef);
12761 continue;
12762 }
12763 if (type_info->name == (char *) NULL)
12764 PUSHs(&sv_undef);
12765 else
12766 PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
12767 if (type_info->description == (char *) NULL)
12768 PUSHs(&sv_undef);
12769 else
12770 PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
12771 if (type_info->family == (char *) NULL)
12772 PUSHs(&sv_undef);
12773 else
12774 PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
12775 if (type_info->style == UndefinedStyle)
12776 PUSHs(&sv_undef);
12777 else
12778 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
12779 type_info->style),0)));
12780 if (type_info->stretch == UndefinedStretch)
12781 PUSHs(&sv_undef);
12782 else
12783 PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
12784 type_info->stretch),0)));
cristy151b66d2015-04-15 10:50:31 +000012785 (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double)
cristy4a3ce0a2013-08-03 20:06:59 +000012786 type_info->weight);
12787 PUSHs(sv_2mortal(newSVpv(message,0)));
12788 if (type_info->encoding == (char *) NULL)
12789 PUSHs(&sv_undef);
12790 else
12791 PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
12792 if (type_info->foundry == (char *) NULL)
12793 PUSHs(&sv_undef);
12794 else
12795 PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
12796 if (type_info->format == (char *) NULL)
12797 PUSHs(&sv_undef);
12798 else
12799 PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
12800 if (type_info->metrics == (char *) NULL)
12801 PUSHs(&sv_undef);
12802 else
12803 PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
12804 if (type_info->glyphs == (char *) NULL)
12805 PUSHs(&sv_undef);
12806 else
12807 PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
12808 }
12809
12810 PerlException:
12811 InheritPerlException(exception,perl_exception);
12812 exception=DestroyExceptionInfo(exception);
12813 SvREFCNT_dec(perl_exception);
12814 }
12815
12816#
12817###############################################################################
12818# #
12819# #
12820# #
12821# Q u e r y F o n t M e t r i c s #
12822# #
12823# #
12824# #
12825###############################################################################
12826#
12827#
12828void
12829QueryFontMetrics(ref,...)
12830 Image::Magick ref=NO_INIT
12831 ALIAS:
12832 queryfontmetrics = 1
12833 PPCODE:
12834 {
12835 AffineMatrix
12836 affine,
12837 current;
12838
12839 AV
12840 *av;
12841
12842 char
12843 *attribute;
12844
12845 double
12846 x,
12847 y;
12848
12849 DrawInfo
12850 *draw_info;
12851
12852 ExceptionInfo
12853 *exception;
12854
12855 GeometryInfo
12856 geometry_info;
12857
12858 Image
12859 *image;
12860
12861 MagickBooleanType
12862 status;
12863
12864 MagickStatusType
12865 flags;
12866
12867 register ssize_t
12868 i;
12869
12870 ssize_t
12871 type;
12872
12873 struct PackageInfo
12874 *info,
12875 *package_info;
12876
12877 SV
12878 *perl_exception,
12879 *reference; /* reference is the SV* of ref=SvIV(reference) */
12880
12881 TypeMetric
12882 metrics;
12883
12884 PERL_UNUSED_VAR(ref);
12885 PERL_UNUSED_VAR(ix);
12886 exception=AcquireExceptionInfo();
12887 package_info=(struct PackageInfo *) NULL;
12888 perl_exception=newSVpv("",0);
12889 reference=SvRV(ST(0));
12890 av=(AV *) reference;
12891 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
12892 exception);
12893 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
12894 if (image == (Image *) NULL)
12895 {
12896 ThrowPerlException(exception,OptionError,"NoImagesDefined",
12897 PackageName);
12898 goto PerlException;
12899 }
12900 package_info=ClonePackageInfo(info,exception);
12901 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
12902 CloneString(&draw_info->text,"");
12903 current=draw_info->affine;
12904 GetAffineMatrix(&affine);
12905 x=0.0;
12906 y=0.0;
12907 EXTEND(sp,7*items);
12908 for (i=2; i < items; i+=2)
12909 {
12910 attribute=(char *) SvPV(ST(i-1),na);
12911 switch (*attribute)
12912 {
12913 case 'A':
12914 case 'a':
12915 {
12916 if (LocaleCompare(attribute,"antialias") == 0)
12917 {
12918 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
12919 SvPV(ST(i),na));
12920 if (type < 0)
12921 {
12922 ThrowPerlException(exception,OptionError,"UnrecognizedType",
12923 SvPV(ST(i),na));
12924 break;
12925 }
12926 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
12927 break;
12928 }
12929 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12930 attribute);
12931 break;
12932 }
12933 case 'd':
12934 case 'D':
12935 {
12936 if (LocaleCompare(attribute,"density") == 0)
12937 {
12938 CloneString(&draw_info->density,SvPV(ST(i),na));
12939 break;
12940 }
12941 if (LocaleCompare(attribute,"direction") == 0)
12942 {
12943 draw_info->direction=(DirectionType) ParseCommandOption(
12944 MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
12945 break;
12946 }
12947 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12948 attribute);
12949 break;
12950 }
12951 case 'e':
12952 case 'E':
12953 {
12954 if (LocaleCompare(attribute,"encoding") == 0)
12955 {
12956 CloneString(&draw_info->encoding,SvPV(ST(i),na));
12957 break;
12958 }
12959 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12960 attribute);
12961 break;
12962 }
12963 case 'f':
12964 case 'F':
12965 {
12966 if (LocaleCompare(attribute,"family") == 0)
12967 {
12968 CloneString(&draw_info->family,SvPV(ST(i),na));
12969 break;
12970 }
12971 if (LocaleCompare(attribute,"fill") == 0)
12972 {
12973 if (info)
12974 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
12975 &draw_info->fill,exception);
12976 break;
12977 }
12978 if (LocaleCompare(attribute,"font") == 0)
12979 {
12980 CloneString(&draw_info->font,SvPV(ST(i),na));
12981 break;
12982 }
12983 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
12984 attribute);
12985 break;
12986 }
12987 case 'g':
12988 case 'G':
12989 {
12990 if (LocaleCompare(attribute,"geometry") == 0)
12991 {
12992 CloneString(&draw_info->geometry,SvPV(ST(i),na));
12993 break;
12994 }
12995 if (LocaleCompare(attribute,"gravity") == 0)
12996 {
12997 draw_info->gravity=(GravityType) ParseCommandOption(
12998 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
12999 break;
13000 }
13001 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13002 attribute);
13003 break;
13004 }
13005 case 'i':
13006 case 'I':
13007 {
13008 if (LocaleCompare(attribute,"interline-spacing") == 0)
13009 {
13010 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13011 draw_info->interline_spacing=geometry_info.rho;
13012 break;
13013 }
13014 if (LocaleCompare(attribute,"interword-spacing") == 0)
13015 {
13016 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13017 draw_info->interword_spacing=geometry_info.rho;
13018 break;
13019 }
13020 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13021 attribute);
13022 break;
13023 }
13024 case 'k':
13025 case 'K':
13026 {
13027 if (LocaleCompare(attribute,"kerning") == 0)
13028 {
13029 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13030 draw_info->kerning=geometry_info.rho;
13031 break;
13032 }
13033 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13034 attribute);
13035 break;
13036 }
13037 case 'p':
13038 case 'P':
13039 {
13040 if (LocaleCompare(attribute,"pointsize") == 0)
13041 {
13042 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13043 draw_info->pointsize=geometry_info.rho;
13044 break;
13045 }
13046 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13047 attribute);
13048 break;
13049 }
13050 case 'r':
13051 case 'R':
13052 {
13053 if (LocaleCompare(attribute,"rotate") == 0)
13054 {
13055 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13056 affine.rx=geometry_info.rho;
13057 affine.ry=geometry_info.sigma;
13058 if ((flags & SigmaValue) == 0)
13059 affine.ry=affine.rx;
13060 break;
13061 }
13062 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13063 attribute);
13064 break;
13065 }
13066 case 's':
13067 case 'S':
13068 {
13069 if (LocaleCompare(attribute,"scale") == 0)
13070 {
13071 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13072 affine.sx=geometry_info.rho;
13073 affine.sy=geometry_info.sigma;
13074 if ((flags & SigmaValue) == 0)
13075 affine.sy=affine.sx;
13076 break;
13077 }
13078 if (LocaleCompare(attribute,"skew") == 0)
13079 {
13080 double
13081 x_angle,
13082 y_angle;
13083
13084 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13085 x_angle=geometry_info.rho;
13086 y_angle=geometry_info.sigma;
13087 if ((flags & SigmaValue) == 0)
13088 y_angle=x_angle;
13089 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13090 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13091 break;
13092 }
13093 if (LocaleCompare(attribute,"stroke") == 0)
13094 {
13095 if (info)
13096 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13097 &draw_info->stroke,exception);
13098 break;
13099 }
13100 if (LocaleCompare(attribute,"style") == 0)
13101 {
13102 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13103 SvPV(ST(i),na));
13104 if (type < 0)
13105 {
13106 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13107 SvPV(ST(i),na));
13108 break;
13109 }
13110 draw_info->style=(StyleType) type;
13111 break;
13112 }
13113 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13114 attribute);
13115 break;
13116 }
13117 case 't':
13118 case 'T':
13119 {
13120 if (LocaleCompare(attribute,"text") == 0)
13121 {
13122 CloneString(&draw_info->text,SvPV(ST(i),na));
13123 break;
13124 }
13125 if (LocaleCompare(attribute,"translate") == 0)
13126 {
13127 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13128 affine.tx=geometry_info.rho;
13129 affine.ty=geometry_info.sigma;
13130 if ((flags & SigmaValue) == 0)
13131 affine.ty=affine.tx;
13132 break;
13133 }
13134 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13135 attribute);
13136 break;
13137 }
13138 case 'w':
13139 case 'W':
13140 {
13141 if (LocaleCompare(attribute,"weight") == 0)
13142 {
13143 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13144 draw_info->weight=(size_t) geometry_info.rho;
13145 break;
13146 }
13147 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13148 attribute);
13149 break;
13150 }
13151 case 'x':
13152 case 'X':
13153 {
13154 if (LocaleCompare(attribute,"x") == 0)
13155 {
13156 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13157 x=geometry_info.rho;
13158 break;
13159 }
13160 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13161 attribute);
13162 break;
13163 }
13164 case 'y':
13165 case 'Y':
13166 {
13167 if (LocaleCompare(attribute,"y") == 0)
13168 {
13169 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13170 y=geometry_info.rho;
13171 break;
13172 }
13173 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13174 attribute);
13175 break;
13176 }
13177 default:
13178 {
13179 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13180 attribute);
13181 break;
13182 }
13183 }
13184 }
13185 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13186 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13187 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13188 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13189 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13190 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13191 if (draw_info->geometry == (char *) NULL)
13192 {
13193 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013194 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -050013195 "%.20g,%.20g",x,y);
cristy4a3ce0a2013-08-03 20:06:59 +000013196 }
13197 status=GetTypeMetrics(image,draw_info,&metrics,exception);
13198 (void) CatchImageException(image);
13199 if (status == MagickFalse)
13200 PUSHs(&sv_undef);
13201 else
13202 {
13203 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13204 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13205 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13206 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13207 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13208 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13209 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13210 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13211 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13212 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13213 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13214 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13215 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13216 }
13217 draw_info=DestroyDrawInfo(draw_info);
13218
13219 PerlException:
13220 if (package_info != (struct PackageInfo *) NULL)
13221 DestroyPackageInfo(package_info);
13222 InheritPerlException(exception,perl_exception);
13223 exception=DestroyExceptionInfo(exception);
13224 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13225 }
13226
13227#
13228###############################################################################
13229# #
13230# #
13231# #
13232# 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 #
13233# #
13234# #
13235# #
13236###############################################################################
13237#
13238#
13239void
13240QueryMultilineFontMetrics(ref,...)
13241 Image::Magick ref=NO_INIT
13242 ALIAS:
13243 querymultilinefontmetrics = 1
13244 PPCODE:
13245 {
13246 AffineMatrix
13247 affine,
13248 current;
13249
13250 AV
13251 *av;
13252
13253 char
13254 *attribute;
13255
13256 double
13257 x,
13258 y;
13259
13260 DrawInfo
13261 *draw_info;
13262
13263 ExceptionInfo
13264 *exception;
13265
13266 GeometryInfo
13267 geometry_info;
13268
13269 Image
13270 *image;
13271
13272 MagickBooleanType
13273 status;
13274
13275 MagickStatusType
13276 flags;
13277
13278 register ssize_t
13279 i;
13280
13281 ssize_t
13282 type;
13283
13284 struct PackageInfo
13285 *info,
13286 *package_info;
13287
13288 SV
13289 *perl_exception,
13290 *reference; /* reference is the SV* of ref=SvIV(reference) */
13291
13292 TypeMetric
13293 metrics;
13294
13295 PERL_UNUSED_VAR(ref);
13296 PERL_UNUSED_VAR(ix);
13297 exception=AcquireExceptionInfo();
13298 package_info=(struct PackageInfo *) NULL;
13299 perl_exception=newSVpv("",0);
13300 reference=SvRV(ST(0));
13301 av=(AV *) reference;
13302 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13303 exception);
13304 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
13305 if (image == (Image *) NULL)
13306 {
13307 ThrowPerlException(exception,OptionError,"NoImagesDefined",
13308 PackageName);
13309 goto PerlException;
13310 }
13311 package_info=ClonePackageInfo(info,exception);
13312 draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
13313 CloneString(&draw_info->text,"");
13314 current=draw_info->affine;
13315 GetAffineMatrix(&affine);
13316 x=0.0;
13317 y=0.0;
13318 EXTEND(sp,7*items);
13319 for (i=2; i < items; i+=2)
13320 {
13321 attribute=(char *) SvPV(ST(i-1),na);
13322 switch (*attribute)
13323 {
13324 case 'A':
13325 case 'a':
13326 {
13327 if (LocaleCompare(attribute,"antialias") == 0)
13328 {
13329 type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
13330 SvPV(ST(i),na));
13331 if (type < 0)
13332 {
13333 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13334 SvPV(ST(i),na));
13335 break;
13336 }
13337 draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
13338 break;
13339 }
13340 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13341 attribute);
13342 break;
13343 }
13344 case 'd':
13345 case 'D':
13346 {
13347 if (LocaleCompare(attribute,"density") == 0)
13348 {
13349 CloneString(&draw_info->density,SvPV(ST(i),na));
13350 break;
13351 }
13352 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13353 attribute);
13354 break;
13355 }
13356 case 'e':
13357 case 'E':
13358 {
13359 if (LocaleCompare(attribute,"encoding") == 0)
13360 {
13361 CloneString(&draw_info->encoding,SvPV(ST(i),na));
13362 break;
13363 }
13364 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13365 attribute);
13366 break;
13367 }
13368 case 'f':
13369 case 'F':
13370 {
13371 if (LocaleCompare(attribute,"family") == 0)
13372 {
13373 CloneString(&draw_info->family,SvPV(ST(i),na));
13374 break;
13375 }
13376 if (LocaleCompare(attribute,"fill") == 0)
13377 {
13378 if (info)
13379 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13380 &draw_info->fill,exception);
13381 break;
13382 }
13383 if (LocaleCompare(attribute,"font") == 0)
13384 {
13385 CloneString(&draw_info->font,SvPV(ST(i),na));
13386 break;
13387 }
13388 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13389 attribute);
13390 break;
13391 }
13392 case 'g':
13393 case 'G':
13394 {
13395 if (LocaleCompare(attribute,"geometry") == 0)
13396 {
13397 CloneString(&draw_info->geometry,SvPV(ST(i),na));
13398 break;
13399 }
13400 if (LocaleCompare(attribute,"gravity") == 0)
13401 {
13402 draw_info->gravity=(GravityType) ParseCommandOption(
13403 MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
13404 break;
13405 }
13406 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13407 attribute);
13408 break;
13409 }
13410 case 'p':
13411 case 'P':
13412 {
13413 if (LocaleCompare(attribute,"pointsize") == 0)
13414 {
13415 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13416 draw_info->pointsize=geometry_info.rho;
13417 break;
13418 }
13419 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13420 attribute);
13421 break;
13422 }
13423 case 'r':
13424 case 'R':
13425 {
13426 if (LocaleCompare(attribute,"rotate") == 0)
13427 {
13428 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13429 affine.rx=geometry_info.rho;
13430 affine.ry=geometry_info.sigma;
13431 if ((flags & SigmaValue) == 0)
13432 affine.ry=affine.rx;
13433 break;
13434 }
13435 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13436 attribute);
13437 break;
13438 }
13439 case 's':
13440 case 'S':
13441 {
13442 if (LocaleCompare(attribute,"scale") == 0)
13443 {
13444 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13445 affine.sx=geometry_info.rho;
13446 affine.sy=geometry_info.sigma;
13447 if ((flags & SigmaValue) == 0)
13448 affine.sy=affine.sx;
13449 break;
13450 }
13451 if (LocaleCompare(attribute,"skew") == 0)
13452 {
13453 double
13454 x_angle,
13455 y_angle;
13456
13457 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13458 x_angle=geometry_info.rho;
13459 y_angle=geometry_info.sigma;
13460 if ((flags & SigmaValue) == 0)
13461 y_angle=x_angle;
13462 affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
13463 affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
13464 break;
13465 }
13466 if (LocaleCompare(attribute,"stroke") == 0)
13467 {
13468 if (info)
13469 (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
13470 &draw_info->stroke,exception);
13471 break;
13472 }
13473 if (LocaleCompare(attribute,"style") == 0)
13474 {
13475 type=ParseCommandOption(MagickStyleOptions,MagickFalse,
13476 SvPV(ST(i),na));
13477 if (type < 0)
13478 {
13479 ThrowPerlException(exception,OptionError,"UnrecognizedType",
13480 SvPV(ST(i),na));
13481 break;
13482 }
13483 draw_info->style=(StyleType) type;
13484 break;
13485 }
13486 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13487 attribute);
13488 break;
13489 }
13490 case 't':
13491 case 'T':
13492 {
13493 if (LocaleCompare(attribute,"text") == 0)
13494 {
13495 CloneString(&draw_info->text,SvPV(ST(i),na));
13496 break;
13497 }
13498 if (LocaleCompare(attribute,"translate") == 0)
13499 {
13500 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13501 affine.tx=geometry_info.rho;
13502 affine.ty=geometry_info.sigma;
13503 if ((flags & SigmaValue) == 0)
13504 affine.ty=affine.tx;
13505 break;
13506 }
13507 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13508 attribute);
13509 break;
13510 }
13511 case 'w':
13512 case 'W':
13513 {
13514 if (LocaleCompare(attribute,"weight") == 0)
13515 {
13516 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13517 draw_info->weight=(size_t) geometry_info.rho;
13518 break;
13519 }
13520 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13521 attribute);
13522 break;
13523 }
13524 case 'x':
13525 case 'X':
13526 {
13527 if (LocaleCompare(attribute,"x") == 0)
13528 {
13529 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13530 x=geometry_info.rho;
13531 break;
13532 }
13533 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13534 attribute);
13535 break;
13536 }
13537 case 'y':
13538 case 'Y':
13539 {
13540 if (LocaleCompare(attribute,"y") == 0)
13541 {
13542 flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
13543 y=geometry_info.rho;
13544 break;
13545 }
13546 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13547 attribute);
13548 break;
13549 }
13550 default:
13551 {
13552 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
13553 attribute);
13554 break;
13555 }
13556 }
13557 }
13558 draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
13559 draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
13560 draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
13561 draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
13562 draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
13563 draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
13564 if (draw_info->geometry == (char *) NULL)
13565 {
13566 draw_info->geometry=AcquireString((char *) NULL);
cristy151b66d2015-04-15 10:50:31 +000013567 (void) FormatLocaleString(draw_info->geometry,MagickPathExtent,
Cristyb1710fe2017-02-11 13:51:48 -050013568 "%.20g,%.20g",x,y);
cristy4a3ce0a2013-08-03 20:06:59 +000013569 }
13570 status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
13571 (void) CatchException(exception);
13572 if (status == MagickFalse)
13573 PUSHs(&sv_undef);
13574 else
13575 {
13576 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
13577 PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
13578 PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
13579 PUSHs(sv_2mortal(newSVnv(metrics.descent)));
13580 PUSHs(sv_2mortal(newSVnv(metrics.width)));
13581 PUSHs(sv_2mortal(newSVnv(metrics.height)));
13582 PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
13583 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
13584 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
13585 PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
13586 PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
13587 PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
13588 PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
13589 }
13590 draw_info=DestroyDrawInfo(draw_info);
13591
13592 PerlException:
13593 if (package_info != (struct PackageInfo *) NULL)
13594 DestroyPackageInfo(package_info);
13595 InheritPerlException(exception,perl_exception);
13596 exception=DestroyExceptionInfo(exception);
13597 SvREFCNT_dec(perl_exception); /* can't return warning messages */
13598 }
13599
13600#
13601###############################################################################
13602# #
13603# #
13604# #
13605# Q u e r y F o r m a t #
13606# #
13607# #
13608# #
13609###############################################################################
13610#
13611#
13612void
13613QueryFormat(ref,...)
13614 Image::Magick ref=NO_INIT
13615 ALIAS:
13616 queryformat = 1
13617 PPCODE:
13618 {
13619 char
13620 *name;
13621
13622 ExceptionInfo
13623 *exception;
13624
13625 register ssize_t
13626 i;
13627
13628 SV
13629 *perl_exception;
13630
13631 volatile const MagickInfo
13632 *magick_info;
13633
13634 PERL_UNUSED_VAR(ref);
13635 PERL_UNUSED_VAR(ix);
13636 exception=AcquireExceptionInfo();
13637 perl_exception=newSVpv("",0);
13638 if (items == 1)
13639 {
13640 char
cristy151b66d2015-04-15 10:50:31 +000013641 format[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000013642
13643 const MagickInfo
13644 **format_list;
13645
13646 size_t
13647 types;
13648
13649 format_list=GetMagickInfoList("*",&types,exception);
13650 EXTEND(sp,types);
13651 for (i=0; i < (ssize_t) types; i++)
13652 {
cristy151b66d2015-04-15 10:50:31 +000013653 (void) CopyMagickString(format,format_list[i]->name,MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000013654 LocaleLower(format);
13655 PUSHs(sv_2mortal(newSVpv(format,0)));
13656 }
13657 format_list=(const MagickInfo **)
13658 RelinquishMagickMemory((MagickInfo *) format_list);
13659 goto PerlException;
13660 }
13661 EXTEND(sp,8*items);
13662 for (i=1; i < items; i++)
13663 {
13664 name=(char *) SvPV(ST(i),na);
13665 magick_info=GetMagickInfo(name,exception);
13666 if (magick_info == (const MagickInfo *) NULL)
13667 {
13668 PUSHs(&sv_undef);
13669 continue;
13670 }
cristy4a3ce0a2013-08-03 20:06:59 +000013671 if (magick_info->description == (char *) NULL)
13672 PUSHs(&sv_undef);
13673 else
13674 PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
Cristy31756212019-07-31 15:55:08 -040013675 if (magick_info->magick_module == (char *) NULL)
cristy4a3ce0a2013-08-03 20:06:59 +000013676 PUSHs(&sv_undef);
13677 else
Cristy31756212019-07-31 15:55:08 -040013678 PUSHs(sv_2mortal(newSVpv(magick_info->magick_module,0)));
cristy4a3ce0a2013-08-03 20:06:59 +000013679 }
13680
13681 PerlException:
13682 InheritPerlException(exception,perl_exception);
13683 exception=DestroyExceptionInfo(exception);
13684 SvREFCNT_dec(perl_exception);
13685 }
13686
13687#
13688###############################################################################
13689# #
13690# #
13691# #
13692# Q u e r y O p t i o n #
13693# #
13694# #
13695# #
13696###############################################################################
13697#
13698#
13699void
13700QueryOption(ref,...)
13701 Image::Magick ref=NO_INIT
13702 ALIAS:
13703 queryoption = 1
13704 PPCODE:
13705 {
13706 char
13707 **options;
13708
13709 ExceptionInfo
13710 *exception;
13711
13712 register ssize_t
13713 i;
13714
13715 ssize_t
13716 j,
13717 option;
13718
13719 SV
13720 *perl_exception;
13721
13722 PERL_UNUSED_VAR(ref);
13723 PERL_UNUSED_VAR(ix);
13724 exception=AcquireExceptionInfo();
13725 perl_exception=newSVpv("",0);
13726 EXTEND(sp,8*items);
13727 for (i=1; i < items; i++)
13728 {
13729 option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
13730 SvPV(ST(i),na));
13731 options=GetCommandOptions((CommandOption) option);
13732 if (options == (char **) NULL)
13733 PUSHs(&sv_undef);
13734 else
13735 {
13736 for (j=0; options[j] != (char *) NULL; j++)
13737 PUSHs(sv_2mortal(newSVpv(options[j],0)));
13738 options=DestroyStringList(options);
13739 }
13740 }
13741
13742 InheritPerlException(exception,perl_exception);
13743 exception=DestroyExceptionInfo(exception);
13744 SvREFCNT_dec(perl_exception);
13745 }
13746
13747#
13748###############################################################################
13749# #
13750# #
13751# #
13752# R e a d #
13753# #
13754# #
13755# #
13756###############################################################################
13757#
13758#
13759void
13760Read(ref,...)
13761 Image::Magick ref=NO_INIT
13762 ALIAS:
13763 ReadImage = 1
13764 read = 2
13765 readimage = 3
13766 PPCODE:
13767 {
13768 AV
13769 *av;
13770
13771 char
13772 **keep,
13773 **list;
13774
13775 ExceptionInfo
13776 *exception;
13777
13778 HV
13779 *hv;
13780
13781 Image
13782 *image;
13783
13784 int
13785 n;
13786
13787 MagickBooleanType
13788 status;
13789
13790 register char
13791 **p;
13792
13793 register ssize_t
13794 i;
13795
13796 ssize_t
13797 ac,
13798 number_images;
13799
13800 STRLEN
13801 *length;
13802
13803 struct PackageInfo
13804 *info,
13805 *package_info;
13806
13807 SV
13808 *perl_exception, /* Perl variable for storing messages */
13809 *reference,
13810 *rv,
13811 *sv;
13812
13813 PERL_UNUSED_VAR(ref);
13814 PERL_UNUSED_VAR(ix);
13815 exception=AcquireExceptionInfo();
13816 perl_exception=newSVpv("",0);
13817 sv=NULL;
13818 package_info=(struct PackageInfo *) NULL;
13819 number_images=0;
13820 ac=(items < 2) ? 1 : items-1;
13821 list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
13822 keep=list;
13823 length=(STRLEN *) NULL;
13824 if (list == (char **) NULL)
13825 {
13826 ThrowPerlException(exception,ResourceLimitError,
13827 "MemoryAllocationFailed",PackageName);
13828 goto PerlException;
13829 }
13830 length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
13831 if (length == (STRLEN *) NULL)
13832 {
13833 ThrowPerlException(exception,ResourceLimitError,
13834 "MemoryAllocationFailed",PackageName);
13835 goto PerlException;
13836 }
13837 if (sv_isobject(ST(0)) == 0)
13838 {
13839 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13840 PackageName);
13841 goto PerlException;
13842 }
13843 reference=SvRV(ST(0));
13844 hv=SvSTASH(reference);
13845 if (SvTYPE(reference) != SVt_PVAV)
13846 {
13847 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
13848 PackageName);
13849 goto PerlException;
13850 }
13851 av=(AV *) reference;
13852 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
13853 exception);
13854 package_info=ClonePackageInfo(info,exception);
13855 n=1;
13856 if (items <= 1)
13857 *list=(char *) (*package_info->image_info->filename ?
13858 package_info->image_info->filename : "XC:black");
13859 else
13860 for (n=0, i=0; i < ac; i++)
13861 {
13862 list[n]=(char *) SvPV(ST(i+1),length[n]);
13863 if ((items >= 3) && strEQcase(list[n],"blob"))
13864 {
13865 void
13866 *blob;
13867
13868 i++;
13869 blob=(void *) (SvPV(ST(i+1),length[n]));
13870 SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
13871 }
13872 if ((items >= 3) && strEQcase(list[n],"filename"))
13873 continue;
13874 if ((items >= 3) && strEQcase(list[n],"file"))
13875 {
13876 FILE
13877 *file;
13878
13879 PerlIO
13880 *io_info;
13881
13882 i++;
13883 io_info=IoIFP(sv_2io(ST(i+1)));
13884 if (io_info == (PerlIO *) NULL)
13885 {
13886 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13887 PackageName);
13888 continue;
13889 }
13890 file=PerlIO_findFILE(io_info);
13891 if (file == (FILE *) NULL)
13892 {
13893 ThrowPerlException(exception,BlobError,"UnableToOpenFile",
13894 PackageName);
13895 continue;
13896 }
13897 SetImageInfoFile(package_info->image_info,file);
13898 }
13899 if ((items >= 3) && strEQcase(list[n],"magick"))
13900 continue;
13901 n++;
13902 }
13903 list[n]=(char *) NULL;
13904 keep=list;
13905 status=ExpandFilenames(&n,&list);
13906 if (status == MagickFalse)
13907 {
13908 ThrowPerlException(exception,ResourceLimitError,
13909 "MemoryAllocationFailed",PackageName);
13910 goto PerlException;
13911 }
13912 number_images=0;
13913 for (i=0; i < n; i++)
13914 {
13915 if ((package_info->image_info->file == (FILE *) NULL) &&
13916 (package_info->image_info->blob == (void *) NULL))
13917 image=ReadImages(package_info->image_info,list[i],exception);
13918 else
13919 {
13920 image=ReadImages(package_info->image_info,
13921 package_info->image_info->filename,exception);
13922 if (image != (Image *) NULL)
13923 DisassociateImageStream(image);
13924 }
13925 if (image == (Image *) NULL)
13926 break;
13927 for ( ; image; image=image->next)
13928 {
13929 AddImageToRegistry(sv,image);
13930 rv=newRV(sv);
13931 av_push(av,sv_bless(rv,hv));
13932 SvREFCNT_dec(sv);
13933 number_images++;
13934 }
13935 }
13936 /*
13937 Free resources.
13938 */
13939 for (i=0; i < n; i++)
13940 if (list[i] != (char *) NULL)
13941 for (p=keep; list[i] != *p++; )
13942 if (*p == (char *) NULL)
13943 {
13944 list[i]=(char *) RelinquishMagickMemory(list[i]);
13945 break;
13946 }
13947
13948 PerlException:
13949 if (package_info != (struct PackageInfo *) NULL)
13950 DestroyPackageInfo(package_info);
13951 if (list && (list != keep))
13952 list=(char **) RelinquishMagickMemory(list);
13953 if (keep)
13954 keep=(char **) RelinquishMagickMemory(keep);
13955 if (length)
13956 length=(STRLEN *) RelinquishMagickMemory(length);
13957 InheritPerlException(exception,perl_exception);
13958 exception=DestroyExceptionInfo(exception);
13959 sv_setiv(perl_exception,(IV) number_images);
13960 SvPOK_on(perl_exception);
13961 ST(0)=sv_2mortal(perl_exception);
13962 XSRETURN(1);
13963 }
13964
13965#
13966###############################################################################
13967# #
13968# #
13969# #
13970# R e m o t e #
13971# #
13972# #
13973# #
13974###############################################################################
13975#
13976#
13977void
13978Remote(ref,...)
13979 Image::Magick ref=NO_INIT
13980 ALIAS:
13981 RemoteCommand = 1
13982 remote = 2
13983 remoteCommand = 3
13984 PPCODE:
13985 {
13986 AV
13987 *av;
13988
13989 ExceptionInfo
13990 *exception;
13991
13992 register ssize_t
13993 i;
13994
13995 SV
13996 *perl_exception,
13997 *reference;
13998
13999 struct PackageInfo
14000 *info;
14001
14002 PERL_UNUSED_VAR(ref);
14003 PERL_UNUSED_VAR(ix);
14004 exception=AcquireExceptionInfo();
14005 perl_exception=newSVpv("",0);
14006 reference=SvRV(ST(0));
14007 av=(AV *) reference;
14008 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
14009 exception);
14010 for (i=1; i < items; i++)
14011 (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
14012 SvPV(ST(i),na),exception);
14013 InheritPerlException(exception,perl_exception);
14014 exception=DestroyExceptionInfo(exception);
14015 SvREFCNT_dec(perl_exception); /* throw away all errors */
14016 }
14017
14018#
14019###############################################################################
14020# #
14021# #
14022# #
14023# S e t #
14024# #
14025# #
14026# #
14027###############################################################################
14028#
14029#
14030void
14031Set(ref,...)
14032 Image::Magick ref=NO_INIT
14033 ALIAS:
14034 SetAttributes = 1
14035 SetAttribute = 2
14036 set = 3
14037 setattributes = 4
14038 setattribute = 5
14039 PPCODE:
14040 {
14041 ExceptionInfo
14042 *exception;
14043
14044 Image
14045 *image;
14046
14047 register ssize_t
14048 i;
14049
14050 struct PackageInfo
14051 *info;
14052
14053 SV
14054 *perl_exception,
14055 *reference; /* reference is the SV* of ref=SvIV(reference) */
14056
14057 PERL_UNUSED_VAR(ref);
14058 PERL_UNUSED_VAR(ix);
14059 exception=AcquireExceptionInfo();
14060 perl_exception=newSVpv("",0);
14061 if (sv_isobject(ST(0)) == 0)
14062 {
14063 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14064 PackageName);
14065 goto PerlException;
14066 }
14067 reference=SvRV(ST(0));
14068 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14069 if (items == 2)
14070 SetAttribute(aTHX_ info,image,"size",ST(1),exception);
14071 else
14072 for (i=2; i < items; i+=2)
14073 SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
14074
14075 PerlException:
14076 InheritPerlException(exception,perl_exception);
14077 exception=DestroyExceptionInfo(exception);
14078 sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
14079 SvPOK_on(perl_exception);
14080 ST(0)=sv_2mortal(perl_exception);
14081 XSRETURN(1);
14082 }
14083
14084#
14085###############################################################################
14086# #
14087# #
14088# #
14089# S e t P i x e l #
14090# #
14091# #
14092# #
14093###############################################################################
14094#
14095#
14096void
14097SetPixel(ref,...)
14098 Image::Magick ref=NO_INIT
14099 ALIAS:
14100 setpixel = 1
14101 setPixel = 2
14102 PPCODE:
14103 {
14104 AV
14105 *av;
14106
14107 char
14108 *attribute;
14109
14110 ChannelType
14111 channel,
14112 channel_mask;
14113
14114 ExceptionInfo
14115 *exception;
14116
14117 Image
14118 *image;
14119
14120 MagickBooleanType
14121 normalize;
14122
14123 RectangleInfo
14124 region;
14125
14126 register ssize_t
14127 i;
14128
14129 register Quantum
14130 *q;
14131
14132 ssize_t
14133 option;
14134
14135 struct PackageInfo
14136 *info;
14137
14138 SV
14139 *perl_exception,
14140 *reference; /* reference is the SV* of ref=SvIV(reference) */
14141
14142 PERL_UNUSED_VAR(ref);
14143 PERL_UNUSED_VAR(ix);
14144 exception=AcquireExceptionInfo();
14145 perl_exception=newSVpv("",0);
14146 reference=SvRV(ST(0));
14147 av=(AV *) reference;
14148 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
14149 exception);
14150 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14151 if (image == (Image *) NULL)
14152 {
14153 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14154 PackageName);
14155 goto PerlException;
14156 }
14157 av=(AV *) NULL;
14158 normalize=MagickTrue;
14159 region.x=0;
14160 region.y=0;
14161 region.width=image->columns;
14162 region.height=1;
14163 if (items == 1)
14164 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
14165 channel=DefaultChannels;
14166 for (i=2; i < items; i+=2)
14167 {
14168 attribute=(char *) SvPV(ST(i-1),na);
14169 switch (*attribute)
14170 {
14171 case 'C':
14172 case 'c':
14173 {
14174 if (LocaleCompare(attribute,"channel") == 0)
14175 {
14176 ssize_t
14177 option;
14178
14179 option=ParseChannelOption(SvPV(ST(i),na));
14180 if (option < 0)
14181 {
14182 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14183 SvPV(ST(i),na));
14184 return;
14185 }
14186 channel=(ChannelType) option;
14187 break;
14188 }
14189 if (LocaleCompare(attribute,"color") == 0)
14190 {
14191 if (SvTYPE(ST(i)) != SVt_RV)
14192 {
14193 char
cristy151b66d2015-04-15 10:50:31 +000014194 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014195
cristy151b66d2015-04-15 10:50:31 +000014196 (void) FormatLocaleString(message,MagickPathExtent,
cristy4a3ce0a2013-08-03 20:06:59 +000014197 "invalid %.60s value",attribute);
14198 ThrowPerlException(exception,OptionError,message,
14199 SvPV(ST(i),na));
14200 }
14201 av=(AV *) SvRV(ST(i));
14202 break;
14203 }
14204 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14205 attribute);
14206 break;
14207 }
14208 case 'g':
14209 case 'G':
14210 {
14211 if (LocaleCompare(attribute,"geometry") == 0)
14212 {
14213 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
14214 break;
14215 }
14216 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14217 attribute);
14218 break;
14219 }
14220 case 'N':
14221 case 'n':
14222 {
14223 if (LocaleCompare(attribute,"normalize") == 0)
14224 {
14225 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14226 SvPV(ST(i),na));
14227 if (option < 0)
14228 {
14229 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14230 SvPV(ST(i),na));
14231 break;
14232 }
14233 normalize=option != 0 ? MagickTrue : MagickFalse;
14234 break;
14235 }
14236 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14237 attribute);
14238 break;
14239 }
14240 case 'x':
14241 case 'X':
14242 {
14243 if (LocaleCompare(attribute,"x") == 0)
14244 {
14245 region.x=SvIV(ST(i));
14246 break;
14247 }
14248 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14249 attribute);
14250 break;
14251 }
14252 case 'y':
14253 case 'Y':
14254 {
14255 if (LocaleCompare(attribute,"y") == 0)
14256 {
14257 region.y=SvIV(ST(i));
14258 break;
14259 }
14260 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14261 attribute);
14262 break;
14263 }
14264 default:
14265 {
14266 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14267 attribute);
14268 break;
14269 }
14270 }
14271 }
14272 (void) SetImageStorageClass(image,DirectClass,exception);
14273 channel_mask=SetImageChannelMask(image,channel);
14274 q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
14275 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14276 (SvTYPE(av) != SVt_PVAV))
14277 PUSHs(&sv_undef);
14278 else
14279 {
14280 double
14281 scale;
14282
14283 register ssize_t
14284 i;
14285
14286 i=0;
14287 scale=1.0;
14288 if (normalize != MagickFalse)
14289 scale=QuantumRange;
14290 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14291 (i <= av_len(av)))
14292 {
14293 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14294 av_fetch(av,i,0)))),q);
14295 i++;
14296 }
14297 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14298 (i <= av_len(av)))
14299 {
14300 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14301 av_fetch(av,i,0)))),q);
14302 i++;
14303 }
14304 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14305 (i <= av_len(av)))
14306 {
14307 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14308 av_fetch(av,i,0)))),q);
14309 i++;
14310 }
14311 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14312 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14313 {
14314 SetPixelBlack(image,ClampToQuantum(scale*
14315 SvNV(*(av_fetch(av,i,0)))),q);
14316 i++;
14317 }
14318 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14319 (i <= av_len(av)))
14320 {
14321 SetPixelAlpha(image,ClampToQuantum(scale*
14322 SvNV(*(av_fetch(av,i,0)))),q);
14323 i++;
14324 }
14325 (void) SyncAuthenticPixels(image,exception);
14326 }
14327 (void) SetImageChannelMask(image,channel_mask);
14328
14329 PerlException:
14330 InheritPerlException(exception,perl_exception);
14331 exception=DestroyExceptionInfo(exception);
14332 SvREFCNT_dec(perl_exception);
14333 }
14334
14335#
14336###############################################################################
14337# #
14338# #
14339# #
Cristybba545b2018-07-04 15:00:12 -040014340# S e t P i x e l s #
14341# #
14342# #
14343# #
14344###############################################################################
14345#
14346#
14347void
14348SetPixels(ref,...)
14349 Image::Magick ref=NO_INIT
14350 ALIAS:
14351 setpixels = 1
14352 setPixels = 2
14353 PPCODE:
14354 {
14355 AV
14356 *av;
14357
14358 char
14359 *attribute;
14360
14361 ChannelType
14362 channel,
14363 channel_mask;
14364
14365 ExceptionInfo
14366 *exception;
14367
14368 Image
14369 *image;
14370
14371 RectangleInfo
14372 region;
14373
14374 register ssize_t
14375 i;
14376
14377 register Quantum
14378 *q;
14379
14380 struct PackageInfo
14381 *info;
14382
14383 SV
14384 *perl_exception,
14385 *reference; /* reference is the SV* of ref=SvIV(reference) */
14386
14387 PERL_UNUSED_VAR(ref);
14388 PERL_UNUSED_VAR(ix);
14389 exception=AcquireExceptionInfo();
14390 perl_exception=newSVpv("",0);
14391 reference=SvRV(ST(0));
14392 av=(AV *) reference;
14393 info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
14394 exception);
14395 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14396 if (image == (Image *) NULL)
14397 {
14398 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14399 PackageName);
14400 goto PerlException;
14401 }
14402 av=(AV *) NULL;
14403 region.x=0;
14404 region.y=0;
14405 region.width=image->columns;
14406 region.height=1;
14407 if (items == 1)
14408 (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
14409 channel=DefaultChannels;
14410 for (i=2; i < items; i+=2)
14411 {
14412 attribute=(char *) SvPV(ST(i-1),na);
14413 switch (*attribute)
14414 {
14415 case 'C':
14416 case 'c':
14417 {
14418 if (LocaleCompare(attribute,"channel") == 0)
14419 {
14420 ssize_t
14421 option;
14422
14423 option=ParseChannelOption(SvPV(ST(i),na));
14424 if (option < 0)
14425 {
14426 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14427 SvPV(ST(i),na));
14428 return;
14429 }
14430 channel=(ChannelType) option;
14431 break;
14432 }
14433 if (LocaleCompare(attribute,"color") == 0)
14434 {
14435 if (SvTYPE(ST(i)) != SVt_RV)
14436 {
14437 char
14438 message[MagickPathExtent];
14439
14440 (void) FormatLocaleString(message,MagickPathExtent,
14441 "invalid %.60s value",attribute);
14442 ThrowPerlException(exception,OptionError,message,
14443 SvPV(ST(i),na));
14444 }
14445 av=(AV *) SvRV(ST(i));
14446 break;
14447 }
14448 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14449 attribute);
14450 break;
14451 }
14452 case 'g':
14453 case 'G':
14454 {
14455 if (LocaleCompare(attribute,"geometry") == 0)
14456 {
14457 (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
14458 break;
14459 }
14460 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14461 attribute);
14462 break;
14463 }
14464 case 'h':
14465 case 'H':
14466 {
14467 if (LocaleCompare(attribute,"height") == 0)
14468 {
14469 region.height=SvIV(ST(i));
14470 break;
14471 }
14472 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14473 attribute);
14474 break;
14475 }
14476 case 'w':
14477 case 'W':
14478 {
14479 if (LocaleCompare(attribute,"width") == 0)
14480 {
14481 region.width=SvIV(ST(i));
14482 break;
14483 }
14484 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14485 attribute);
14486 break;
14487 }
14488 case 'x':
14489 case 'X':
14490 {
14491 if (LocaleCompare(attribute,"x") == 0)
14492 {
14493 region.x=SvIV(ST(i));
14494 break;
14495 }
14496 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14497 attribute);
14498 break;
14499 }
14500 case 'y':
14501 case 'Y':
14502 {
14503 if (LocaleCompare(attribute,"y") == 0)
14504 {
14505 region.y=SvIV(ST(i));
14506 break;
14507 }
14508 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14509 attribute);
14510 break;
14511 }
14512 default:
14513 {
14514 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14515 attribute);
14516 break;
14517 }
14518 }
14519 }
14520 (void) SetImageStorageClass(image,DirectClass,exception);
14521 channel_mask=SetImageChannelMask(image,channel);
14522 q=GetAuthenticPixels(image,region.x,region.y,region.width,region.height,
14523 exception);
14524 if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
14525 (SvTYPE(av) != SVt_PVAV))
14526 PUSHs(&sv_undef);
14527 else
14528 {
14529 double
14530 scale;
14531
14532 register ssize_t
14533 i,
14534 n,
14535 number_pixels;
14536
14537 i=0;
14538 n=0;
14539 scale=(double) QuantumRange;
14540 number_pixels=region.width*region.height;
14541 while ((n < number_pixels) && (i < av_len(av)))
14542 {
14543 if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
14544 (i <= av_len(av)))
14545 {
14546 SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
14547 av_fetch(av,i,0)))),q);
14548 i++;
14549 }
14550 if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
14551 (i <= av_len(av)))
14552 {
14553 SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
14554 av_fetch(av,i,0)))),q);
14555 i++;
14556 }
14557 if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
14558 (i <= av_len(av)))
14559 {
14560 SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
14561 av_fetch(av,i,0)))),q);
14562 i++;
14563 }
14564 if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
14565 (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
14566 {
14567 SetPixelBlack(image,ClampToQuantum(scale*
14568 SvNV(*(av_fetch(av,i,0)))),q);
14569 i++;
14570 }
14571 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
14572 (i <= av_len(av)))
14573 {
14574 SetPixelAlpha(image,ClampToQuantum(scale*
14575 SvNV(*(av_fetch(av,i,0)))),q);
14576 i++;
14577 }
14578 n++;
14579 q+=image->number_channels;
14580 }
14581 (void) SyncAuthenticPixels(image,exception);
14582 }
14583 (void) SetImageChannelMask(image,channel_mask);
14584
14585 PerlException:
14586 InheritPerlException(exception,perl_exception);
14587 exception=DestroyExceptionInfo(exception);
14588 SvREFCNT_dec(perl_exception);
14589 }
14590
14591#
14592###############################################################################
14593# #
14594# #
14595# #
cristy4a3ce0a2013-08-03 20:06:59 +000014596# S m u s h #
14597# #
14598# #
14599# #
14600###############################################################################
14601#
14602#
14603void
14604Smush(ref,...)
14605 Image::Magick ref=NO_INIT
14606 ALIAS:
14607 SmushImage = 1
14608 smush = 2
14609 smushimage = 3
14610 PPCODE:
14611 {
14612 AV
14613 *av;
14614
14615 char
14616 *attribute;
14617
14618 ExceptionInfo
14619 *exception;
14620
14621 HV
14622 *hv;
14623
14624 Image
14625 *image;
14626
14627 register ssize_t
14628 i;
14629
14630 ssize_t
14631 offset,
14632 stack;
14633
14634 struct PackageInfo
14635 *info;
14636
14637 SV
14638 *av_reference,
14639 *perl_exception,
14640 *reference,
14641 *rv,
14642 *sv;
14643
14644 PERL_UNUSED_VAR(ref);
14645 PERL_UNUSED_VAR(ix);
14646 exception=AcquireExceptionInfo();
14647 perl_exception=newSVpv("",0);
14648 sv=NULL;
14649 attribute=NULL;
14650 av=NULL;
14651 if (sv_isobject(ST(0)) == 0)
14652 {
14653 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14654 PackageName);
14655 goto PerlException;
14656 }
14657 reference=SvRV(ST(0));
14658 hv=SvSTASH(reference);
14659 av=newAV();
14660 av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
14661 SvREFCNT_dec(av);
14662 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14663 if (image == (Image *) NULL)
14664 {
14665 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14666 PackageName);
14667 goto PerlException;
14668 }
14669 info=GetPackageInfo(aTHX_ (void *) av,info,exception);
14670 /*
14671 Get options.
14672 */
14673 offset=0;
14674 stack=MagickTrue;
14675 for (i=2; i < items; i+=2)
14676 {
14677 attribute=(char *) SvPV(ST(i-1),na);
14678 switch (*attribute)
14679 {
14680 case 'O':
14681 case 'o':
14682 {
14683 if (LocaleCompare(attribute,"offset") == 0)
14684 {
14685 offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
14686 break;
14687 }
14688 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14689 attribute);
14690 break;
14691 }
14692 case 'S':
14693 case 's':
14694 {
14695 if (LocaleCompare(attribute,"stack") == 0)
14696 {
14697 stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
14698 SvPV(ST(i),na));
14699 if (stack < 0)
14700 {
14701 ThrowPerlException(exception,OptionError,"UnrecognizedType",
14702 SvPV(ST(i),na));
14703 return;
14704 }
14705 break;
14706 }
14707 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14708 attribute);
14709 break;
14710 }
14711 default:
14712 {
14713 ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
14714 attribute);
14715 break;
14716 }
14717 }
14718 }
14719 image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
14720 exception);
14721 if (image == (Image *) NULL)
14722 goto PerlException;
14723 for ( ; image; image=image->next)
14724 {
14725 AddImageToRegistry(sv,image);
14726 rv=newRV(sv);
14727 av_push(av,sv_bless(rv,hv));
14728 SvREFCNT_dec(sv);
14729 }
14730 exception=DestroyExceptionInfo(exception);
14731 ST(0)=av_reference;
14732 SvREFCNT_dec(perl_exception);
14733 XSRETURN(1);
14734
14735 PerlException:
14736 InheritPerlException(exception,perl_exception);
14737 exception=DestroyExceptionInfo(exception);
14738 sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
14739 SvPOK_on(perl_exception);
14740 ST(0)=sv_2mortal(perl_exception);
14741 XSRETURN(1);
14742 }
14743
14744#
14745###############################################################################
14746# #
14747# #
14748# #
14749# S t a t i s t i c s #
14750# #
14751# #
14752# #
14753###############################################################################
14754#
14755#
14756void
14757Statistics(ref,...)
14758 Image::Magick ref=NO_INIT
14759 ALIAS:
14760 StatisticsImage = 1
14761 statistics = 2
14762 statisticsimage = 3
14763 PPCODE:
14764 {
14765#define ChannelStatistics(channel) \
14766{ \
cristy151b66d2015-04-15 10:50:31 +000014767 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014768 (double) channel_statistics[channel].depth); \
14769 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014770 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014771 channel_statistics[channel].minima/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014772 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014773 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014774 channel_statistics[channel].maxima/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014775 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014776 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014777 channel_statistics[channel].mean/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014778 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014779 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
Cristy5a854dc2017-02-11 15:43:46 -050014780 channel_statistics[channel].standard_deviation/QuantumRange); \
cristy4a3ce0a2013-08-03 20:06:59 +000014781 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014782 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014783 channel_statistics[channel].kurtosis); \
14784 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014785 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy4a3ce0a2013-08-03 20:06:59 +000014786 channel_statistics[channel].skewness); \
14787 PUSHs(sv_2mortal(newSVpv(message,0))); \
Cristyb1710fe2017-02-11 13:51:48 -050014788 (void) FormatLocaleString(message,MagickPathExtent,"%.20g", \
cristy275bdd92014-11-08 23:45:03 +000014789 channel_statistics[channel].entropy); \
14790 PUSHs(sv_2mortal(newSVpv(message,0))); \
cristy4a3ce0a2013-08-03 20:06:59 +000014791}
14792
14793 AV
14794 *av;
14795
14796 char
cristy151b66d2015-04-15 10:50:31 +000014797 message[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014798
14799 ChannelStatistics
14800 *channel_statistics;
14801
cristy4a3ce0a2013-08-03 20:06:59 +000014802 ExceptionInfo
14803 *exception;
14804
14805 Image
14806 *image;
14807
14808 ssize_t
14809 count;
14810
14811 struct PackageInfo
14812 *info;
14813
14814 SV
14815 *perl_exception,
14816 *reference;
14817
14818 PERL_UNUSED_VAR(ref);
14819 PERL_UNUSED_VAR(ix);
14820 exception=AcquireExceptionInfo();
14821 perl_exception=newSVpv("",0);
14822 av=NULL;
14823 if (sv_isobject(ST(0)) == 0)
14824 {
14825 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14826 PackageName);
14827 goto PerlException;
14828 }
14829 reference=SvRV(ST(0));
14830 av=newAV();
14831 SvREFCNT_dec(av);
14832 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14833 if (image == (Image *) NULL)
14834 {
14835 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14836 PackageName);
14837 goto PerlException;
14838 }
cristy4a3ce0a2013-08-03 20:06:59 +000014839 count=0;
14840 for ( ; image; image=image->next)
14841 {
Cristyb1710fe2017-02-11 13:51:48 -050014842 register size_t
14843 i;
14844
cristy4a3ce0a2013-08-03 20:06:59 +000014845 channel_statistics=GetImageStatistics(image,exception);
14846 if (channel_statistics == (ChannelStatistics *) NULL)
14847 continue;
14848 count++;
Cristyb1710fe2017-02-11 13:51:48 -050014849 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
14850 {
14851 PixelChannel channel=GetPixelChannelChannel(image,i);
14852 PixelTrait traits=GetPixelChannelTraits(image,channel);
Cristy5a854dc2017-02-11 15:43:46 -050014853 if (traits == UndefinedPixelTrait)
Cristyb1710fe2017-02-11 13:51:48 -050014854 continue;
Cristy5a854dc2017-02-11 15:43:46 -050014855 EXTEND(sp,8*(i+1)*count);
Cristyb1710fe2017-02-11 13:51:48 -050014856 ChannelStatistics(channel);
14857 }
Cristy25813902017-02-11 15:47:52 -050014858 EXTEND(sp,8*(i+1)*count);
14859 ChannelStatistics(CompositePixelChannel);
cristy4a3ce0a2013-08-03 20:06:59 +000014860 channel_statistics=(ChannelStatistics *)
14861 RelinquishMagickMemory(channel_statistics);
14862 }
14863
14864 PerlException:
14865 InheritPerlException(exception,perl_exception);
14866 exception=DestroyExceptionInfo(exception);
14867 SvREFCNT_dec(perl_exception);
14868 }
14869
14870#
14871###############################################################################
14872# #
14873# #
14874# #
14875# S y n c A u t h e n t i c P i x e l s #
14876# #
14877# #
14878# #
14879###############################################################################
14880#
14881#
14882void
14883SyncAuthenticPixels(ref,...)
14884 Image::Magick ref = NO_INIT
14885 ALIAS:
14886 Syncauthenticpixels = 1
14887 SyncImagePixels = 2
14888 syncimagepixels = 3
14889 CODE:
14890 {
14891 ExceptionInfo
14892 *exception;
14893
14894 Image
14895 *image;
14896
14897 MagickBooleanType
14898 status;
14899
14900 struct PackageInfo
14901 *info;
14902
14903 SV
14904 *perl_exception,
14905 *reference;
14906
14907 PERL_UNUSED_VAR(ref);
14908 PERL_UNUSED_VAR(ix);
14909 exception=AcquireExceptionInfo();
14910 perl_exception=newSVpv("",0);
14911 if (sv_isobject(ST(0)) == 0)
14912 {
14913 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14914 PackageName);
14915 goto PerlException;
14916 }
14917
14918 reference=SvRV(ST(0));
14919 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14920 if (image == (Image *) NULL)
14921 {
14922 ThrowPerlException(exception,OptionError,"NoImagesDefined",
14923 PackageName);
14924 goto PerlException;
14925 }
14926
14927 status=SyncAuthenticPixels(image,exception);
14928 if (status != MagickFalse)
14929 return;
14930
14931 PerlException:
14932 InheritPerlException(exception,perl_exception);
14933 exception=DestroyExceptionInfo(exception);
14934 SvREFCNT_dec(perl_exception); /* throw away all errors */
14935 }
14936
14937#
14938###############################################################################
14939# #
14940# #
14941# #
cristy4a3ce0a2013-08-03 20:06:59 +000014942# W r i t e #
14943# #
14944# #
14945# #
14946###############################################################################
14947#
14948#
14949void
14950Write(ref,...)
14951 Image::Magick ref=NO_INIT
14952 ALIAS:
14953 WriteImage = 1
14954 write = 2
14955 writeimage = 3
14956 PPCODE:
14957 {
14958 char
cristy151b66d2015-04-15 10:50:31 +000014959 filename[MagickPathExtent];
cristy4a3ce0a2013-08-03 20:06:59 +000014960
14961 ExceptionInfo
14962 *exception;
14963
14964 Image
14965 *image,
14966 *next;
14967
14968 register ssize_t
14969 i;
14970
14971 ssize_t
14972 number_images,
14973 scene;
14974
14975 struct PackageInfo
14976 *info,
14977 *package_info;
14978
14979 SV
14980 *perl_exception,
14981 *reference;
14982
14983 PERL_UNUSED_VAR(ref);
14984 PERL_UNUSED_VAR(ix);
14985 exception=AcquireExceptionInfo();
14986 perl_exception=newSVpv("",0);
14987 number_images=0;
14988 package_info=(struct PackageInfo *) NULL;
14989 if (sv_isobject(ST(0)) == 0)
14990 {
14991 ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
14992 PackageName);
14993 goto PerlException;
14994 }
14995 reference=SvRV(ST(0));
14996 image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
14997 if (image == (Image *) NULL)
14998 {
14999 ThrowPerlException(exception,OptionError,"NoImagesDefined",
15000 PackageName);
15001 goto PerlException;
15002 }
Cristyb4ee45c2017-09-27 17:58:55 -040015003 scene=0;
15004 for (next=image; next; next=next->next)
15005 next->scene=scene++;
cristy4a3ce0a2013-08-03 20:06:59 +000015006 package_info=ClonePackageInfo(info,exception);
15007 if (items == 2)
15008 SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
15009 else
15010 if (items > 2)
15011 for (i=2; i < items; i+=2)
15012 SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
15013 exception);
15014 (void) CopyMagickString(filename,package_info->image_info->filename,
cristy151b66d2015-04-15 10:50:31 +000015015 MagickPathExtent);
cristy4a3ce0a2013-08-03 20:06:59 +000015016 for (next=image; next; next=next->next)
cristy151b66d2015-04-15 10:50:31 +000015017 (void) CopyMagickString(next->filename,filename,MagickPathExtent);
cristy68bd79a2015-02-25 12:23:36 +000015018 *package_info->image_info->magick='\0';
cristy4a3ce0a2013-08-03 20:06:59 +000015019 SetImageInfo(package_info->image_info,(unsigned int)
15020 GetImageListLength(image),exception);
15021 for (next=image; next; next=next->next)
15022 {
15023 (void) WriteImage(package_info->image_info,next,exception);
15024 number_images++;
15025 if (package_info->image_info->adjoin)
15026 break;
15027 }
15028
15029 PerlException:
15030 if (package_info != (struct PackageInfo *) NULL)
15031 DestroyPackageInfo(package_info);
15032 InheritPerlException(exception,perl_exception);
15033 exception=DestroyExceptionInfo(exception);
15034 sv_setiv(perl_exception,(IV) number_images);
15035 SvPOK_on(perl_exception);
15036 ST(0)=sv_2mortal(perl_exception);
15037 XSRETURN(1);
15038 }